锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

基于单片机、DS1302、DS1602的电子时钟,可以设置时间日期

时间:2024-04-16 20:07:10

这是DS1602+DS1302完整程序,其中P1口接独立 。 DS1602部分: # include "SY M.H" //#ifndef __ 1602_8_H__ //#define __LCD1602_8_H__ //LCD 定义 sfr io = 0x80; //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0; sbit rs = P2^6; //LCD数据/命令选择端(H/L) sbit rw = P2^5; //LCD读/写选择端(H/L) sbit ep = P2^7; //LCD使能控制 sbit bz = io^7; //LCD忙标志位 //函数声明 void lcd_busy(void); //测试LCD忙碌状态程序 void lcd_wcmd(unsigned char cmd); //写入指令到LCD程序 void lcd_wdat(unsigned char dat); //写入数据到LCD程序 void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序 void lcd_sef_chr(); //void printc(unsigned char CHAR); //显示字符 void lcd_init(void); //LCD初始化设定程序 //测试LCD忙碌状态 void lcd_busy(void) { do{ ep = 0; rs = 0; //指令 rw = 1; //读出 io = 0xff; ep = 1; _nop_(); //高电平读出 1us }while(bz); //bz=1表示忙,bz=0表示空闲 ep = 0; } //写入指令到LCD void lcd_wcmd(unsigned char cmd) { lcd_busy(); //检测忙 rs = 0; //指令 rw = 0; //写入 ep = 1; io = cmd; //指令 ep = 0; //下降沿有效 } //写入数据函数 void lcd_wdat(unsigned char Data) { lcd_busy(); //检测忙 rs = 1; //数据 rw = 0; //写入 ep = 1; io = Data; //数据 ep = 0; //下降沿有效 } //LCD数据指针位置程序 void lcd_pos(unsigned char x, bit y) { if(y)lcd_wcmd(x|0xc0); //y=1,第二行显示;y=0,第一行显示 0<=x<16 else lcd_wcmd(x|0x80); //数据指针=80+地址码(00H~27H,40H~67H) } //显示字符 // void printc(unsigned char CHAR) { lcd_wdat(CHAR); } // //显示字符串 void prints(unsigned char //string) { //unsigned char i; //do{lcd_wdat(string[i]);i++;}while(string[i]!='\0');//生成代码比for循环大 for(i=0;string[i]!='\0';i++)lcd_wdat(string[i]); //有时用for循环也好哈// while(//string) {lcd_wdat(//string);string++;} } //LCD初始化设定 void lcd_init() { lcd_wcmd(0x38); //设置LCD为16X2显示,5X7点阵,八位数据接口 lcd_wcmd(0x06); //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动) lcd_wcmd(0x0c); //LCD开显示及光标设置(光标不闪烁,不显示"_") lcd_wcmd(0x01); //清除LCD的显示内容 } DS1302部分: # include "SY EM.H" //#ifndef __DS1302_A_H__ //#define __DS1302_A_H__ //引脚及位的定义 sbit DS1302_CLK = P3^6; //时钟引脚 sbit DS1302_IO = P3^4; //数据引脚 sbit DS1302_RST = P3^5; //复位引脚 sbit ACC0 = ACC^0; sbit ACC7 = ACC^7; //函数声明 void DS1302_InputByte(unchar Data); //写入一个字节(内部函数) unchar DS1302_OutputByte(void); //读取一个字节(内部函数) void Write1302(unchar Address, unchar Data); //在指定地址写入指定的数据 unchar Read1302(unchar Address); //读取DS1302指定地址中的数据 void DS1302_SetProtect(bit Flag); //DS1302是否写入保护 void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数 void DS1302_GetTime(SYS MTIME *Time); //读出时间 void DateToStr(SYSTEMTIME *Time); //日期转化成字符 void TimeToStr(SYSTEMTIME *Time); //时间转化成字符 void DS1302_Initial (void); //DS1302初始化 //写入一个字节(内部函数) void DS1302_InputByte(unchar Data) { unchar i; ACC = Data; for(i=8; i>0; i--) { DS1302_CLK = 0; DS1302_IO = ACC0; //由低位到高位 DS1302_CLK = 1; //上升沿写入数据 ACC >>= 1; } } //读取一个字节(内部函数) unchar DS1302_OutputByte(void) { unchar i; for(i=8; i>0; i--) { DS1302_CLK = 0; //下降沿读出DS1302的数据 ACC >>= 1; //读出由低到高位,只能移7次有效位!!! ACC7 = DS1302_IO; //第一个数据 DS1302_CLK = 1; } return (ACC); } //在指定地址写入指定的数据 void Write1302(unchar Address, unchar Data) { DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302_InputByte(Address); DS1302_InputByte(Data); DS1302_CLK = 1; DS1302_RST = 0; } //读取1302指定地址中的数据 unchar Read1302(unchar Address) { unchar Data; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; //RST拉高,启动数据传送 DS1302_InputByte(Address|0x01);//读取指定地址数据指令 Data = DS1302_OutputByte(); DS1302_CLK = 1; DS1302_RST = 0; return (Data); } //是否写入保护 void DS1302_SetProtect(bit Flag) { if(Flag) Write1302(0x8E,0x80); //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302 else Write1302(0x8E,0x00); //WP=0 允许数据写入DS1302 } //设置时间函数 void DS1302_SetTime(unchar Address, unchar Value) { DS1302_SetProtect(0); Write1302(Address,((Value/10)<<4|(Value))); DS1302_SetProtect(1); } //读出时间 void DS1302_GetTime(SYSTEMTIME *Time) { unchar ReadValue; ReadValue = Read1302(DS1302_SEC D); Time-> nd = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_MINUTE); Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_HOUR); Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_DAY); Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_WEEK); Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_MO H); Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); ReadValue = Read1302(DS1302_YEAR); Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f); } //日期转化成字符 void DateToStr(SYSTEMTIME *Time) { Time->DateString[0] = Time->Year/10 + '0'; Time->DateString[1] = Time->Year + '0'; Time->DateString[2] = '-'; Time->DateString[3] = Time->Month/10 + '0'; Time->DateString[4] = Time->Month + '0'; Time->DateString[5] = '-'; Time->DateString[6] = Time->Day/10 + '0'; Time->DateString[7] = Time->Day + '0'; Time->DateString[8] = '\0'; } //时间转化成字符 void TimeToStr(SYSTEMTIME *Time) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour + '0'; Time->TimeString[2] = ':'; Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute + '0'; Time->TimeString[5] = ':'; Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second + '0'; Time->TimeString[8] = '\0'; } //初始化DS1302 void DS1302_Initial (void) { unchar Second=Read1302(DS1302_SECOND); if(Second&0x80)//bit7=CH CH=0 允许工作,CH=1振荡器停止工作 DS1302_SetTime(DS1302_SECOND,0); } 函数声明SYSTEM.H: //包含头文件 #include #include //#include"LCD1602_8.H" //#include"DS1302_A.H" //P0 Bit Registers sbit P0_0 = 0x80; sbit P0_1 = 0x81; sbit P0_2 = 0x82; sbit P0_3 = 0x83; sbit P0_4 = 0x84; sbit P0_5 = 0x85; sbit P0_6 = 0x86; sbit P0_7 = 0x87; //P1 Bit Registers sbit P1_0 = 0x90; sbit P1_1 = 0x91; sbit P1_2 = 0x92; sbit P1_3 = 0x93; sbit P1_4 = 0x94; sbit P1_5 = 0x95; sbit P1_6 = 0x96; sbit P1_7 = 0x97; //P2 Bit Registers sbit P2_0 = 0xA0; sbit P2_1 = 0xA1; sbit P2_2 = 0xA2; sbit P2_3 = 0xA3; sbit P2_4 = 0xA4; sbit P2_5 = 0xA5; sbit P2_6 = 0xA6; sbit P2_7 = 0xA7; //P3 Bit Registers (Mnemonics & Ports) sbit P3_0 = 0xB0; sbit P3_1 = 0xB1; sbit P3_2 = 0xB2; sbit P3_3 = 0xB3; sbit P3_4 = 0xB4; sbit P3_5 = 0xB5; sbit P3_6 = 0xB6; sbit P3_7 = 0xB7; //宏定义便于理解 #define unchar unsigned char #define unint unsigned int #define DS1302_SECOND 0x80 #define DS1302_MINUTE 0x82 #define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A #define DS1302_DAY 0x86 #define DS1302_MONTH 0x88 #define DS1302_YEAR 0x8C #define DS1302_RAM(X) (0xC0+(X)*2) //用于计算RAM地址的宏运算 //定义时间类型 typedef struct _SYSTEMTIME_ { unchar Second; unchar Minute; unchar Hour; unchar Week; unchar Day; unchar Month; unchar Year; unchar DateString[9]; unchar TimeString[9]; }SYSTEMTIME; //LCD1602外部引用函数 extern void lcd_init(void); //LCD初始化设定程序 extern void prints(unsigned char *string); //显示字符串 extern void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序 extern void lcd_sef_chr() ; extern void lcd_wcmd(unsigned char cmd);//写入指令到LCD程序 //*DS1302外部引用函数 extern void DS1302_SetTime(unchar Address, unchar Value); //设置时间函数 extern void DS1302_Initial (void); //DS1302初始化 extern void DS1302_GetTime(SYSTEMTIME *Time); //读出时间 extern void DateToStr(SYSTEMTIME *Time); //日期转化成字符 extern void TimeToStr(SYSTEMTIME *Time); //时间转化成字符 MAIN函数部分: #include "SYSTEM.H" SYSTEMTIME CurrentTime; unsigned char k = 0; //键值 unsigned char K1,K2,K3,M1,M2,M3,K1J,K2J,K3J,K4J; //键值 unsigned char Set; //调整值 char Set_Mode = 0; void Keysan(void); void delay200ms(void); //主函数 void main(void) { lcd_init(); //lcd_sef_chr(); //写入自定义字符号 DS1302_Initial(); lcd_pos(0,0); prints("Date:"); lcd_pos(0,1); prints("Time:"); k = 6; //不改变时间 while(1) { Keysan(); DS1302_GetTime(&CurrentTime); DateToStr(&CurrentTime); TimeToStr(&CurrentTime); lcd_pos(6,0); prints(CurrentTime.DateString); lcd_pos(6,1); prints(Curr
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章