51单片机使用ds3231模块

更新时间:2024-07-09 09:55:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

//DS3231某宝买的模块,5块不到的样子。麻烦大家下载一下,不要直接复制。89c52不能用1t的单片机。

//此修正版的文件可以解决之前的word下载后不能打开的蛋疼问题。1602数据端口是P2如果需要修改,只有2个地方需要改。 #include #include

#define uchar unsigned char #define uint unsigned int

#define yh 0x80 //第一行的初始位置 #define er 0x80+0x40 //第二行初始位置

sbitrs=P0^7;//1602的3个端口 sbitwr=P0^6; sbit en=P0^5;

sbit SDA=P1^6; //模拟I2C数据传送位SDA 模块只使用了2个端口 sbit SCL=P1^7; //模拟I2C时钟控制位SCL //sbit INT=P3^2;

sbit key1=P3^5; //功能键,修改键这是3个按键,低电平有效,串联个4到10千欧的电阻到按键开关上,然后接地就行 sbit key2=P3^4; //上调键 sbit key3=P3^3; //下调键 //sbit RESET=P3^3;

bit ack; //应答标志位

#define DS3231_WriteAddress 0xD0 //器件写地址 #define DS3231_ReadAddress 0xD1 //器件读地址 #define DS3231_SECOND 0x00 //秒 #define DS3231_MINUTE 0x01 //分 #define DS3231_HOUR 0x02 //时 #define DS3231_WEEK 0x03 //星期 #define DS3231_DAY 0x04 //日 #define DS3231_MONTH 0x05 //月 #define DS3231_YEAR 0x06 //年 //闹铃1

#define DS3231_SALARM1ECOND 0x07 //秒 #define DS3231_ALARM1MINUTE 0x08 //分 #define DS3231_ALARM1HOUR 0x09 //时

#define DS3231_ALARM1WEEK 0x0A //星期/日 //闹铃2

#define DS3231_ALARM2MINUTE 0x0b //分 #define DS3231_ALARM2HOUR 0x0c //时

#define DS3231_ALARM2WEEK 0x0d //星期/日 #define DS3231_CONTROL 0x0e //控制寄存器

#define DS3231_STATUS 0x0f //状态寄存器 #define BSY 2 //忙

#define OSF 7 //振荡器停止标志 #define DS3231_XTAL 0x10 //晶体老化寄存器

#define DS3231_TEMPERATUREH 0x11 //温度寄存器高字节(8位) #define DS3231_TEMPERATUREL 0x12 //温度寄存器低字节(高2位)

uchar a,miao,shi,fen,ri,yue,nian,week,temp1,temp2,key1n,temp; uchar code tab1[]={\ - FRI%uchar code tab2[]={\ : : .\ /*

uchar HEX2BCD(ucharval) //B码转换为BCD码 {

uchar k; k=(val)/10*16+(val); return k; } */

ucharBCD_Decimal(ucharbcd) {

uchar Decimal; Decimal=bcd>>4;

return(Decimal=Decimal*10+(bcd&=0x0F)); }

void delayus(uint us) {

while (us--); }

void Start_I2C() {

SDA=1; //发送起始条件的数据信号 delayus(1); SCL=1;

delayus(5); //起始条件建立时间大于4.7us,延时

SDA=0; //发送起始信号

delayus(5); // 起始条件锁定时间大于4μs

SCL=0; //钳住I2C总线,准备发送或接收数据 delayus(2); }

void Stop_I2C() {

SDA=0; //发送结束条件的数据信号 delayus(1); //发送结束条件的时钟信号

SCL=1; //结束条件建立时间大于4us delayus(5);

SDA=1; //发送I2C总线结束信号 delayus(4); }

void SendByte(uchar c) {

ucharBitCnt;

for(BitCnt=0;BitCnt<8;BitCnt++) {

if((c<

SDA=1; else

SDA=0; delayus(1);

SCL=1; 据位

delayus(5); SCL=0; }

delayus(2);

SDA=1; 答位

delayus(2); SCL=1; delayus(3); if(SDA==1) ack=0; else

ack=1; SCL=0; delayus(2); }

ucharRcvByte()

//要传送的数据长度为8位 //判断发送位 //置时钟线为高,通知被控器开始接收数//保证时钟高电平周期大于4μs //8位发送完后释放数据线,准备接收应 //判断是否接收到应答信号 {

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); }

void Ack_I2C(bit a) {

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) return 0;

SendByte(addr); if (ack == 0) return 0;

SendByte(write_data); if (ack == 0) return 0;

Stop_I2C(); delayus(10); return 1; }

ucharread_current() {

ucharread_data; Start_I2C();

SendByte(DS3231_ReadAddress); if(ack==0) return(0);

read_data = RcvByte(); Ack_I2C(1); Stop_I2C();

return read_data; }

ucharread_random(ucharrandom_addr) {

Start_I2C();

SendByte(DS3231_WriteAddress); if(ack==0) return(0);

SendByte(random_addr); if(ack==0) return(0);

break; case 2:fen++; if(fen==60) fen=0; write_sfm(0x03,fen); temp=(fen)/10*16+(fen); write_byte(DS3231_MINUTE,temp); write_1602com(er+3); break; case 3:shi++; if(shi==24) shi=0; write_sfm(0,shi); temp=(shi)/10*16+(shi); write_byte(DS3231_HOUR,temp); write_1602com(er+0); break; case 4:week++; if(week==8) week=0; write_week(week); write_byte(DS3231_WEEK,week); //修改星期 write_1602com(yh+0x0d); break; case 5:ri++; if(ri==31) ri=0; write_nyr(9,ri); temp=(ri)/10*16+(ri); write_byte(DS3231_DAY,temp); //修改日 write_1602com(yh+9); break; case 6:yue++; if(yue==13) yue=0; write_nyr(6,yue); temp=(yue)/10*16+(yue); write_byte(DS3231_MONTH,temp); //修改月 write_1602com(yh+6); break; case 7:nian++; if(nian==100) nian=0; write_nyr(3,nian);

} }

temp=(nian)/10*16+(nian);

write_byte(DS3231_YEAR,temp); //修改年 write_1602com(yh+3); break;

}

if(key3==0) {

delayus(5000); if(key3==0) {

while(!key3); switch(key1n) { case 1:miao--; if(miao==-1) miao=59;

write_sfm(6,miao);//写入新的秒数 temp=(miao)/10*16+(miao);

write_byte(DS3231_SECOND,temp); //修改秒 write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 break; case 2:fen--; if(fen==-1) fen=59; write_sfm(3,fen); temp=(fen)/10*16+(fen); write_byte(DS3231_MINUTE,temp); //修改分 write_1602com(er+3); break; case 3:shi--; if(shi==-1) shi=23; write_sfm(0,shi); temp=(shi)/10*16+(shi); write_byte(DS3231_HOUR,temp); //修改时 write_1602com(er+0);

} } } }

break; case 4:week--; if(week==-1) week=7; write_week(week);

write_byte(DS3231_WEEK,week); //修改星期 write_1602com(yh+0x0d); break; case 5:ri--; if(ri==-1) ri=30; write_nyr(9,ri); temp=(ri)/10*16+(ri); write_byte(DS3231_DAY,temp); //修改日 write_1602com(yh+9); break; case 6:yue--; if(yue==-1) yue=12; write_nyr(6,yue); temp=(yue)/10*16+(yue); write_byte(DS3231_MONTH,temp); //修改月 write_1602com(yh+6); break; case 7:nian--; if(nian==-1) nian=99; write_nyr(3,nian); temp=(nian)/10*16+(nian); write_byte(DS3231_YEAR,temp); //修改年 write_1602com(yh+3); break;

}

void main() {

uint ii = 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,10,6,21,50,20,5); //初始化,年月日时分秒星期(24小时制) //这个函数不能用,因为如果使用这个函数,会导致断电后重新打开就重置了时间。

while(1) { keyscan();

} }

void timer0() interrupt 1 { //TH0=(65536-60000)/256; //TL0=(65536-60000)%6; 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));

temp1=BCD_Decimal(read_random(DS3231_TEMPERATUREH)); //温度高4位 temp2=BCD_Decimal(read_random(DS3231_TEMPERATUREL)); //温度低4位 keyscan(); temp2=(temp2>>6)*25; write_sfm(6,miao); //write_1602com(er+0x0a); //write_1602dat(':'); write_sfm(3,fen); //write_1602com(er+0x07); //write_1602dat(':'); write_sfm(0,shi); write_nyr(3,nian); write_nyr(9,ri); write_nyr(6,yue); write_week(week);

write_sfm(9,temp1); write_sfm(12,temp2); }

本文来源:https://www.bwwdw.com/article/z92.html

Top