STC单片机20——DS1302可调电子时钟1602显示proteus仿真

STC单片机20——DS1302可调电子时钟1602显示proteus仿真

include

sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit t=P1^0;//进入调时按键
sbit jia=P1^1;//加一按键
sbit jian=P1^2;//减一按键
sbit m=P1^3;//退出调时按键
sbit BEEP=P2^0;//蜂鸣器
sbit jtod=P1^4;//矩阵按键转独立按键,该脚置0
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数据/命令选择引脚
uchar code hanzi[][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}};

void v_W1302(uchar ucAddr, uchar ucDa);
uchar uc_R1302(uchar);
uchar dectobcd(uchar bcd);
uchar bcdtodec(uchar);
void beep();
void delay(uchar x)
{
uchar i;
while(x–)
for(i=0;i

/**********
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********/

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

/**********
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********/

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

/**********
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x06);
enable(0x0c);
E=0;
}

//装入自定义字符(汉字)
void writch()
{
uchar i,j;
enable(0x40);
for(i=0;i

/**********
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示”ab cd ef” ,调用该函数如下
L1602_string(1,5,”ab cd ef;”)
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
**********/
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 timechange()
{
uchar a,num=1;
uchar year,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 写入的数据
* 输出 : 无
***********/
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;
}
}

/**********
* 名称 : uc_RTOutputByte()
* 功能 : 从DS1302读取1Byte数据
* 输入 : 无
* 返回值: ACC
**********/
uchar uc_RTOutputByte(void)
{
uchar i;
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(uchar ucAddr, uchar ucDa)
* 功能 : 往DS1302写入数据
* 输入 : ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值 : 无
***********/
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;
}
/
*********
* 名称 : uc_R1302(uchar ucAddr)
* 功能 : 读取DS1302某地址的数据
* 输入 : ucAddr: DS1302地址
* 返回值 : ucDa :读取的数据
**********/
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);
}
/
*********
* 名称 : bcdtodec(uchar bcd)
* 功能 : BCD码转换为DEC码(DEC码为十进制数据:BCD:0x11->DEC为数值11(HEX:0x0b))
* 输入 : bcd码
* 输出 : dec码
**********/
uchar bcdtodec(uchar bcd)
{
uchar data1;
data1=((bcd&0x70)>>4)*10+(bcd&0x0f);
return data1;
}

uchar dectobcd(uchar dec)
{
uchar dat;
dat=((dec/10)<

/**********
* 名称 : Run_DS1302(void)
* 功能 : 读出DS1302中的数据,并在液晶1602上进行显示
* 输入 : 无
* 输出 : 无
***********/
void Run_DS1302(void)
{
uchar sec, 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 = bcdtodec(uc_R1302(0x89)); //读出DS1302中的月
v_W1302(0x8f, 0);
year = bcdtodec(uc_R1302(0x8d)); //读出DS1302中的年

L1602_char(2, 6, hour / 10 % 10 + 48); //字符ASIIC码显示,0的ASIIC=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, 7, year / 10 % 10 + 48);
L1602_char(1, 8, year % 10 + 48);
L1602_char(1, 9, 0);
L1602_char(1, 10, month / 10 % 10 + 48);
L1602_char(1, 11, month % 10 + 48);
L1602_char(1, 12, 1);
L1602_char(1, 13, day / 10 % 10 + 48);
L1602_char(1, 14, day % 10 + 48);
L1602_char(1, 15, 2);

}
void beep()
{
uchar i;
for(i=0;i

完整资料打包(含仿真):

STC51单片机20-DS1302可调电子时钟1602显示proteus仿真-单片机文档类资源-CSDN下载

Original: https://blog.csdn.net/fengyuzhe13/article/details/127817070
Author: fengyuzhe13
Title: STC单片机20——DS1302可调电子时钟1602显示proteus仿真

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/654875/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球