DS3231高精度时钟程序代码单片机STC89c52RC与1602显示.docx
- 文档编号:3927881
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:20
- 大小:52.75KB
DS3231高精度时钟程序代码单片机STC89c52RC与1602显示.docx
《DS3231高精度时钟程序代码单片机STC89c52RC与1602显示.docx》由会员分享,可在线阅读,更多相关《DS3231高精度时钟程序代码单片机STC89c52RC与1602显示.docx(20页珍藏版)》请在冰豆网上搜索。
DS3231高精度时钟程序代码单片机STC89c52RC与1602显示
//DS3231,经测试,日期,时间,星期,温度可以用1602显示
#inelude
#ineludevintrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineyh0x80//第一行的初始位置
#defineer0x80+0x40//第二行初始位置
sbitwr=P1A1;
sbitrs=P1A。
;
sbiten=卩2人5;
sbitSDA=P3A6;//模拟I2C数据传送位SDA
sbitSCL=P3A7;//模拟I2C时钟控制位SCLsbitINT=P3A2;
sbitkey1=P1A7;
//功能键,修改键
sbitkey2=P3A4;
//上调键
sbitkey3=P3A5;
//下调键
sbitRESET=P3A3;
bitack;
//应答标志位
#defineDS3231
_WriteAddress0xD0
//器件写地址
#defineDS3231
_ReadAddress
0xD1
//器件读地址
#defineDS3231
_SECOND
0x00
//秒
#defineDS3231
_MINUTE
0x01
//分
#defineDS3231
_HOUR
0x02
//时
#defineDS3231
_WEEK
0x03
//星期
#defineDS3231
_DAY
0x04
//日
#defineDS3231
_MONTH
0x05
//月
#defineDS3231
_YEAR
0x06
//年
//闹铃1
#defineDS3231
_SALARM1ECOND0x07
//秒
#defineDS3231
_ALARM1MINUTE0x08
//分
#defineDS3231
_ALARM1HOUR
0x09
//时
#defineDS3231
_ALARM1WEEK
0x0A
//星期/日
//闹铃2
#defineDS3231
_ALARM2MINUTE0x0b
//分
#defineDS3231
_ALARM2HOUR
0x0c
//时
可编辑
#defineDS3231_TEMPERATUREH0x11
//温度寄存器高字节
//温度寄存器低字节
(8位)
(高2位)
#defineDS3231_TEMPERATUREL0x12uchara,miao,shi,fen,ri,yue,nian,week,temp1,temp2,key1n,temp;
ucharcodetab1[]={"2017--FRI"};
ucharcodetab2[]={":
:
."};
ucharHEX2BCD(ucharval)//B码转换为BCD码
{
uchark;
k=(val)/10*16+(val)%10;
returnk;
}
ucharBCD_Decimal(ucharbcd)
{
ucharDecimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
voiddelayus(uintus)
{
while(us--);
}
voidStart_I2C()
{
SDA=1;//发送起始条件的数据信号delayus
(1);
SCL=1;
delayus(5);//起始条件建立时间大于4.7us,延时
SDA=0;//发送起始信号
delayus(5);//起始条件锁定时间大于4阳
SCL=0;//钳住I2C总线,准备发送或接收数据
delayus
(2);
}
voidStop_I2C()
{
SDA=0;//发送结束条件的数据信号
delayus
(1);
//发送结束条件的时钟信号
SCL=1;
//结束条件建立时间大于4us
delayus(5);
SDA=1;
//发送I2C总线结束信号
delayus(4);
}
voidSendByte(ucharc)
{
ucharBitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
if((c< SDA=1; else SDA=0; delayus (1); SCL=1; 数据位 delayus(5); SCL=0; //要传送的数据长度为8位 //判断发送位 //置时钟线为高,通知被控器开始接收 //保证时钟咼电平周期大于4阳 delayus (2); SDA=1;//8位发送完后释放数据线,准备接收应答位 delayus (2); SCL=1; delayus(3); if(SDA==1) ack=0; else ack=1;//判断是否接收到应答信号 SCL=0; delayus (2); } ucharRcvByte() { ucharretc; ucharBitCnt; retc=0; SDA=1;//置数据线为输入方式 for(BitCnt=0;BitCnt<8;BitCnt++) SCL=0; delayus(5); SCL=1; delayus(3); retc=retc<<1; if(SDA==1) retc=retc+1; delayus (2); } SCL=0; delayus (2); return(retc); } //置时钟线为低,准备接收数据位 //时钟低电平周期大于4.7Q //置时钟线为高使数据线上数据有效 //读数据位,接收的数据位放入retc中 voidAck_I2C(bita) { if(a==0) SDA=0; else //在此发出应答或非应答信号 SDA=1; SCL=1; delayus(5);//时钟低电平周期大于4阴 SCL=0;//清时钟线,钳住I2C总线以便继续接收 delayus (2); } ucharwrite_byte(ucharaddr,ucharwrite_data){ Start_I2C(); SendByte(DS3231_WriteAddress); if(ack==0) return0; SendByte(addr); if(ack==0) return0; SendByte(write_data); if(ack==0) return0; Stop_I2C(); return1; } ucharread_current() { ucharread_data; Start_I2C(); SendByte(DS3231_ReadAddress); if(ack==0) return(0); read_data=RcvByte(); Ack_I2C (1); Stop_I2C(); returnread_data; } ucharread_random(ucharrandom_addr) { Start_I2C(); SendByte(DS3231_WriteAddress); if(ack==0) SendByte(random_addr); if(ack==0) return(0); return(read_current()); } voidModifyTime(ucharyea,uchar sec,ucharweek) { uchartemp=0; temp=HEX2BCD(yea); write_byte(DS3231_YEAR,temp); temp=HEX2BCD(mon); write_byte(DS3231_MONTH,temp); temp=HEX2BCD(da); write_byte(DS3231_DAY,temp); temp=HEX2BCD(hou); write_byte(DS3231_HOUR,temp); mon,ucharda,ucharhou,uchar //修改年 //修改月 //修改日 //修改时 min,uchar temp=HEX2BCD(min); write_byte(DS3231_MINUTE,temp);//修改分 temp=HEX2BCD(sec); write_byte(DS3231_SECOND,temp);//修改秒 temp=HEX2BCD(week); write_byte(DS3231_WEEK,temp);//修改星期 **************** 液晶写入********************** } write_1602com(ucharcom)//液晶写入指令函数{ rs=0;//置为写入命令 P0=com;//送入数据 delayus(1000); en=1;//拉高使能端 delayus(1000); en=0;//完成高脉冲 } write_1602dat(uchardat) { rs=1;//置为写入数据 P0=dat;//送入数据 delayus(1000); en=1; delayus(1000); *******************over********************* en=0; } lcd_init()//液晶初始化函数 {wr=0; write_1602com(0x38);// 设置液晶工作模式 write_1602com(0x0c);// 开显示不显示光标 write_1602com(0x06);// 整屏不移动,指针加一 write_1602com(0x01); write_1602com(yh+1);// 字符写入的位置 for(a=0;a<14;a++) { write_1602dat(tab1[a]); //delay(3); } write_1602com(er); for(a=0;a<12;a++) { //delay(3); } write_1602com(er+14);//写温度符号 write_1602dat(0xdf); write_1602dat(0x43); voidwrite_sfm(ucharadd,uchardat)//写时分秒及温度{ uchargw,sw; gw=dat%10; sw=dat/10; write_1602com(er+add); write_1602dat(0x30+sw); write_1602dat(0x30+gw); } voidwrite_nyr(ucharadd,uchardat)//写日期{ uchargw,sw; gw=dat%10; sw=dat/10; write_1602com(yh+add); write_1602dat(0x30+sw); write_1602dat(0x30+gw); } voidwrite_week(ucharweek)//写星期函数 { write_1602com(yh+0x0c); switch(week) { case1: write_1602dat('M');//delay(5); write_1602dat('O');//delay(5); write_1602dat('N'); break; case2: write_1602dat('T');//delay(5); write_1602dat('U');//delay(5); write_1602dat('E'); break; case3: write_1602dat('W');//delay(5); break; case4: write_1602dat('T');//delay(5); write_1602dat('H');//delay(5);write_1602dat('U'); break; case5: write_1602dat('F');//delay(5); write_1602dat('R');//delay(5);write_1602dat('I'); break; case6: write_1602dat('S');//delay(5); write_1602dat('T');//delay(5);write_1602dat('A'); break; case7: write_1602dat('S');//delay(5); write_1602dat('U');//delay(5);write_1602dat('N'); break; } voidkeyscan() { if(key1==0)//key1为功能键 { delayus(5000); if(key1==0) { while(! key1); key1n++; if(key1n==9) key1n=1; switch(key1n) { case1: TR0=0;//关闭定时器 //TR1=0; write_1602com(er+0x06);//写入光标位置 write_1602com(0x0f);//设置光标为闪烁 break; //write_1602com(0x0f); break; case3: write_1602com(er+0);//shi //write_1602com(0x0f); break; case4: write_1602com(yh+0x0d);//week //write_1602com(0x0f); break; case5: write_1602com(yh+0x09);//ri //write_1602com(0x0f); break; case6: write_1602com(yh+0x06);//yue //write_1602com(0x0f); break; case7: write_1602com(yh+0x03);//nian //write_1602com(0x0f); break; case8: write_1602com(0x0c);//设置光标不闪烁 write_sfm(6,miao);//写入新的秒数 temp=(miao)/10*16+(miao)%10; write_byte(DS3231_SECOND,temp);//退出时修改秒write_1602com(er+6); temp=(fen)/10*16+(fen)%10; write_byte(DS3231_MINUTE,temp);//修改分 write_1602com(er+3); TR0=1;//打开定时器 break; } } } if(key1n! =0)//当key1按下以下。 再按以下键才有效 { if(key2==0)//上调键 { delayus(5000); if(key2==0) { while(! key2); switch(key1n) { case1: miao++; if(miao==60) miao=0; write_sfm(6,miao);//写入新的秒数 temp=(miao)/10*16+(miao)%10; write_byte(DS3231_SECOND,temp);//修改秒 write_1602com(er+6);//设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 break; case2: fen++; if(fen==60) fen=0; write_sfm(0x03,fen); temp=(fen)/10*16+(fen)%10; write_byte(DS3231_MINUTE,temp); write_1602com(er+3); break; case3: shi++; if(shi==24) shi=0; write_sfm(0,shi); temp=(shi)/10*16+(shi)%10; write_1602com(er+0); break; case4: week++; if(week==8) week=0; write_week(week); write_byte(DS3231_WEEK,week);// write_1602com(yh+0x0d); break; case5: ri++; if(ri==31) ri=0; write_nyr(9,ri); temp=(ri)/10*16+(ri)%10; write_byte(DS3231_DAY,temp); write_1602com(yh+9); break; case6: yue++; if(yue==13) yue=0; write_nyr(6,yue); 修改星期 //修改日 temp=(yue)/10*16+(yue)%10; write_byte(DS3231_MONTH,temp); write_1602com(yh+6); break; case7: nian++; if(nian==100) nian=0; write_nyr(3,nian); temp=(nian)/10*16+(nian)%10; write_byte(DS3231_YEAR,temp); write_1602com(yh+3); break; //修改月 //修改年 } if(key3==0) { delayus(5000); if(key3==0) { while(! key3); switch(key1n) { case1: miao--; if(miao==-1) miao=59; write_sfm(6,miao);//写入新的秒数 temp=(miao)/10*16+(miao)%10; write_byte(DS3231_SECOND,temp);//修改秒 指针自动加一, write_1602com(er+6);//因为设置液晶的模式是写入数据后,在这里是写回原来的位置 break; case2: fen--; if(fen==-1) fen=59; write_sfm(3,fen); temp=(fen)/10*16+(fen)%10; write_byte(DS3231_MINUTE,temp);//修改分 write_1602com(er+3); break; case3: shi--; if(shi==-1)shi=23; write_sfm(0,shi); temp=(shi)/10*16+(shi)%10; write_byte(DS3231_HOUR,temp); write_1602com(er+0); break; case4: week--; if(week==-1) week=7; write_week(week); write_byte(DS3231_WEEK,week);// write_1602com(yh+0x0d); break; case5: ri--; if(ri==-1) ri=30; write_nyr(9,ri); temp=(ri)/10*16+(ri)%10;write_byte(DS3231_DAY,temp); write_1602com(yh+9); break; case6: yue--; if(yue==-1) //修改时 修改星期 //修改日 } } } } yue=12; write_nyr(6,yue); temp=(yue)/10*16+(yue)%10; write_byte(DS3231_MONTH,temp);//修改月 write_1602com(yh+6); break; case7: nian--; if(nian==-1) nian=99; write_nyr(3,nian); temp=(nian)/10*16+(nian)%10; write_byte(DS3231_YEAR,temp);//修改年 write_1602com(yh+3); break; } voidmain() { uintii=0; lcd_init(); RESET=0x1;//DS3231复位操作,正常操作下不需要每次都复位 TMOD=0x11;//定时器0,1工作模式1,16位定时方式 TH0=0; TL0=0; EA=1; ET0=1; TCON=0x01; IE=0x82;//使能timer0,1中断 TR0=1; //ModifyTime(17,8,15,23,02,20,2);//初始化,年月日时分秒星期(24小时制) while (1) { keyscan(); } } voidtimer0()interrupt1 { //TH0=(65536-60000)/256; //TL0=(65536-60000)%256; miao=BCD_Decimal(read_random(DS3231_SECOND)); fen=BCD_Decimal(read_random(DS3231_MINUTE)); shi=BCD_Decimal(read_random(DS3231_HOUR)); ri=BCD_Decimal(read_random(DS3231_DAY)); yue=BCD_Decimal(read_random(DS3231_MONTH)); nian=BCD_Decimal(read_random(DS3231_YEAR)); week=BCD_Decimal(read_random(DS3231_WEEK)); //温度高4位 //温度低4位 temp1=BCD_Decimal(read_random(DS3231_TEMPERATUREH)); temp2=BCD_Decimal(read_random(DS3231_TEMPERATUREL)); keyscan(); temp2=(temp2>
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DS3231 高精度 时钟 程序代码 单片机 STC89c52RC 1602 显示