DS1302可调电子时钟1602显示proteus仿真.docx
- 文档编号:9968471
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:24
- 大小:345.58KB
DS1302可调电子时钟1602显示proteus仿真.docx
《DS1302可调电子时钟1602显示proteus仿真.docx》由会员分享,可在线阅读,更多相关《DS1302可调电子时钟1602显示proteus仿真.docx(24页珍藏版)》请在冰点文库上搜索。
DS1302可调电子时钟1602显示proteus仿真
总电路图:
单片机电路图:
1602接线图:
1302接线图:
〔I/O接单片机3.5脚〕
按键接线图:
程序清单:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitt=P1^0;//进入调时按键
sbitjia=P1^1;//加一按键
sbitjian=P1^2;//减一按键
sbitm=P1^3;//退出调时按键
sbitBEEP=P2^0;//蜂鸣器
sbitjtod=P1^4;//矩阵按键转独立按键,该脚置0
sbitT_CLK=P1^6;/*实时时钟时钟线引脚*/
sbitT_IO=P3^5;/*实时时钟数据线引脚*/
sbitT_RST=P1^7;/*实时时钟复位线引脚*/
sbitE=P2^7;//1602使能引脚
sbitRW=P2^6;//1602读写引脚
sbitRS=P2^5;//1602数据/命令选择引脚
ucharcodehanzi[][8]={{0x04,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02},{0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x11},{0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}};
voidv_W1302(ucharucAddr,ucharucDa);
ucharuc_R1302(uchar);
uchardectobcd(ucharbcd);
ucharbcdtodec(uchar);
voidbeep();
voiddelay(ucharx)
{
uchari;
while(x--)
for(i=0;i<110;i++);
}
/********************************************************************
*名称:
enable(uchardel)
*功能:
1602命令函数
*输入:
输入的命令值
*输出:
无
***********************************************************************/
voidenable(uchardel)
{
RS=0;
RW=0;
P0=del;
E=1;
delay(3);
E=0;
}
/********************************************************************
*名称:
write(uchardel)
*功能:
1602写数据函数
*输入:
需要写入1602的数据
*输出:
无
***********************************************************************/
voidwrite(uchardel)
{
RS=1;
RW=0;
P0=del;
E=1;
delay(3);
E=0;
}
/********************************************************************
*名称:
L1602_init()
*功能:
1602初始化,请参考1602的资料
*输入:
无
*输出:
无
***********************************************************************/
voidL1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x06);
enable(0x0c);
E=0;
}
//装入自定义字符〔汉字〕
voidwritch()
{
uchari,j;
enable(0x40);
for(i=0;i<8;i++)
for(j=0;j<8;j++)
write(hanzi[i][j]);
}
/********************************************************************
*名称:
L1602_char(ucharhang,ucharlie,charsign)
*功能:
改变液晶中某位的值,如果要让第一行,第五个字符显示"b",调用该函数如下
L1602_char(1,5,'b')
*输入:
行,列,需要输入1602的数据
*输出:
无
***********************************************************************/
voidL1602_char(ucharhang,ucharlie,charsign)
{
uchara;
if(hang==1)a=0x80;
if(hang==2)a=0xc0;
a=a+lie-1;
enable(a);
write(sign);
}
/********************************************************************
*名称:
L1602_string(ucharhang,ucharlie,uchar*p)
*功能:
改变液晶中某位的值,如果要让第一行,第五个字符开场显示"abcdef",调用该函数如下
L1602_string(1,5,"abcdef;")
*输入:
行,列,需要输入1602的数据
*输出:
无
***********************************************************************/
voidL1602_string(ucharhang,ucharlie,uchar*p)
{
uchara;
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++;
}
}
//时钟调节//
voidtimechange()
{
uchara,num=1;
ucharyear,mon,day,hour,min,sec;
//进入调时循环
while(num)
{
if(t==0)
delay(5);
if(t==0)
{
num++;
beep();
while(!
t);
}
//退出调时按键m
if(m==0)
delay(5);
if(m==0)
num=0;
enable(0x0f);
a=uc_R1302(0x81)|0x80;
v_W1302(0x8e,0);
v_W1302(0x80,a);
//调时到年以后退出调时
if(num==7)
num=0;
//num=1调秒
if(num==1)
{
enable(0xc0+12);
if(jia==0)
delay(5);
if(jia==0)//秒加一
{
while(!
jia);
sec=bcdtodec(uc_R1302(0x81)&0x7f);
sec++;
if(sec>59)
sec=0;
L1602_char(2,12,sec/10%10+48);
L1602_char(2,13,sec%10+48);
v_W1302(0x80,dectobcd(sec)|0x80);
}
if(jian==0)//秒减一
delay(5);
if(jian==0)
{
while(!
jian);
sec=bcdtodec(uc_R1302(0x81));
sec--;
if(sec==-1)
sec=59;
L1602_char(2,12,sec/10%10+48);
L1602_char(2,13,sec%10+48);
v_W1302(0x80,dectobcd(sec)|0x80);
}
}
if(num==2)//调分钟
{
enable(0xc0+9);
if(jia==0)
delay(5);
if(jia==0)
{
min=bcdtodec(uc_R1302(0x83));
min++;
while(!
jia);
if(min>59)
min=0;
L1602_char(2,9,min/10%10+48);
L1602_char(2,10,min%10+48);
v_W1302(0x82,dectobcd(min));
}
if(jian==0)
delay(5);
if(jian==0)
{
min=bcdtodec(uc_R1302(0x83));
min--;
while(!
jian);
if(min==-1)
min=59;
L1602_char(2,9,min/10%10+48);
L1602_char(2,10,min%10+48);
v_W1302(0x82,dectobcd(min));
}
}
if(num==3)//调小时
{
enable(0xc0+6);
if(jia==0)
delay(5);
if(jia==0)
{
hour=bcdtodec(uc_R1302(0x85));
hour++;
while(!
jia);
if(hour>23)
hour=0;
L1602_char(2,6,hour/10%10+48);
L1602_char(2,7,hour%10+48);
v_W1302(0x84,dectobcd(hour));
}
if(jian==0)
delay(5);
if(jian==0)
{
while(!
jian);
hour=bcdtodec(uc_R1302(0x85));
hour--;
if(hour==-1)
hour=23;
L1602_char(2,6,hour/10%10+48);
L1602_char(2,7,hour%10+48);
v_W1302(0x84,dectobcd(hour));
}
}
if(num==4)//调日期
{
enable(0x80+13);
if(jia==0)
delay(5);
if(jia==0)
{
hour=bcdtodec(uc_R1302(0x87));
day++;
while(!
jia);
if(day>31)
day=0;
L1602_char(1,13,day/10%10+48);
L1602_char(1,14,day%10+48);
v_W1302(0x86,dectobcd(day));
}
if(jian==0)
delay(5);
if(jian==0)
{
while(!
jian);
day=bcdtodec(uc_R1302(0x87));
day--;
if(day==-1)
day=31;
L1602_char(1,13,day/10%10+48);
L1602_char(1,14,day%10+48);
v_W1302(0x86,dectobcd(day));
}
}
if(num==5)//调月份
{
enable(0x80+10);
if(jia==0)
delay(5);
if(jia==0)
{
mon=bcdtodec(uc_R1302(0x89));
mon++;
while(!
jia);
if(mon>12)
mon=0;
L1602_char(1,10,mon/10%10+48);
L1602_char(1,11,mon%10+48);
v_W1302(0x88,dectobcd(mon));
}
if(jian==0)
delay(5);
if(jian==0)
{
while(!
jian);
mon=bcdtodec(uc_R1302(0x89));
mon--;
if(mon==-1)
mon=12;
L1602_char(1,10,mon/10%10+48);
L1602_char(1,11,mon%10+48);
v_W1302(0x88,dectobcd(mon));
}
}
if(num==6)//调年份
{
enable(0x80+7);
if(jia==0)
delay(5);
if(jia==0)
{
year=bcdtodec(uc_R1302(0x8d));
year++;
while(!
jia);
if(year>20)
year=0;
L1602_char(1,7,year/10%10+48);
L1602_char(1,8,year%10+48);
v_W1302(0x8c,dectobcd(year));
}
if(jian==0)
delay(5);
if(jian==0)
{
while(!
jian);
year=bcdtodec(uc_R1302(0x8d));
year--;
if(year==-1)
year=20;
L1602_char(1,7,year/10%10+48);
L1602_char(1,8,year%10+48);
v_W1302(0x8c,dectobcd(year));
}
}
}
if(num==0)//关闭光标闪烁
{
enable(0x0c);
}
v_W1302(0x80,uc_R1302(0x81)&0x7f);//开启1302记时
}
/********************************************************************
*名称:
v_RTInputByte〔〕
*功能:
往DS1302写入1Byte数据
*输入:
ucDa写入的数据
*输出:
无
***********************************************************************/
voidv_RTInputByte(ucharucDa)
{
uchari;
ACC=ucDa;
T_RST=1;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
}
/********************************************************************
*名称:
uc_RTOutputByte〔〕
*功能:
从DS1302读取1Byte数据
*输入:
无
*返回值:
ACC
***********************************************************************/
ucharuc_RTOutputByte(void)
{
uchari;
T_RST=1;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=T_IO;
T_CLK=1;
T_CLK=0;
}
return(ACC);
}
/********************************************************************
*名称:
v_W1302(ucharucAddr,ucharucDa)
*功能:
往DS1302写入数据
*输入:
ucAddr:
DS1302地址,ucDa:
要写的数据
*返回值:
无
***********************************************************************/
voidv_W1302(ucharucAddr,ucharucDa)
{
T_RST=0;
T_CLK=0;
T_RST=1;
v_RTInputByte(ucAddr);//写地址
_nop_();
_nop_();
v_RTInputByte(ucDa);//写1Byte数据
T_CLK=1;
T_RST=0;
}
/********************************************************************
*名称:
uc_R1302(ucharucAddr)
*功能:
读取DS1302某地址的数据
*输入:
ucAddr:
DS1302地址
*返回值:
ucDa:
读取的数据
***********************************************************************/
ucharuc_R1302(ucharucAddr)
{
ucharucDa;
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);
}
/********************************************************************
*名称:
bcdtodec(ucharbcd)
*功能:
BCD码转换为DEC码(DEC码为十进制数据:
BCD:
0x11->DEC为数值11(HEX:
0x0b))
*输入:
bcd码
*输出:
dec码
***********************************************************************/
ucharbcdtodec(ucharbcd)
{
uchardata1;
data1=((bcd&0x70)>>4)*10+(bcd&0x0f);
returndata1;
}
uchardectobcd(uchardec)
{
uchardat;
dat=((dec/10)<<4|(dec%10));
returndat;
}
/********************************************************************
*名称:
Write_DS1302Init()
*功能:
往DS1302中写入数据。
最开场显示的数据就是在这里设置的。
*输入:
无
*输出:
无
***********************************************************************/
voidWrite_DS1302Init(void)
{
v_W1302(0x8e,0);
v_W1302(0x80,0x00);//写入秒
v_W1302(0x8e,0);
v_W1302(0x82,0x00);//写入分
v_W1302(0x8e,0);
v_W1302(0x84,0x00);//写入小时
v_W1302(0x8e,0);
v_W1302(0x86,0x00);//写入日
v_W1302(0x8e,0);
v_W1302(0x88,0x00);//写入月
v_W1302(0x8e,0);
v_W1302(0x8a,0x00);//写入星期
v_W1302(0x8e,0);
v_W1302(0x8c,0x00);//写入年
v_W1302(0x90,0xa6);//单二极管,2K电阻充电
}
/********************************************************************
*名称:
Run_DS1302(void)
*功能:
读出DS1302中的数据,并在液晶1602上进展显示
*输入:
无
*输出:
无
***********************************************************************/
voidRun_DS1302(void)
{
ucharsec,min,hour,day,month,year;
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=bc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DS1302 可调 电子 时钟 1602 显示 proteus 仿真