DS1302时钟芯片使用51单片机
51单片机使用DS1302实现时钟功能
调试过程中出现了很多情况,LCD1602显示的数据和写入的数据不一样;秒不是1秒+1,而是过了近2秒才+1,而且是不连续,中家缺少一些数据不显示,用示波器看波形也是正常的,没有显示在LCD1602的波形,在示波器数据中是存在的。后来发现是DS1302_Read_Byte中出现了问题,然而示波器里看不出来这里的时序是有问题的。
/**#include <reg52.h> #include<intrins.h> #define DATAOUTPUT P0 sbit SCK = P2^0; sbit IO = P2^1; sbit RST = P2^2; unsigned char code num[] = "0123456789ABCDEF"; unsigned char num_i; sbit RS = P2^4; sbit RW = P2^5; sbit EN = P2^6; void delayus() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void delayms(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i --) for(j = 110; j > 0; j --); } void Write_Data(unsigned char dat) { EN = 0; RS = 1; RW = 0; DATAOUTPUT = dat; // delayms(5); EN = 1; delayms(5); EN = 0; } void Write_Cmd(unsigned char cmd) { EN = 0; RS = 0; RW = 0; DATAOUTPUT = cmd; // delayms(5); EN = 1; delayms(5); EN = 0; } void Write_Str(unsigned char *s) { while(*s != '\0') { Write_Data(*s); delayms(5); s ++; } } void LCD1602_Init() { Write_Cmd(0x01); Write_Cmd(0x38); Write_Cmd(0x0f); Write_Cmd(0x06); } void DS1302_Write_Data(unsigned char cmd, unsigned char dat) { unsigned char i; SCK = 0; RST = 0; delayus(); RST = 0; delayus(); RST = 1; delayus(); for(i = 0; i < 8; i ++) { if((cmd&0x01)==0x01) { IO = 1; } else { IO = 0; } delayus(); SCK = 1; delayus(); cmd >>= 1; SCK = 0; delayus(); } for(i = 0; i < 8; i ++) { if((dat&0x01)==0x01) { IO = 1; } else { IO = 0; } delayus(); SCK = 1; delayus(); dat >>= 1; SCK = 0; delayus(); } RST = 0; } unsigned char DS1302_Read_Data(unsigned char cmd) { unsigned char i,val; SCK = 0; RST = 0; delayus(); RST = 0; delayus(); RST = 1; delayus(); for(i = 0; i < 8; i ++) { if((cmd&0x01)==0x01) { IO = 1; } else { IO = 0; } if(i < 7) { delayus(); SCK = 1; delayus(); cmd >>= 1; SCK = 0; delayus(); } if(i == 7) { delayus(); SCK = 1; delayus(); } } for(i = 0; i < 8; i ++) { if(IO == 1) val |= 0x80; else val |= 0x00; delayus(); SCK = 0; delayus(); if(i < 7) { SCK = 1; delayus(); } val >>= 1; } RST = 0; delayus(); return val; } void main() { unsigned char HR,MIN,SEC; LCD1602_Init(); DS1302_Write_Data(0x8e,0); //WP clear DS1302_Write_Data(0x80,0x80);//sec stop DS1302_Write_Data(0x84,8);//write HR 8 DS1302_Write_Data(0x82,8);//write MIN 16 DS1302_Write_Data(0x80,8);//write SEC 24 DS1302_Write_Data(0x8e,0x80); // WP start while(1) { HR = DS1302_Read_Data(0x85); MIN = DS1302_Read_Data(0x83); SEC = (DS1302_Read_Data(0x81))&0x7f; // hr1 = HR/16; // hr2 = HR%16; // hr = hr1*10 + hr2; Write_Cmd(0x80); Write_Data(num[HR/16]); Write_Cmd(0x81); Write_Data(num[HR%16]); Write_Cmd(0x82); Write_Str(":"); Write_Cmd(0x83); Write_Data(num[MIN/16]); Write_Cmd(0x84); Write_Data(num[MIN%16]); Write_Cmd(0x85); Write_Str(":"); Write_Cmd(0x86); Write_Data(num[SEC/16]); Write_Cmd(0x87); Write_Data(num[SEC%16]); } } */ #include<reg52.h> #include<intrins.h> sbit LCD1602_RS = P2^4; sbit LCD1602_RW = P2^5; sbit LCD1602_EN = P2^6; #define LCD1602_DataPort P0 sbit DS1302_SCK = P1^0; sbit DS1302_IO = P1^1; sbit DS1302_RST = P1^2; sbit LED = P1^3; #define DS1302_SEC 0X80 #define DS1302_MIN 0X82 #define DS1302_HR 0X84 #define DS1302_DATE 0X86 #define DS1302_MONTH 0X88 #define DS1302_DAY 0X8A #define DS1302_YEAR 0X8C #define DS1302_CONTOR 0X8E unsigned char DATE_MSG[] = {24,5,21,21,14,00,2};// year month date hr min sec day unsigned char DATE_MSG2[7]; unsigned char code NUM_Table[] = "0123456789ABCDEF"; unsigned char T0_t = 0,T0_num = 0, T0_FLAG = 0; //LCD1602 void delayus(unsigned char t); void delayms(unsigned int t); void LCD1602_Write_Data(unsigned char dat); void LCD1602_Write_Cmd(unsigned char cmd); void LCD1602_Write_Str(unsigned char *s); void LCD1602_Init(); //DS1302 void DS1302_Write_Byte(unsigned char cmd, unsigned char dat); unsigned char DS1302_Read_Byte(unsigned char cmd); void DS1302_Write_Data(); void DS1302_Read_Data(); //T0定时器 void T0_MODE2_Init(); //main void main() { T0_MODE2_Init(); LCD1602_Init(); DS1302_Write_Data(); // LCD1602_Write_Cmd(0x80); // LCD1602_Write_Str("hello world!"); // // LCD1602_Write_Cmd(0x80+0x40); // LCD1602_Write_Str("working!!!"); LCD1602_Write_Cmd(0x80); LCD1602_Write_Str(" - - "); LCD1602_Write_Cmd(0xc0); LCD1602_Write_Str(" : : "); while(1) { if(T0_FLAG) { DS1302_Read_Data(); T0_FLAG = 0; } LCD1602_Write_Cmd(0x80); LCD1602_Write_Data(NUM_Table[DATE_MSG2[0]/10]); // LCD1602_Write_Cmd(0x81); LCD1602_Write_Data(NUM_Table[DATE_MSG2[0]%10]); LCD1602_Write_Cmd(0x83); LCD1602_Write_Data(NUM_Table[DATE_MSG2[1]/10]); // LCD1602_Write_Cmd(0x84); LCD1602_Write_Data(NUM_Table[DATE_MSG2[1]%10]); LCD1602_Write_Cmd(0x86); LCD1602_Write_Data(NUM_Table[DATE_MSG2[2]/10]); // LCD1602_Write_Cmd(0x87); LCD1602_Write_Data(NUM_Table[DATE_MSG2[2]%10]); LCD1602_Write_Cmd(0xC0); LCD1602_Write_Data(NUM_Table[DATE_MSG2[3]/10]); // LCD1602_Write_Cmd(0xC1); LCD1602_Write_Data(NUM_Table[DATE_MSG2[3]%10]); LCD1602_Write_Cmd(0xC3); LCD1602_Write_Data(NUM_Table[DATE_MSG2[4]/10]); // LCD1602_Write_Cmd(0xC4); LCD1602_Write_Data(NUM_Table[DATE_MSG2[4]%10]); LCD1602_Write_Cmd(0xC6); LCD1602_Write_Data(NUM_Table[DATE_MSG2[5]/10]); // LCD1602_Write_Cmd(0xC7); LCD1602_Write_Data(NUM_Table[DATE_MSG2[5]%10]); } } void delayms(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i --) for(j = 110; j > 0; j --); } void delayus(unsigned char t) { while(t --) { _nop_(); } } //LCD1602--------------------------------------- void LCD1602_Write_Data(unsigned char dat) { LCD1602_EN = 0; // LCD1602_RW = 1; LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DataPort = dat; delayms(5); // LCD1602_EN = 0; // delayms(5); LCD1602_EN = 1; delayms(5); LCD1602_EN = 0; } void LCD1602_Write_Cmd(unsigned char cmd) { LCD1602_EN = 0; // LCD1602_RW = 1; LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DataPort = cmd; delayms(5); // LCD1602_EN = 0; // delayms(5); LCD1602_EN = 1; delayms(5); LCD1602_EN = 0; } void LCD1602_Write_Str(unsigned char *s) { while(*s != '\0') { LCD1602_Write_Data(*s); // delayms(5); s ++; } } void LCD1602_Init() { LCD1602_Write_Cmd(0x38); LCD1602_Write_Cmd(0x0c); LCD1602_Write_Cmd(0x06); LCD1602_Write_Cmd(0x01); } //DS1302------------------------------------------- /* void Ds1302_Write_Byte(unsigned char addr, unsigned char d) { unsigned char i; RST_SET; //写入目标地址:addr addr = addr & 0xFE; //最低位置零 for (i = 0; i < 8; i ++) { if (addr & 0x01) { IO_SET; } else { IO_CLR; } SCK_SET; SCK_CLR; addr = addr >> 1; } //写入数据:d for (i = 0; i < 8; i ++) { if (d & 0x01) { IO_SET; } else { IO_CLR; } SCK_SET; SCK_CLR; d = d >> 1; } RST_CLR; //停止DS1302总线 }*/ void DS1302_Write_Byte(unsigned char cmd, unsigned char dat) { unsigned char i; DS1302_RST = 0; DS1302_SCK = 0; DS1302_RST = 1; delayus(15); for(i = 0; i < 8; i ++) { delayus(15); if((cmd&0x01) == 0x01) { DS1302_IO = 1; } else DS1302_IO = 0; DS1302_SCK = 1; delayus(15); DS1302_SCK = 0; cmd >>= 1; } for(i = 0; i < 8; i ++) { delayus(15); if((dat&0x01) == 0x01) DS1302_IO = 1; else DS1302_IO = 0; DS1302_SCK = 1; delayus(15); DS1302_SCK = 0; dat >>= 1; } delayus(15); DS1302_RST = 0; delayus(15); } unsigned char DS1302_Read_Byte(unsigned char cmd) { unsigned char i,dat,val; dat = (cmd|0x01); DS1302_RST = 0; DS1302_SCK = 0; DS1302_RST = 1; delayus(15); for(i = 0; i < 8; i ++) { delayus(15); if((dat&0x01) == 0x01) { DS1302_IO = 1; } else DS1302_IO = 0; DS1302_SCK = 1; delayus(15); DS1302_SCK = 0; dat >>= 1; } for(i = 0; i < 8; i ++) { val >>= 1; //这一句找了好久,不然放最后,2s过去了秒才能+1 ,而且数据不对 delayus(15); if(DS1302_IO == 1) val |= 0x80; delayus(15); DS1302_SCK = 1; delayus(15); DS1302_SCK = 0; } delayus(15); DS1302_RST = 0; delayus(15); return val; } void DS1302_Write_Data() { unsigned char i ,tmp1; for(i = 0; i < 7; i ++) { tmp1 = DATE_MSG[i]/10; DATE_MSG[i] = DATE_MSG[i]%10; DATE_MSG2[i] = tmp1*16 + DATE_MSG[i]; } DS1302_Write_Byte(DS1302_CONTOR, 0x00);//WP DISABLE DS1302_Write_Byte(DS1302_SEC, 0X80);//STOP COUNT DS1302_Write_Byte(DS1302_YEAR, DATE_MSG2[0]); DS1302_Write_Byte(DS1302_MONTH, DATE_MSG2[1]); DS1302_Write_Byte(DS1302_DATE, DATE_MSG2[2]); DS1302_Write_Byte(DS1302_HR, DATE_MSG2[3]); DS1302_Write_Byte(DS1302_MIN, DATE_MSG2[4]); DS1302_Write_Byte(DS1302_DAY, DATE_MSG2[6]); DS1302_Write_Byte(DS1302_SEC, DATE_MSG2[5]);//START COUNT DS1302_Write_Byte(DS1302_CONTOR, 0x80);// WP ENABLE } void DS1302_Read_Data() { unsigned char i ,tmp1; DATE_MSG[0] = DS1302_Read_Byte(DS1302_YEAR); DATE_MSG[1] = DS1302_Read_Byte(DS1302_MONTH); DATE_MSG[2] = DS1302_Read_Byte(DS1302_DATE); DATE_MSG[3] = DS1302_Read_Byte(DS1302_HR); DATE_MSG[4] = DS1302_Read_Byte(DS1302_MIN); DATE_MSG[5] = DS1302_Read_Byte(DS1302_SEC)&0X7F; DATE_MSG[6] = DS1302_Read_Byte(DS1302_DAY); for(i = 0; i < 7; i ++) { tmp1 = DATE_MSG[i]/16; DATE_MSG2[i] = DATE_MSG[i]%16; DATE_MSG2[i] = tmp1*10 + DATE_MSG2[i]; } } //T0 void T0_MODE2_Init() { TMOD = 0x02; TH0 = (256-230); TL0 = (256-230); ET0 = 1; TR0 = 1; EA = 1; } void T0_Ser() interrupt 1 { T0_t ++; if(T0_t >= 40) { T0_t = 0; T0_num ++; { if(T0_num >= 100) { T0_num = 0; T0_FLAG = 1; LED = !LED; } } } }