求一个51单片机使用LCD1602做的万年历,最好带温度显示和蜂鸣器报警的。 100

求一个51单片机使用LCD1602做的万年历,最好带温度显示和蜂鸣器报警的。求大佬发个proteus仿真图和程序。... 求一个51单片机使用LCD1602做的万年历,最好带温度显示和蜂鸣器报警的。求大佬发个proteus仿真图和程序。 展开
 我来答
zhxiufan
2018-04-05 · 知道合伙人软件行家
zhxiufan
知道合伙人软件行家
采纳数:14923 获赞数:38384
国家科技进步奖

向TA提问 私信TA
展开全部
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int

sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;

sbit T_CLK = P1^6; /*实时时钟时钟线引脚 */
sbit T_IO = P3^5; /*实时时钟数据线引脚 */
sbit T_RST = P1^7; /*实时时钟复位线引脚 */

//这三个引脚参考资料
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令选择引脚

void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++)
;
}

void enable(uchar del)
{
P0 = del;
RS = 0;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
void write(uchar del)
{
P0 = del;
RS = 1;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}

void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}

void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}

void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
T_RST = 1;
for(i=8; i>0; i--)
{
T_IO = ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}

uchar uc_RTOutputByte(void) 
{
uchar i;
T_RST = 1;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
T_IO=1;
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr);   // 写地址 
_nop_();
_nop_();
v_RTInputByte(ucDa);     // 写1Byte数据
T_CLK = 1;
T_RST = 0;
}

uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr);    //写地址,命令
_nop_();
_nop_();
ucDa = uc_RTOutputByte(); //读1Byte数据
T_CLK = 1;
T_RST = 0;
return(ucDa);
}

void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e, 0x00);          //控制命令,WP=0,写操作
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbe);          //0xbe:时钟多字节写命令
for(i=8; i>0; i--)            //8Byte = 7Byte 时钟数据 + 1Byte 控制
{
v_RTInputByte(*pSecDa);   //写1Byte数据
pSecDa++;
}
T_CLK = 1;
T_RST = 0;
}

void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf);               //0xbf:时钟多字节读命令
for(i=8; i>0; i--)
{
*pSecDa = uc_RTOutputByte();   //读1Byte数据
pSecDa++;
}
T_CLK = 1;
T_RST = 0;
}

void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e,0x00);         //控制命令,WP=0,写操作
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe);       //0xbe:时钟多字节写命令
for(i=31; i>0; i--)        //31Byte 寄存器数据
{
v_RTInputByte(*pReDa); //写1Byte数据
pReDa++;
}
T_CLK = 1;
T_RST = 0;
}

void v_BurstR1302R(uchar *pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xff);            //0xbf:时钟多字节读命令
for(i=31; i>0; i--)             //31Byte 寄存器数据
{
*pReDa = uc_RTOutputByte(); //读1Byte数据
pReDa++;
}
T_CLK = 1;
T_RST = 0;
}

void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e, 0x00);            //控制命令,WP=0,写操作
for(i=7; i>0; i--)
{
v_W1302(ucAddr, *pSecDa);   // 秒 分 时 日 月 星期 年
pSecDa++;
ucAddr += 2;
}
v_W1302(0x8e, 0x80);            //控制命令,WP=1,写保护
}

void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for(i=0; i<7; i++)
{
ucCurtime[i] = uc_R1302(ucAddr);    //格式为: 秒 分 时 日 月 星期 年
ucAddr += 2;
}
}

uchar dectobcd(uchar dec)
{
uchar bcd;
bcd = 0;
while(dec >= 10)
{              
dec -= 10;                         
bcd++;

bcd <<= 4;
bcd |= dec;
return bcd;
}

uchar bcdtodec(uchar bcd)
{
uchar data1;
data1 = bcd & 0x0f;     //取BCD低4位
bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
data1 += bcd >> 1;
data1 += bcd >> 3;      //用位移代替乘法运算
return data1;
}

void Write_DS1302Init(void)
{
v_W1302(0x8e,0);
v_W1302(0x80,0x50); //写入秒
v_W1302(0x8e,0);
v_W1302(0x82,0x59); //写入分
v_W1302(0x8e,0);
v_W1302(0x84,0x07); //写入小时
v_W1302(0x8e,0);
v_W1302(0x86,0x08); //写入日
v_W1302(0x8e,0);
v_W1302(0x88,0x08); //写入月
v_W1302(0x8e,0);
v_W1302(0x8a,0x05); //写入星期
v_W1302(0x8e,0);
v_W1302(0x8c,0x08); //写入年
}

void Run_DS1302(void)
{
uchar sec, min, hour, day, month, year;
while(1)
{
v_W1302(0x8f, 0);
sec = bcdtodec(uc_R1302(0x81));    //读出DS1302中的秒
v_W1302(0x8f, 0);
min = bcdtodec(uc_R1302(0x83));    //读出DS1302中的分
v_W1302(0x8f, 0);
hour = bcdtodec(uc_R1302(0x85));   //读出DS1302中的小时
v_W1302(0x8f, 0);
day = bcdtodec(uc_R1302(0x87));    //读出DS1302中的日
v_W1302(0x8f, 0);
month = bcdtodec(uc_R1302(0x89));  //读出DS1302中的月
v_W1302(0x8f, 0);
year = bcdtodec(uc_R1302(0x8d));   //读出DS1302中的年

L1602_char(2, 6, hour / 10 % 10 + 48);
L1602_char(2, 7, hour % 10 + 48);
L1602_char(2, 8, '-');
L1602_char(2, 9, min / 10 % 10 + 48);
L1602_char(2, 10, min % 10 + 48);
L1602_char(2, 11, '-');
L1602_char(2, 12, sec / 10 % 10 + 48);
L1602_char(2, 13, sec % 10 + 48);
L1602_char(1, 8, year / 10 % 10 + 48);
L1602_char(1, 9, year % 10 + 48);
L1602_char(1, 10, '-');
L1602_char(1, 11, month / 10 % 10 + 48);
L1602_char(1, 12, month % 10 + 48);
L1602_char(1, 13, '-');
L1602_char(1, 14, day / 10 % 10 + 48);
L1602_char(1, 15, day % 10 + 48);
}


void Main(void)
{
L1602_init();
L1602_string(1,1,"DAYS 20");
L1602_string(2,1,"TIME");
Write_DS1302Init();
Run_DS1302();
}
匿名用户
2018-04-02
展开全部
我做电路板的,帮不到你,
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zxcdfhh
2018-04-02 · TA获得超过123个赞
知道答主
回答量:301
采纳率:0%
帮助的人:31.5万
展开全部
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式