51单片机使用ds3231模块.docx
- 文档编号:9450935
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:24
- 大小:18.74KB
51单片机使用ds3231模块.docx
《51单片机使用ds3231模块.docx》由会员分享,可在线阅读,更多相关《51单片机使用ds3231模块.docx(24页珍藏版)》请在冰豆网上搜索。
51单片机使用ds3231模块
//DS3231某宝买的模块,5块不到的样子。
麻烦大家下载一下,不要直接复制。
89c52不能用1t的单片机。
//此修正版的文件可以解决之前的word下载后不能打开的蛋疼问题。
1602数据端口是P2如果需要修改,只有2个地方需要改。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineyh0x80//第一行的初始位置
#defineer0x80+0x40//第二行初始位置
sbitrs=P0^7;//1602的3个端口
sbitwr=P0^6;
sbiten=P0^5;
sbitSDA=P1^6;//模拟I2C数据传送位SDA模块只使用了2个端口
sbitSCL=P1^7;//模拟I2C时钟控制位SCL
//sbitINT=P3^2;
sbitkey1=P3^5;//功能键,修改键这是3个按键,低电平有效,串联个4到10千欧的电阻到按键开关上,然后接地就行
sbitkey2=P3^4;//上调键
sbitkey3=P3^3;//下调键
//sbitRESET=P3^3;
bitack;//应答标志位
#defineDS3231_WriteAddress0xD0//器件写地址
#defineDS3231_ReadAddress0xD1//器件读地址
#defineDS3231_SECOND0x00//秒
#defineDS3231_MINUTE0x01//分
#defineDS3231_HOUR0x02//时
#defineDS3231_WEEK0x03//星期
#defineDS3231_DAY0x04//日
#defineDS3231_MONTH0x05//月
#defineDS3231_YEAR0x06//年
//闹铃1
#defineDS3231_SALARM1ECOND0x07//秒
#defineDS3231_ALARM1MINUTE0x08//分
#defineDS3231_ALARM1HOUR0x09//时
#defineDS3231_ALARM1WEEK0x0A//星期/日
//闹铃2
#defineDS3231_ALARM2MINUTE0x0b//分
#defineDS3231_ALARM2HOUR0x0c//时
#defineDS3231_ALARM2WEEK0x0d//星期/日
#defineDS3231_CONTROL0x0e//控制寄存器
#defineDS3231_STATUS0x0f//状态寄存器
#defineBSY2//忙
#defineOSF7//振荡器停止标志
#defineDS3231_XTAL0x10//晶体老化寄存器
#defineDS3231_TEMPERATUREH0x11//温度寄存器高字节(8位)
#defineDS3231_TEMPERATUREL0x12//温度寄存器低字节(高2位)
uchara,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μs
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++)//要传送的数据长度为8位
{
if((c< SDA=1;//判断发送位 else SDA=0; delayus (1); SCL=1;//置时钟线为高,通知被控器开始接收数据位 delayus(5);//保证时钟高电平周期大于4μs SCL=0; } 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++) { delayus (1); SCL=0;//置时钟线为低,准备接收数据位 delayus(5);//时钟低电平周期大于4.7μs SCL=1;//置时钟线为高使数据线上数据有效 delayus(3); retc=retc<<1; if(SDA==1) retc=retc+1;//读数据位,接收的数据位放入retc中 delayus (2); } SCL=0; delayus (2); return(retc); } voidAck_I2C(bita) { if(a==0) SDA=0;//在此发出应答或非应答信号 else SDA=1; delayus(3); SCL=1; delayus(5);//时钟低电平周期大于4μs 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(); delayus(10); 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) return(0); SendByte(random_addr); if(ack==0) return(0); return(read_current()); } /* voidModifyTime(ucharyea,ucharmon,ucharda,ucharhou,ucharmin,ucharsec,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);//修改时 temp=HEX2BCD(min); write_byte(DS3231_MINUTE,temp);//修改分 temp=HEX2BCD(sec); write_byte(DS3231_SECOND,temp);//修改秒 temp=HEX2BCD(week); write_byte(DS3231_WEEK,temp);//修改星期 } */ /******************液晶写入************************/ voidwrite_1602com(uchar)//液晶写入指令函数 { rs=0;//置为写入命令 P2=;//送入数据 delayus(1000); en=1;//拉高使能端 delayus(1000); en=0;//完成高脉冲 } voidwrite_1602dat(uchardat) { rs=1;//置为写入数据 P2=dat;//送入数据 delayus(1000); en=1; delayus(1000); en=0; } /*********************over***********************/ voidlcd_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++) { write_1602dat(tab2[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); write_1602dat('E');//delay(5); write_1602dat('D'); 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; case2: write_1602com(er+3);//fen //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); write_sfm(0x03,fen); 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_byte(DS3231_HOUR,temp); 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_1602
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 使用 ds3231 模块