第九讲 1602LCD DS1302 24C08器件的编程
- 格式:ppt
- 大小:1.64 MB
- 文档页数:21
/////////////////////////////////////////////////////////////*********************1602时钟****************************//***********2010年09月22日10:10至次日00:09做**************/ ////////////////////////////////////////////////////////////#include <reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define SECOND 0x81#define MINUTE 0x83#define HOUR 0x85sbit rs=P2^0;sbit rw=P2^1;sbit ep=P2^2;sbit DS1302_SCLK = P1^0;sbit DS1302_IO= P1^1;sbit DS1302_RST = P1^2;sbit M=P3^2;sbit U=P3^3;sbit D=P3^4;unsigned char sel=0;uchar code DIS1[]={"Centrineer"};uchar code DIS2[]={"QQ:778341220"};/////////////////////////延时////////////////////////////////void delay(uint ms){unsigned int a,b;for(a=0;a<ms;a++)for(b=0;b<120;b++);}/////////////////////////////////////////////////////////////***************DS1302驱动************************/////////////////////////////////////////////////////////////void DS1302_Write(uchar D){uchar i;for(i=0;i<8;i++){DS1302_IO=D&0x01;DS1302_SCLK=1;DS1302_SCLK=0;D=D>>1;}}////////////////////////////////////////////////////////////uchar DS1302_Read(){uchar TempDat=0,i;for(i=0;i<8;i++){TempDat>>=1;if(DS1302_IO) TempDat=TempDat|0x80;DS1302_SCLK=1;DS1302_SCLK=0;}return TempDat;}////////////////////////////////////////////////////////////void WDS1302(uchar ucAddr, uchar ucDat){DS1302_RST = 0;DS1302_SCLK = 0;DS1302_RST = 1;DS1302_Write(ucAddr);DS1302_Write(ucDat);DS1302_SCLK = 1;DS1302_RST = 0;}////////////////////////////////////////////////////////////uchar RDS1302(uchar ucAddr){uchar ucDat;DS1302_RST = 0;DS1302_SCLK = 0;DS1302_RST = 1;DS1302_Write(ucAddr);ucDat=DS1302_Read();DS1302_SCLK = 1;DS1302_RST = 0;return ucDat;}//////////////////////////////////////////////////////////void init_1302(){WDS1302(0x8e,0x00);//开保护寄存器WDS1302(0x80,0x55);//秒WDS1302(0x82,0x59);//分WDS1302(0x84,0x23);//时WDS1302(0x8A,0x07);//星期WDS1302(0x86,0x02);//日WDS1302(0x88,0x08);//月WDS1302(0x8C,0x09);//年WDS1302(0x90,0xab);//卷电流充电WDS1302(0x8e,0x80);//关保护寄存器}///////////////////////////////////////////////////////////************************1602驱动************************/ //////////////////////////////////////////////////////////bit lcd_bz(){bit result;rs = 0;rw = 1;ep = 1;_nop_();_nop_();_nop_();_nop_();result = (bit)(P0 & 0x80);ep = 0;return result;}////////////////////////////////////////////////////////void lcd_wcmd(unsigned char cmd){while(lcd_bz());rs = 0;rw = 0;ep = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep= 0;}/////////////////////////////////////////////////////////void lcd_pos(unsigned char pos){lcd_wcmd(pos | 0x80);}/////////////////////////////////////////////////////////void lcd_wdat(unsigned char dat){while(lcd_bz());rs = 1;rw = 0;ep = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//////////////////////////////////////////////////////////void lcd_init(){lcd_wcmd(0x38);delay(1);lcd_wcmd(0x0c);delay(1);lcd_wcmd(0x06);delay(1);lcd_wcmd(0x01);delay(1);}//////////////////////////////////////////////////////////*********************调时函数*************************//////////////////////////////////////////////////////////void set_time(){signed char address,item;signed char max,mini;if(M==0){sel++;delay(300);if(sel==6) sel=0;if(sel==2) {address=0x82; max=59;mini=0; }if(sel==1) {address=0x84; max=23;mini=0; }if(sel==3) {address=0x8c; max=99;mini=9;}if(sel==4) {address=0x88; max=12;mini=1; }if(sel==5) {address=0x86; max=31;mini=1; }M=1;}item=((RDS1302(address+1))/16)*10 + (RDS1302(address+1))%16; if(U == 0){delay(200);U=1;item++;}if(D == 0){delay(200);D=1;item--;}if(item>max) item=mini;if(item<mini) item=max;WDS1302(0x8e,0x00);//允许写操作WDS1302(address,(item/10)*16+item%10);WDS1302(0x8e,0x80);//写保护,禁止写操作}//////////////////////////////////////////////////////////*********************显示子函数************************/ /////////////////////////////////////////////////////////uchar lcdshow_u(uchar i,uchar y){lcd_wcmd(0x80+0x00+i);lcd_wdat(y);}uchar lcdshow_d(uchar i,uchar y){lcd_wcmd(0x80+0x40+i);lcd_wdat(y);}//////////////////////////////////////////////////////////*******************显示函数****************************/ /////////////////////////////////////////////////////////void display(void){uchar x,y;x=RDS1302(HOUR);y=x;x=x>>4; lcdshow_u(6,0x30+x);y=y&0x0f; lcdshow_u(7,0x30+y);lcdshow_u(8,':');x=RDS1302(MINUTE);y=x;x=x>>4; lcdshow_u(9,0x30+x);y=y&0x0f; lcdshow_u(0x0a,0x30+y);lcdshow_u(0x0b,':');x=RDS1302(SECOND);y=x;x=x>>4; lcdshow_u(0x0c,0x30+x);y=y&0x0f; lcdshow_u(0x0d,0x30+y);x=RDS1302(0x8d);y=x;x=x>>4; lcdshow_d(8,0x30+x);y=y&0x0f; lcdshow_d(9,0x30+y);lcdshow_d(0x0a,'-');x=RDS1302(0x89);y=x;x=x>>4; lcdshow_d(0x0b,0x30+x);y=y&0x0f; lcdshow_d(0x0c,0x30+y);lcdshow_d(0x0d,'-');x=RDS1302(0x87);y=x;x=x>>4; lcdshow_d(0x0e,0x30+x);y=y&0x0f; lcdshow_d(0x0f,0x30+y);for(x=45;x>0;x--){set_time();delay(10);}}/////////////////////////////////////////////////////////////////**************************主函数******************************/ ////////////////////////////////////////////////////////////////void main(){uchar i;lcd_init();delay(10);lcd_pos(0x03);i = 0;while(DIS1[i] != '\0'){lcd_wdat(DIS1[i]);i++;}lcd_pos(0x42);i = 0;while(DIS2[i] != '\0'){lcd_wdat(DIS2[i]);i++;}//init_1302();delay(1000);for(i=0;i<17;i++){lcdshow_u(i,'>');delay(90) ;}for(i=0;i<17;i++){lcdshow_d(i,'>');delay(90) ;}lcd_init();delay(10);lcdshow_u(0,'T');lcdshow_u(1,'i');lcdshow_u(2,'m');lcdshow_u(3,'e');lcdshow_d(0,'D');lcdshow_d(1,'a');lcdshow_d(2,'t');lcdshow_d(3,'a');lcdshow_d(6,'2');lcdshow_d(7,'0'); //LCD框架描绘while(1){set_time();if(sel==2) {lcdshow_u(9,' ');lcdshow_u(0x0a,' ');delay(500); }if(sel==1) {lcdshow_u(6,' ');lcdshow_u(7,' ');delay(500); }if(sel==4) {lcdshow_d(0x0b,' ');lcdshow_d(0x0c,' ');delay(500); }if(sel==5) {lcdshow_d(0x0e,' ');lcdshow_d(0x0f,' ');delay(500); } //调时LCD闪烁显示display();}}。
DS1302测试程序晶振:11.0592MHZ/*********************************包含头文件********************************/#include "reg51.h"#include <intrins.h>/*********************************端口定义**********************************/ sbit DS1302_CLK = P1^0;sbit DS1302_IO = P1^1;sbit DS1302_RST = P1^2;/******************************定义全局变量*********************************/ unsigned char second,minute,hour,week,day,month,year; //秒、分、时、星期、日、月、年unsigned char time[]={0x06,0x03,0x14,0x03,0x12,0x30,0x00}; //初始时间数组/**************************************************************************** 函数功能:数码管扫描延时子程序入口参数:出口参数:****************************************************************************/ void delay1(void){int k;for(k=0;k<400;k++);}/***************************************************************************** 函数功能:向DS1302送一字节数据子程序入口参数:出口参数:*****************************************************************************/ void InputByte(unsigned char byte1){char i;for(i=8;i>0;i--){DS1302_IO=(bit)(byte1&0x01);DS1302_CLK=1;_nop_();DS1302_CLK=0;byte1>>=1;}return;}/***************************************************************************** 函数功能:读DS1302一个字节子程序入口参数:出口参数:*****************************************************************************/ unsigned char outputbyte(void){unsigned char i;unsigned ucdat=0;for(i=8;i>0;i--){DS1302_IO=1;ucdat>>=1;if(DS1302_IO)ucdat|=0x80;DS1302_CLK=1;_nop_();DS1302_CLK=0;}return(ucdat);}/***************************************************************************** 函数功能:向DS1302某地址写一字节数据子程序入口参数:addr,TDat出口参数:*****************************************************************************/ void write_ds1302(unsigned char addr,unsigned char TDat){DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);_nop_();InputByte(TDat);DS1302_CLK=1;_nop_();DS1302_RST=0;}/***************************************************************************** 函数功能:读DS1302地址子程序入口参数:add出口参数:timedata*****************************************************************************/ unsigned char read_ds1302(unsigned char addr){unsigned char timedata;DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);timedata=OutputByte();DS1302_CLK=1;_nop_();DS1302_RST=0;return(timedata);}/***************************************************************************** 函数功能:初始化DS1302子程序入口参数:time[](全局变量)出口参数:*****************************************************************************/ void initial_ds1302(){write_ds1302(0x8e,0x00); //写保护寄存器,在对时钟或RAM写前WP一定要为0write_ds1302(0x8c,time[0]); //年write_ds1302(0x88,time[1]); //月write_ds1302(0x86,time[2]); //日write_ds1302(0x8A,time[3]); //星期write_ds1302(0x84,time[4]); //时write_ds1302(0x82,time[5]); //分write_ds1302(0x80,time[6]); //秒write_ds1302(0x8e,0x80); //写保护寄存器}/***************************************************************************** 函数功能:读DS1302时间子程序入口参数:出口参数:全局变量(second,minute,hour,week,day,month,year)*****************************************************************************/ void read_time(){second=read_ds1302(0x81); //秒寄存器minute=read_ds1302(0x83); //分hour=read_ds1302(0x85); //时week=read_ds1302(0x8B); //星期day=read_ds1302(0x87); //日month=read_ds1302(0x89); //月year=read_ds1302(0x8d); //年}void write_com(uchar com){P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}//液晶读写程序//void write_date(uchar date){P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void init(){dula=0;wela=0;write_com(0x38);delay(20);write_com(0x0f);delay(20);write_com(0x06);delay(20);write_com(0x01);delay(20);}//液晶显示时间程序//void time_display(){void write_com(0x80);void write_date(year);void write_com(0x80+5);void write_date(month);void write_com(0x80+8);void write_date(day);void write_com(0x80+11);void write_date(week);}/***************************************************************************** 函数功能:主程序入口参数:出口参数:*****************************************************************************/ void main(void){initial_ds1302(); //初始化DS1302while(1){read_time(); //读取时间time_display(); //显示时间}}。
/*============================================================1602液晶显示DS1302时钟=============================================================*/#include <AT89X51.h>#include <string.h>#include < intrins.h >#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;#define LCM_RW P2_1 //定义引脚#define LCM_RS P2_0#define LCM_E P2_2#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识#define uchar unsigned charsbit T_CLK=P1^0;sbit T_IO =P1^1;sbit T_RST=P1^2;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit system=P1^4; //模式对应实验板K1按键sbit TimerUp=P1^5; //时间减对应实验板K2按键sbit TimerDown=P1^6; //时间加对应实验板K3按键sbit wireless =P3^3;sbit wireless_up=P3^2;sbit wireless_down=P3^1;void Set(uchar,uchar); //根据选择调整相应项目void RTInputByte(uchar); //输入1Byte */uchar RTOutputByte(void); //输出1Byte */void W1302(uchar, uchar); //向DS1302写入一个字节uchar R1302(uchar); //从DS1302读出一个字节void Set1302(uchar * ); //设置时间uchar id,msec,model,LedTime,d;bit a,b; //闪烁标志位uchar inittime[7]={0x50,0x59,0x23,0x24,0x07,0x05,0x09}; //初始化后设置为:09年7月24日星期5 23点59分50秒void Out_LCM(void); //显示屏幕void model0(void); //显示输出void model1(void);void model2(void);void model3(void);void id_case1_key(); //项目调整void Modset(); //模式键处理void WriteDataLCM(uchar WDLCM);void WriteCommandLCM(uchar WCLCM,BuysC);uchar ReadStatusLCM(void);void LCMInit(void);void OutputInformation(uchar X, uchar Y, uchar DData);void DisplayListChar(uchar X, uchar Y, uchar code *DData);void Delay5Ms(void);void Delay400Ms(void);void systemsetup(void); //进入系统设置uchar code systemp[]={"System.setup"}; //字符串输出(系统设定)uchar code TIMER[]={"Time"}; //字符串输出(时间)uchar code DATE[]={"Date"}; //字符串输出(日期)uchar code exit[]={"Exit"}; //字符串输出(退出)void timesetup(void); //时间设置void datesetup(void); //日期设置/*******************************************************************/ void delay1(int ms){unsigned char y ;while(ms--){for(y = 0 ; y<250 ; y++){_nop_() ;_nop_() ;_nop_() ;_nop_() ;}}}void main(void){Delay400Ms(); //启动等待,等LCM讲入工作状态LCMInit(); //LCM初始化TMOD=0x01; //16位定时TH0=0x3c; //50msTL0=0xb0;EA=1;TR0=1;ET0=1;wireless=0;wireless_up=0;wireless_down=0;while(1){b=1; //模式键是否动作标志。
附A: 原理图附B:汇编源程序; ―――――――――――――――――――――――――――――――; 温度值存放单元TEMP_ZH EQU 24H ;实时温度值存放单元TEMPL EQU 25H ;低温度值存放单元TEMPH EQU 26H ;高温度值存放单元TEMPHC EQU 29H ;存十位数BCD码TEMPLC EQU 2AH ;存个位数BCD码;―――――――――――――;=====DS1302通信引脚定义=====RST BIT p1.5SCLK BIT p1.7IO BIT p1.6;=====定义数据存储地址========DS1302_ADDR DATA 30H ;地址寄存器DS1302_DATA DA TA 31H ;数据寄存器TIME_YEAR DATA 32H ;年寄存器TIME_MONT DATA 33H ;月寄存器TIME_DAY DATA 34H ;天寄存器WEEK_DATA DATA 35H ;星期寄存器HOUR DATA 36H ;小时寄存器MINTUE DA TA 37H ;分钟寄存器SECOND DA TA 38H ;秒钟寄存器;=========显示数据缓冲地址============YEAR_HBUF DATA 40HYEAR_LBUF DATA 41HMONT_HBUF DATA 42HMONT_LBUF DA TA 43HDAY_HBUF DA TA 44HDAY_LBUF DATA 45HWEEK_HBUF DATA 46HWEEK_LBUF DA TA 47HHOUR_HBUF DA TA 48HHOUR_LBUF DA TA 49HMINTUE_HBUF DATA 4AHMINTUE_LBUF DA TA 4BHSECOND_HBUF DATA 4CHSECOND_LBUF DATA 4DH;===============================================X EQU 2FH ;LCD 地址变量;―――――――――――――;LCD控制引脚RS EQU P2.5RW EQU P2.6E EQU P2.7;―――――――――――――DQ EQU p1.0;=============主程序==============MAIN:ACALL SET_LCD ;LCD初始化设置子程序ACALL SET_1302 ;1302初始化TOOP: ACALL RESET_1820 ;调用18B20复位子程序ACALL TEMP_BJ ;显示温度标记"℃"ACALL MEU_OK ;调用显示"OK"信息子程序TOOP2:ACALL RE_TEMP ;调用读取温度数据子程序ACALL SET_DA TA ;调用处理显示温度数据子程序ACALL TEMP_BJ ;显示温度标记子程序LCALL RD_DS1302LCALL DATA_BUFLCALL DISPLAYSJMP TOOP2 ;循环;--------――读取温度数据子程序--------――RE_TEMP:ACALL RESET_1820 ;18B20复位子程序MOV A,#0CCH ;跳过ROM匹配ACALL WRITE_1820 ;写入子程序MOV A,#44H ;发出温度转换命令ACALL WRITE_1820 ;调写入子程序ACALL RESET_1820 ;调复位子程序MOV A,#0CCH ;跳过ROM匹配ACALL WRITE_1820 ;写入子程序MOV A,#0BEH ;发出读温度命令ACALL WRITE_1820 ;写入子程序ACALL READ_1820 ;调用读取子程序RET;--------温度数据处理显示子程序----------SET_DATA:ACALL CONV_TEMP ;处理温度BCD 码子程序ACALL DISP_BCD ;显示区BCD 码温度值刷新子程序ACALL CONV ;LCD显示子程序RET;―――――――――――――;----------处理温度BCD 码子程序----------CONV_TEMP:MOV A,TEMPH ;判温度是否零下ANL A,#80HJZ TC1 ;温度零转TC1处CLR C ;C=0MOV A,TEMPL ;二进制数求补(双字节)CPL A ;取反加1ADD A,#01HMOV TEMPL,AMOV A,TEMPHCPL AADDC A,#00HMOV TEMPH,AJMP TC2;―――――――――――――TC1: MOV TEMPHC,#0AHTC2: MOV A,TEMPHCSW AP A ;高、低位交换MOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;乘0.0625MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分BCD ;―――――――――――――MOV A,TEMPL ;整数部分ANL A,#0F0H ;取出高四位SW AP A ;高、低位交换MOV TEMPL,AMOV A,TEMPHANL A,#0FH ;取出低四位SW AP A ;高、低位交换ORL A,TEMPL ;重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0H ;取出高四位SW AP A ;高、低位交换ORL A,TEMPHC ;TEMPHC LOW = 十位数BCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;取出低四位SW AP A ;高、低位交换ORL A,TEMPLC ;TEMPLC HI = 个位数BCDMOV TEMPLC,AMOV A,R4JZ TC3ANL A,#0FH ;取出低四位SW AP A ;高、低位交换MOV R4,AMOV A,TEMPHC ;TEMPHC HI = 百位数BCDANL A,#0FH ;取出低四位ORL A,R4MOV TEMPHC,ATC3: RET;―――――――――――――HEX2BCD1:MOV B,#064H ;十六进制-> BCDDIV AB ;B= A % 100MOV R4,A ;R4 = 百位数MOV A,#0AHXCH A,BDIV AB ;B = A % BSW AP A ;高、低位交换ORL A,BRET;―――――――――――――; 小数部分码表DOTTAB:DB 00H,00H,01H,01H,02H,03H,03H,04HDB 05H,05H,06H,06H,07H,08H,08H,09H;--------显示区BCD 码温度值刷新子程序--------DISP_BCD:MOV A,TEMPLC ;个位数BCD码送入AANL A,#0FH ;取低位码MOV 70H,A ;小数位MOV A,TEMPLCSW AP A ;高、低位交换ANL A,#0FH ;取结果数的高位MOV 71H,A ;个位MOV A,TEMPHCANL A,#0FH ;取低位码MOV 72H,A ;十位MOV A,TEMPHCSW AP A ;高、低位交换ANL A,#0FH ;取结果数的高位MOV 73H,A ;百位MOV A,TEMPHCANL A,#0F0H ;取低位码CJNE A,#010H,DI0JMP DI2;―――――――――――――DI0: MOV A,TEMPHCANL A,#0FH ;取低位码JNZ DI2 ;十位数是0MOV A,TEMPHCSW AP A ;高、低位交换ANL A,#0FH ;取结果数的高位MOV 73H,#0AH ;符号位不显示MOV 72H,A ;十位数显示符号DI2: RET;==================================================;==========读1302子程序=================RD_DS1302:MOV DS1302_ADDR,#8DH ;读DS1302中的年LCALL READ ;调用读DS1302子程序MOV TIME_YEAR, DS1302_DA TA ;把读出的年数据存入年寄存器中MOV DS1302_ADDR,#8BH ;读DS1302中的星期LCALL READMOV WEEK_DA TA, DS1302_DA TA ;把读出的星期数据存入星期寄存器中MOV DS1302_ADDR,#89H ;读DS1302中的月LCALL READMOV TIME_MONT, DS1302_DATA ;把读出的月数据存入月寄存器中MOV DS1302_ADDR,#87H ;读DS1302中的天LCALL READMOV TIME_DAY, DS1302_DATA ;把读出的天数据存入天寄存器中MOV DS1302_ADDR,#85H ;读DS1302中的小时LCALL READMOV HOUR, DS1302_DATA ;把读出的天数据存入小时寄存器中MOV DS1302_ADDR,#83H ;读DS1302中的分钟LCALL READMOV MINTUE, DS1302_DATA ;把读出的天数据存入分钟寄存器中MOV DS1302_ADDR,#81H ;读DS1302中的秒钟LCALL READMOV SECOND, DS1302_DATA ;把读出的天数据存入秒钟寄存器中RET;===========按键子程序=================;=========数据分离后送显示缓存==================DA TA_BUF:MOV R0,TIME_YEAR ;年数据分离,送显示缓存LCALL DIVIDE ;调用数据分离子程序MOV YEAR_HBUF,R1MOV YEAR_LBUF,R2MOV R0,TIME_MONT ;月数据分离,送显示缓存LCALL DIVIDEMOV MONT_HBUF,R1MOV MONT_LBUF,R2MOV R0,TIME_DAY ;日数据分离,送显示缓存LCALL DIVIDEMOV DAY_HBUF,R1MOV DAY_LBUF,R2MOV R0,WEEK_DATA ;星期数据分离,送显示缓存LCALL DIVIDEMOV WEEK_HBUF,R1MOV WEEK_LBUF,R2MOV R0,HOUR ;小时数据分离,送显示缓存LCALL DIVIDEMOV HOUR_HBUF,R1MOV HOUR_LBUF,R2MOV R0,MINTUE ;分钟数据分离,送显示缓存LCALL DIVIDEMOV MINTUE_HBUF,R1MOV MINTUE_LBUF,R2MOV R0,SECOND ;秒钟数据分离,送显示缓存LCALL DIVIDEMOV SECOND_HBUF,R1MOV SECOND_LBUF,R2RET;=========日历显示子程序==========;===============年显示===============DISPLAY:MOV A,#10000001B ;设定年第1位的显示地址为第1行,第1列LCALL WR_COMM ;调用写指令到液晶子程序MOV A, #32H ;数字2的ASCII码LCALL WR_DATA ;调用写数据到液晶子程序MOV A,#10000010B ;设定年第2位的显示地址为第1行,第2列LCALL WR_COMMMOV A, #30H ;数字0的ASCII码LCALL WR_DATAMOV A,#10000011B ;设定年第3位的显示地址为第1行,第3列LCALL WR_COMMMOV A, YEAR_LBUF ;年的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TAMOV A,#10000100B ;设定年第4位的显示地址为第1行,第4列LCALL WR_COMMMOV A, YEAR_HBUF ;年的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TA; =====================斜线显示======================== MOV A,#10000101B ;设定斜线的显示地址为第1行,第5列LCALL WR_COMMMOV A,#2FH ;斜线的ASCII码LCALL WR_DA TA;================显示月============MOV A,#10000110B ;设定月第1位的显示地址为第1行,第6列LCALL WR_COMMMOV A, MONT_LBUF ;月的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TAMOV A,#10000111B ;设定月第2位的显示地址为第1行,第7列LCALL WR_COMMMOV A, MONT_HBUF ;月的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TA;=======================斜线显示============================ MOV A,#10001000B ;设定斜线的显示地址为第1行,第8列LCALL WR_COMMMOV A,#2FH ;斜线的ASCII码LCALL WR_DA TA;==============================天显示======================= MOV A,#10001001B ;设定天第1位的显示地址为第1行,第9列LCALL WR_COMMMOV A, DAY_LBUF ;天的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TAMOV A,#10001010B ;设定天第2位的显示地址为第1行,第10列LCALL WR_COMMMOV A, DAY_HBUF ;天的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TA;========================星期显示====================== MOV A,#10001111B ;设定星期第2位的显示地址为第1行,第13列LCALL WR_COMMMOV A, WEEK_DATA ;星期的高位缓存数据SUBB A,#1ADD A,#30H ;加30H修正取ASCII码LCALL WR_DATA;=======================小时显示============================ MOV A,#11000000B ;设定小时第1位的显示地址为第2行,第0列LCALL WR_COMMMOV A, HOUR_LBUF ;小时的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TAMOV A,#11000001B ;设定小时第2位的显示地址为第2行,第1列LCALL WR_COMMMOV A, HOUR_HBUF ;小时的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DATA;====================== 冒号的显示========================== MOV A,#11000010B ;设定冒号的显示地址为第2行,第2列LCALL WR_COMMMOV A, #3AH ;冒号的ASCII码LCALL WR_DATA;==================== 分钟显示======================MOV A,#11000011B ;设定分钟第1位的显示地址为第2行,第3列LCALL WR_COMMMOV A, MINTUE_LBUF ;分钟的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TAMOV A,#11000100B ;设定分钟第2位的显示地址为第2行,第4列LCALL WR_COMMMOV A, MINTUE_HBUF ;分钟的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DATA;====================== 冒号的显示=========================== MOV A,#11000101B ;设定冒号的显示地址为第2行,第5列LCALL WR_COMMMOV A, #3AH ;冒号的ASCII码LCALL WR_DATA;===================== 秒钟显示============================= MOV A,#11000110B ;设定秒钟第1位的显示地址为第2行,第6列LCALL WR_COMMMOV A, SECOND_LBUF ;秒钟的低位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DATAMOV A,#11000111B ;设定秒钟第2位的显示地址为第2行,第7列LCALL WR_COMMMOV A, SECOND_HBUF ;秒钟的高位缓存数据ADD A,#30H ;加30H修正取ASCII码LCALL WR_DA TARET;――――――――DS18B20复位初始化子程序――――――――――RESET_1820: ;复位(有具体的时序要求)SETB DQNOPCLR DQ;―――――――――――――;主机发出延时537微秒的复位低脉冲MOV R1,#3DL Y: MOV R0,#107DJNZ R0,$DJNZ R1,DL Y;―――――――――――――;然后拉高数据线SETB DQNOPNOPNOP;―――――――――――――;等待DS18B20回应MOV R0,#25HT2: JNB DQ ,T5DJNZ R0, T2;―――――――――――――;时序要求延时一段时间T5: MOV R0,#117T6: DJNZ R0,T6;――――――――――――――T7: SETB DQRET;=======================================================;========DS1302初始化===========SET_1302:MOV DS1302_ADDR, #8EH ;写DS1302控制指令MOV DS1302_DA TA, #00H ;写数据到DS1302的8E控制寄存器中,允许对其进行写操作LCALL WRITE ;调用写DS1302子程序MOV DS1302_ADDR, #90H ;写DS1302控制指令MOV DS1302_DA TA,#0A6H ;写数据到DS1302的90控制寄存器中,对电池涓流充电,充电电流为1.1mALCALL WRITE ;调用写DS1302子程序RET;=========查询忙碌标志============CHECK_BUSY:PUSH ACCBUSY_LOOP:CLR ESETB RWCLR RSSETB EMOV A, p0JB p0.7,BUSY_LOOPPOP ACCLCALL DELRET;---------------------------------------------------------------------------------------------- ;===========延时程序===================DEL:MOV R6,#5L1:MOV R7,#248DJNZ R7,$DJNZ R6,L1RET;――――――――――写入DS18B20子程序―――――――――――;写入DS18B20(有具体的时序要求)WRITE_1820:MOV R2,#8 ;一共8位数据CLR C ;C=0WR1:CLR DQ ;总线低位,开始写入MOV R3,#6DJNZ R3,$ ;保持16微秒以上RRC A ;把字节DATA分成8个BIT环移给CMOV DQ, C ;写入一个BITMOV R3,#23DJNZ R3,$ ;等待SETB DQ ;重新释放总线NOPDJNZ R2,WR1 ;写入下一个BITSETB DQ ;释放总线RET;――――――――――读出DS18B20子程序―――――――――――;将温度值从DS18B20中读出(有具体的时序要求)READ_1820:MOV R4,#4MOV R1,#TEMPL ;存入25H、26H、27H、28HRE0:MOV R2,#8 ;数据一共有8位RE1:CLR CSETB DQNOPNOPCLR DQ ;读前总线保持为低位NOPNOPNOPSETB DQ ;总线释放;―――――――――――――MOV R3,#9DJNZ R3,$ ;延时18微妙MOV C, DQ ;从总线读到一个BIT ;―――――――――――――MOV R3,#23 ;DJNZ R3,$ ;等待50微秒RRC A ;把读得的位值环移给ADJNZ R2,RE1 ;读下一个BITMOV @R1,AINC R1 ; R1内数据递增DJNZ R4,RE0RET;===========LCD 1602 显示程序===========;初始化设置SET_LCD:CLR ECALL INIT_LCD ;初始化LCDCALL STORE_DA TA ;将自定义字符存入LCD的CGRAMRET;-----------LCD 初始化子程序-----------INIT_LCD:MOV A,#38H ;设置8位、2行、5x7点阵ACALL WR_COMM ; 调用写指令子程序ACALL DELAY1 ;调用延时子程序MOV A,#0CH ;开显示,光标不闪烁ACALL WR_COMM ;调用写指令子程序;ACALL DELAY1 ;调用延时子程序MOV A,#01H ;清除LCD 显示屏ACALL WR_COMM ;调用写指令子程序;ACALL DELAY1 ;调用延时子程序RET;----------显示温度标记子程序-----------TEMP_BJ:MOV A, #0CEH ;设定第二行起始地址ACALL WR_COMM ;调用写指令子程序MOV DPTR,#BJ ;存代码表MOV R1 ,#0 ;使指针指到表中第一个码MOV R0 ,#2 ;取码次数Tp0:MOV A,R1 ;A为0MOVC A,@A+DPTR ;取码ACALL WR_DATA ;调用写数据子程序INC R1 ;R1值加1DJNZ R0,Tp0 ;判断是否将代码读取完?RET;―――――――――――――BJ: ;代码表DB 00H,"C";-----------自定义字符子程序-----------;将自定义字符写入LCD1602的CGRAM中STORE_DATA:MOV A,#40H ;指定CG RAM起始地址ACALL WR_COMM ;将指令写入LCDMOV R2,#08H ;图形数据长度8个字节MOV DPTR,#TAB ;存代码表MOV R3,#00H ;使指针指到表中第一个码S_D: MOV A,R3 ;A为0MOVC A,@A+DPTR ;读取表代码ACALL WR_DA TA ;调用写入数据指令INC R3 ;R3值加1DJNZ R2, S_D ;判断是否将代码读取完?RET ;;―――――――――――――TAB: ;代码表DB 0CH,12H,12H,0CHDB 00H,00H,00H,00H;-----------显示"OK"信息子程序---------MEU_OK:MOV DPTR,#M_OK1 ;指针指到显示消息MOV A,#1 ;显示在第一行ACALL LCD_PRINT ;LCD显示MOV DPTR,#M_OK2 ;指针指到显示消息MOV A,#2 ;显示在第一行ACALL LCD_PRINT ;LCD显示RET;――――――――――――――M_OK1:DB " - - WK: " ,0M_OK2:DB " - - ",0;------―――――菜单显示子程序―――――――-----;在LCD的第一行或第二行显示字符LCD_PRINT:CJNE A,#1,LINE2 ;判断是否为第一行LINE1:ACALL CLR_LINE ;清除该行字符数据MOV A,#80H ;设置LCD 的第一行地址ACALL WR_COMM ;写入命令JMP FILLLINE2:ACALL CLR_LINE ;清除该行字符数据MOV A,#0C0H ;设置LCD 的第二行地址ACALL WR_COMMFILL:CLR A ;填入字符MOVC A,@A+DPTR ;由消息区取出字符CJNE A,#0,LC1 ;判断是否为结束码RETLC1:ACALL WR_DATA ;写入数据INC DPTR ;指针加1JMP FILL ;继续填入字符RET;---------―LCD显示子程序----------CONV:MOV A,73H ;加载百位数据MOV X,#9 ;设置位置CJNE A,#1,CO1JMP CO2CO1:MOV A,#" "MOV B,XACALL LCDP2JMP CO3CO2:ACALL SHOW_LINE2 ;显示数据CO3: INC X ;位加1MOV A,72H ;十位ACALL SHOW_LINE2 ;显示数据INC X ;位加1MOV A, 71H ;个位ACALL SHOW_LINE2 ;显示数据INC X ;位加1MOV A,#'.'MOV B,XACALL LCDP2 ;显示字符MOV A,70H ;加载小数点位INC X ;设置位置ACALL SHOW_LINE2 ;显示数据RET;-----――显示第二行-----―――;在LCD 的第二行显示数字SHOW_LINE2:ADD A,#30HMOV B,XACALL LCDP2RETLCDP2: ;在LCD的第二行显示字符PUSH ACC ;放入堆栈MOV A,B ;设置显示地址ADD A,#0C0H ;设置LCD的第二行地址ACALL WR_COMM ;写入命令POP ACC ;由堆栈取出AACALL WR_DATA ;写入数据RET;-----――――――写指令子程序――――――――――--WR_COMM:MOV p0,A ;写入指令CLR RS ;RS=0,选择指令寄存器CLR RW ;RW=0,选择写模式SETB E ;E=1,允许读/写LCMACALL DELAY1 ;延时5MSCLR E ;E=0,禁止读/写LCMRET;---------―――写数据子程序------------WR_DATA:MOV p0,A ;写入数据SETB RS ;RS=1,选择数据寄存器CLR RW ;RW=0,选择写模式SETB E ;E=1,允许读/写LCMACALL DE ;延时0.5MSCLR E ;E=0,禁止读/写LCMACALL DE ;延时0.5MSRET;----------清除LCD 的字符-------------CLR_LINE:MOV R0,#24 ;设置计数值CL1: MOV A,#' ' ;载入空格符至LCDACALL WR_DATA ;输出字符至LCDDJNZ R0,CL1 ;判断RET;--------------CLR_LINE1: ;清除LCD的第一行字符MOV A,#80H ;设置LCD 的第一行地址ACALL WR_COMM ;调用写指令子程序MOV R0,#24 ;设置计数值C1: MOV A,#' ' ;载入空格符至LCDACALL WR_DA TA ;输出字符至LCDDJNZ R0,C1 ;计数结束RET;========================================================= ;***********写1302程序*************WRITE:CLR SCLKNOPSETB RSTNOPMOV A,DS1302_ADDRMOV R4,#8WRITE1:RRC A ;送地址给1302NOPNOPCLR SCLKNOPNOPNOPMOV IO,CSETB SCLK ;送入地址在时钟上升沿有效NOPNOPNOPNOPDJNZ R4,WRITE1CLR SCLKNOPMOV A,DS1302_DA TAMOV R4,#8WRITE2:RRC ANOP ;送数据给1302,时钟上升沿,数据输入CLR SCLKNOPNOPMOV IO,CNOPNOPNOPSETB SCLKNOPNOPDJNZ R4,WRITE2CLR RSTCLR ARET;**********读1302程序************READ:CLR SCLKNOPNOPSETB RSTNOPMOV A,DS1302_ADDRMOV R4,#8READ1:RRC ANOPMOV IO,CNOPNOPNOPSETB SCLK ;送入地址在时钟上升沿有效NOPNOPNOPCLR SCLKNOPNOPDJNZ R4,READ1 ;判断8位数据是否传送完?MOV R4,#8READ2:CLR SCLKNOPNOPNOPMOV C,IONOPNOPNOPNOPNOP ;从ds1302中读取数据,时钟下降沿有效RRC ANOPNOPNOPNOPSETB SCLKNOPDJNZ R4,READ2 ;判断8位数据是否传送完?MOV DS1302_DATA,ACLR RSTRET;==========分离数据子程序=========DIVIDE:MOV A,R0ANL A,#0FH ;屏蔽掉低4位,留下高4位MOV R1,AMOV A,R0SW AP A ;A中数据高4位与低4位互换ANL A,#0FH ;实际上是屏蔽掉了高4位,留下低4位MOV R2,ARET;========延时2秒子程序=============DELAY2:MOV R5,#20D3:MOV R6,#200D2:MOV R7,#250DJNZ R7,$DJNZ R6,D2DJNZ R5,D3RET;-------------鸣响子程序------------DEX1: MOV R7,#180DE2: NOPDJNZ R7,DE2RET;-------------延时子程序-------------DELAY: ;延时时间为:R5×10MSDL1: MOV R7,#100DJNZ R7,$DJNZ R6,DL1DJNZ R5,DELAYRET;―――――――――――――DELAY1: ;延时时间为5MSMOV R6,#25DL2: MOV R7,#100DJNZ R7,$DJNZ R6,DL2RET;―――――――――――――DE:MOV R7,#250 ;延时时间为0.5MSDJNZ R7,$RET;-----------――END。
#include<reg52.h>#define wri_sec 0x80#define wri_min 0x82#define wri_hour 0x84#define wri_day 0x86#define wri_mon 0x88#define wri_week 0x8a#define wri_year 0x8c#define re_sec 0x81#define re_min 0x83#define re_hour 0x85#define re_day 0x87#define re_mon 0x89#define re_week 0x8b#define re_year 0x8d#define wri_pro 0x8e#define uchar unsigned char#define uint unsigned intsbit SCLK=P3^5;sbit DIO=P3^6;sbit CE=P3^7;sbit lcden=P1^0;sbit lcdrs=P1^2;sbit lcdrw=P1^1;uchar weeks[7][3]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; static uchar datatime[7]={0};void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write1302(uchar addr,dat){uchar i,temp;CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){SCLK=0;temp=addr;DIO=(bit)(temp&0x01);addr>>=1;SCLK=1;}for(i=0;i<8;i++){SCLK=0;temp=dat;DIO=(bit)(temp&0x01);dat>>=1;SCLK=1;}CE=0;}uchar read1302(uchar addr){uchar i,temp, dat1,dat2;dat1=0;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--){SCLK=0;temp=addr;DIO=(bit)(temp&0x01);addr>>=1;SCLK=1;}SCLK=0;for(i=8;i>0;i--){DIO=1;dat1>>=1;if(DIO) dat1|=0x80;SCLK=1;delay(5);SCLK=0;}dat2=dat1/16;dat1=dat1%16;dat1=dat2*10+dat1;return(dat1);}void init1302() //初始化{write1302(wri_pro,0x00); //允许写write1302(wri_sec,0x12);// write1302(wri_min,0x23);// write1302(wri_hour,0x16);// write1302(wri_day,0x17);// write1302(wri_mon,0x11);// write1302(wri_year,0x10);// write1302(wri_week,0x03);write1302(wri_pro,0x80); //禁止写}void write_com(uchar com) //lcd写命令{lcdrw=0;lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date) //lcd{lcdrw=0;lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init_lcd() //lcd初始化{uint dat1,dat2;uint i;lcden=0;write_com(0x38);write_com(0x0f);write_com(0x06);write_com(0x01);write_com(0x81);write_data('2');delay(20);write_data('0');delay(20);write1302(wri_pro,0x00);datatime[6]=read1302(re_year);dat2=datatime[6]/10;dat1=datatime[6]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(45);delay(20);datatime[5]=read1302(re_mon);dat2=datatime[5]/10;dat1=datatime[5]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(45);delay(20);datatime[4]=read1302(re_day);dat2=datatime[4]/10;dat1=datatime[4]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(32);delay(20);datatime[3]=read1302(re_week);for (i=0;i<3;i++){write_data(weeks[datatime[3]-1][i]);delay(20);}write_com(0x80+0x43);datatime[2]=read1302(re_hour);dat2=datatime[2]/10;dat1=datatime[2]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(58);delay(20);datatime[1]=read1302(re_min);dat2=datatime[1]/10;dat1=datatime[1]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(39);delay(20);datatime[0]=read1302(re_sec);dat2=datatime[0]/10;dat1=datatime[0]%10;write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);write_data(34);delay(20);write1302(wri_pro,0x80);}void refresh() //更新时间{uchar sec,min,hou,day,mon,yea,wee,dat1,dat2;uint i;write1302(wri_pro,0x00);sec=read1302(re_sec);if(sec!=datatime[0]){datatime[0]=sec;dat2=datatime[0]/10;dat1=datatime[0]%10;write_com(0x80+0x49);delay(50);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);if(!sec){min=read1302(re_min);datatime[1]=min;dat2=datatime[1]/10;dat1=datatime[1]%10;write_com(0x80+0x46);delay(5);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);if(!min){hou=read1302(re_hour);datatime[2]=hou;dat2=datatime[2]/10;dat1=datatime[2]%10;write_com(0x80+0x43);delay(5);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);if(!hou){wee=read1302(re_week);datatime[3]=wee;write_com(0x80+0x0c);delay(5);for (i=0;i<3;i++){write_data(weeks[datatime[3]-1][i]);delay(20);}day=read1302(re_day);datatime[4]=day;dat2=datatime[4]/10;dat1=datatime[4]%10;write_com(0x80+0x09);delay(5);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);if(day==1){mon=read1302(re_mon);datatime[5]=mon;dat2=datatime[5]/10;dat1=datatime[5]%10;write_com(0x80+0x06);delay(5);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);if(mon==1){yea=read1302(re_year);datatime[6]=yea;dat2=datatime[6]/10;dat1=datatime[6]%10;write_com(0x80+0x03);delay(5);write_data(48+dat2);delay(20);write_data(48+dat1);delay(20);}}}}}}write1302(wri_pro,0x80);}void readkey() //查键{uchar key,n,dat1,dat2;uint i;key=P2;delay(10);if(key==0xfe){key=P2;delay(20);n=1;while(1){if(n==1){n=0;write_com(0x83); //修改年write1302(wri_pro,0x00);dat1=read1302(re_year);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd:if(dat2==9) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x83);break;case 0xfb: if(dat2==0) dat2=9;else dat2--;write_data(48+dat2);delay(20);write_com(0x83);break;default: break;}key=P2;delay(10);}delay(200);write_com(0x84);key=P2;delay(20);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x84);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x84);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_year,dat1);delay(200);write_com(0x86); //修改月dat1=read1302(re_mon);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat2==1) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x86);break;case 0xfb: if(dat2==0) dat2=1;else dat2--;write_data(48+dat2);delay(20);write_com(0x86);break;default: break;}key=P2;delay(10);}write_com(0x87);delay(200);key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x87);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x87);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_mon,dat1);delay(200);write_com(0x89); //修改日dat1=read1302(re_day);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat2==3) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x89);break;case 0xfb: if(dat2==0) dat2=3;else dat2--;write_data(48+dat2);delay(20);write_com(0x89);break;default: break;}key=P2;delay(10);}write_com(0x8a);delay(200);key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x8a);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x8a);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_day,dat1);delay(200);write_com(0x8c); //修改星期dat1=read1302(re_week);key=P2;delay(20);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==7) dat1=1;else dat1++;for(i=0;i<3;i++){write_data(weeks[dat1-1][i]);delay(20);}write_com(0x8c);break;case 0xfb: if(dat1==1) dat1=7;else dat1--;for(i=0;i<3;i++){write_data(weeks[dat1-1][i]);delay(20);}write_com(0x8c);break;}key=P2;delay(10);}write1302(wri_week,dat1);delay(200);write_com(0x80+0x43); //修改时dat1=read1302(re_hour);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat2==2) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x80+0x43);break;case 0xfb: if(dat2==0) dat2=2;else dat2--;write_data(48+dat2);delay(20);write_com(0x80+0x43);break;default: break;}key=P2;delay(10);}write_com(0x80+0x44);delay(200);key=P2;delay(20);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x80+0x44);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x80+0x44);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_hour,dat1);delay(250);write_com(0x80+0x46); //修改分dat1=read1302(re_min);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat2==5) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x80+0x46);break;case 0xfb: if(dat2==0) dat2=5;else dat2--;write_data(48+dat2);delay(20);write_com(0x80+0x46);break;default: break;}key=P2;delay(10);}write_com(0x80+0x47);delay(200);key=P2;delay(20);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x80+0x47);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x80+0x47);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_min,dat1);delay(250);write_com(0x80+0x49); //修改秒dat1=read1302(re_sec);dat2=dat1/10;dat1=dat1%10;key=P2;delay(10);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat2==5) dat2=0;else dat2++;write_data(48+dat2);delay(20);write_com(0x80+0x49);break;case 0xfb: if(dat2==0) dat2=5;else dat2--;write_data(48+dat2);delay(20);write_com(0x80+0x49);break;default: break;}key=P2;delay(10);}write_com(0x80+0x4a);delay(200);key=P2;delay(20);while(key!=0xf7){delay(200);switch(key){case 0xfd: if(dat1==9) dat1=0;else dat1++;write_data(48+dat1);delay(20);write_com(0x80+0x4a);break;case 0xfb: if(dat1==0) dat1=9;else dat1--;write_data(48+dat1);delay(20);write_com(0x80+0x4a);break;default: break;}key=P2;delay(10);}dat1=(dat2<<4)|dat1;write1302(wri_sec,dat1);write_com(0x80+0x4d);write1302(wri_pro,0x80);}break;}}}void main(){init1302();init_lcd();while(1){refresh();readkey();write_com(0x80+0x50);}}。
#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="ziye334"; uchar code table1[]="0123456789"; uchar code table2[]="DAY-";sbit rs=P2^5;sbit rw=P2^6;sbit en=P2^7;sbit rst=P1^7;sbit io=P3^5;sbit clk=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;uchar num;uchar t_sec,sec1,sec2;uchar t_min,min1,min2;uchar t_hr,hr1,hr2;uchar t_mon,mon1,mon2; uchar t_date,date1,date2; uchar t_year,year1,year2; uchar t_day,day1,flag;void input_1byte(uchar TD) {uchar i;ACC=TD;for(i=8;i>0;i--){io=ACC0;clk=1;clk=0;ACC=ACC>>1;}}uchar output_1byte(void) {uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=io;clk=1;clk=0;}return(ACC);}void write_ds1302(uchar add,uchar dat) {rst=0;clk=0;rst=1;input_1byte(add);input_1byte(dat);clk=1;rst=0;}uchar read_ds1302(uchar add){uchar inf;rst=0;clk=0;input_1byte(add);inf=output_1byte();clk=1;rst=0;return(inf);}void delay(uchar z) //延时{uint x,y;for(x=110;x>0;x--)for(y=z;z>0;z--);}void write_com(uchar com) //写指令{rs=0;rw=0;en=0;P0=com;delay(5);en=1;delay(5);}void write_date(uchar date) //写数据{rs=1;rw=0;en=0;P0=date;delay(5);en=1;delay(5);en=0;}void init_lcd(){en=0;write_com(0x38); //显示write_com(0x0c); //光标不显示write_com(0x06); //指针加1,整屏不移动write_com(0x01); //清屏write_com(0x80);}void init_1302(){write_ds1302(0x8e,0x00);//关闭写保护write_ds1302(0x90,0xaa); //定义充电write_ds1302(0x80,0x30); //秒write_ds1302(0x82,0x59);//分write_ds1302(0x84,0x23);//时write_ds1302(0x86,0x31);//日write_ds1302(0x88,0x12);//月write_ds1302(0x8a,0x04);//星期write_ds1302(0x8c,0x11);//年write_ds1302(0x8e,0x80);//打开写保护}void display(){t_sec=read_ds1302(0x81);sec1=t_sec&0x0f;sec2=(t_sec>>4);t_min=read_ds1302(0x83);min1=t_min&0x0f;min2=(t_min>>4);t_hr=read_ds1302(0x85); hr1=t_hr&0x0f;hr2=(t_hr>>4);t_date=read_ds1302(0x87); date1=t_date&0x0f;date2=(t_date>>4);t_mon=read_ds1302(0x89); mon1=t_mon&0x0f;mon2=(t_mon>>4);t_day=read_ds1302(0x8b); day1=t_day&0x0f;t_year=read_ds1302(0x8d); year1=t_year&0x0f;year2=(t_year>>4);write_com(0x80+0x4e);write_date(table1[sec2]); write_com(0x80+0x4f); write_date(table1[sec1]); write_com(0x80+0x4d); write_date(':');write_com(0x80+0x4c); write_date(table1[min1]); write_com(0x80+0x4b); write_date(table1[min2]); write_com(0x80+0x4a); write_date(':');write_com(0x80+0x49); write_date(table1[hr1]); write_com(0x80+0x48); write_date(table1[hr2]);write_com(0x80+0x0f); write_date(table1[date1]); write_com(0x80+0x0e); write_date(table1[date2]);write_com(0x80+0x0d);write_date('/');write_com(0x80+0x0c);write_date(table1[mon1]);write_com(0x80+0x0b);write_date(table1[mon2]);write_com(0x80+0x0a);write_date('/');write_com(0x80+0x09);write_date(table1[year1]);write_com(0x80+0x08);write_date(table1[year2]);write_com(0x80+0x40+5);write_date(table1[day1]); }void main(){init_lcd();delay(5);init_1302();delay(5);for(num=0;num<7;num++) {write_date(table[num]);delay(10);}write_com(0x80+0x41);for(num=0;num<4;num++) {write_date(table2[num]);delay(10);}while(1){if(flag==0){display();}}}。
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code s[]={"0123456789"};uchar code s1[]={"Data: 20 - - "};uchar code s2[]={"Time: : : "};/* DS1302的设置程序 */sbit SCLK=P1^0;sbit DATA=P1^1;sbit RST=P1^2;void delayus(uchar n) //延时函数{uchar i;for(i=0;i<n;i++);}void Write1302data(uchar x) //向DS1302写一个字节{uchar i;SCLK=0;delayus(2);for(i=0;i<8;i++){DATA=x&0x01;delayus(2);SCLK=1;delayus(2);SCLK=0;x>>=1;}}void Write1302(uchar cmd,uchar dat) //向DS1302写数据{RST=0;SCLK=0;RST=1;delayus(2);Write1302data(cmd);Write1302data(dat);delayus(2);RST=0;}uchar Read1302data(void) //向DS1302读一个字节{uchar i,x;delayus(2);for(i=0;i<8;i++){x>>=1;if(DATA==1)x|=0x80;SCLK=1;delayus(2);SCLK=0;delayus(2);}return x;}uchar Read1302(uchar cmd) //向DS1302读数据{uchar x;RST=0;SCLK=0;RST=1;delayus(2);Write1302data(cmd);x=Read1302data();SCLK=1;RST=0;return x;}void DS1302int(void) //DS1302初始化{uchar y;y=Read1302(0x81);if(y&0x80){Write1302(0x8E,0x00);Write1302(0x80,0x59);Write1302(0x82,0x22);Write1302(0x84,0x20);Write1302(0x86,0x21);Write1302(0x88,0x07);Write1302(0x8c,0x12);Write1302(0x90,0xa5);Write1302(0x8E,0x80);}}/* 1602液晶的设置的程序*/sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit BF=P0^7;void delayms(uchar n) //延时函数{uchar i;while(n--)for(i=0;i<115;i++);}bit busy(void) //检测忙信号{bit x;RS=0;RW=1;E=1;_nop_();_nop_();_nop_();x=BF;E=0;return x;}void Writelcddata(uchar x) //向1602写一个数据{while(busy()==1);RS=1;RW=0;E=0;P0=x;_nop_();_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();_nop_();E=0;}void Writelcdcmd(uchar x) //向1602写一个命令{while(busy()==1);RS=0;RW=0;E=0;P0=x;_nop_();_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();_nop_();E=0;}void Writelcdaddr(uchar x) //向1602写要显示的数据的地址{Writelcdcmd(x|0x80);}void lcdint() //1602初始化{delayms(15);Writelcdcmd(0x38);delayms(5);Writelcdcmd(0x38);delayms(5);Writelcdcmd(0x38); //三次写模式设置:16x2显示,5x7点阵,8位数据接口delayms(5);Writelcdcmd(0x0c); //显示开,无光标,光标不闪烁delayms(5);Writelcdcmd(0x06); //输入数据时光标右移一位,字符不移delayms(5);Writelcdcmd(0x01); //清屏设置delayms(5);}/* 1602+1302显示程序*/void displaysecond(uchar x) //显示秒{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x4c);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void displayminute(uchar x) //显示分{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x49);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void displayhour(uchar x) //显示小时{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x46);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void displayday(uchar x) //显示日{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x0e);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void displaymonth(uchar x) //显示月{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x0b);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void displayyear(uchar x) //显示年{uchar i,j;i=x/10;j=x%10;Writelcdaddr(0x08);Writelcddata(s[i]);Writelcddata(s[j]);delayms(50);}void main() //主函数{uchar x,i,j;lcdint();DS1302int();delayms(50);Writelcdaddr(0x00);i=0;while(s1[i]!='\0'){Writelcddata(s1[i]);i++;}Writelcdaddr(0x40);i=0;while(s2[i]!='\0'){Writelcddata(s2[i]);i++;}delayms(50);while(1){x=Read1302(0x81);displaysecond(((x&0x70)>>4)*10+(x&0x0f));delayms(50);x=Read1302(0x83);displayminute(((x&0x70)>>4)*10+(x&0x0f));delayms(50);x=Read1302(0x85);displayhour(((x&0x70)>>4)*10+(x&0x0f));delayms(50);x=Read1302(0x87);displayday(((x&0x70)>>4)*10+(x&0x0f));delayms(50);x=Read1302(0x89);displaymonth((((x&0x70)>>4)*10+(x&0x0f)));delayms(50);x=Read1302(0x8d);displayyear(((x&0xf0)>>4)*10+(x&0x0f));delayms(50);}}。
DS1302+DS18B20+lcd1602完整程序#include <REG51.H>#include <intrins.h>//#include "LCD1602.h"//#include "DS1302.h"#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //实时时钟时钟线引脚sbit DS1302_IO = P1^6; //实时时钟数据线引脚sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3;sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P2^0; //模式切换键sbit Up = P2^1; //加法按钮sbit Down = P2^2; //减法按钮sbit out = P2^3; //立刻跳出调整模式按钮sbit DQ = P1^0; //温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //温度值uchar TempBuffer[5],week_value[2];void show_time(); //液晶显示程序/***********1602液晶显示部分子程序****************///Port Definitions**********************************************************sbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口//内部等待函数**************************************************************************unsigned char LCD_Wait(void){LcdRs=0;LcdRw=1; _nop_();LcdEn=1; _nop_();LcdEn=0;return DBPort;}//向LCD写入命令或数据************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){LcdEn=0;LcdRs=style;LcdRw=0; _nop_();DBPort=input; _nop_();//注意顺序LcdEn=1; _nop_();//注意顺序LcdEn=0; _nop_();LCD_Wait();}//设置显示模式************************************************************ #define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关#define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标#define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动void LCD_SetDisplay(unsigned char DisplayMode){LCD_Write(LCD_COMMAND, 0x08|DisplayMode);}//设置输入模式************************************************************ #define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default#define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //defaultvoid LCD_SetInput(unsigned char InputMode){LCD_Write(LCD_COMMAND, 0x04|InputMode);}//初始化LCD************************************************************ void LCD_Initial(){LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}//液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}//将字符输出到液晶显示void Print(unsigned char *str){while(*str!='\0'){LCD_Write(LCD_DATA,*str);str++;}}/***********DS1302时钟部分子程序******************/ typedef struct __SYSTEMTIME__{unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString[11];unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME CurrentTime;#define AM(X) X#define PM(X) (X+12) // 转成24小时制#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 0x8Cvoid DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){unsigned char i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) {unsigned char i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;}return(ACC);}void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0;}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);}void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组{unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((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_MONTH);Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);}void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为2007/07/22{Time->DateString[0] = '2';Time->DateString[1] = '0';Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0'; }else{Time->DateString[0] = ' ';Time->DateString[1] = ' ';Time->DateString[2] = ' ';Time->DateString[3] = ' ';}Time->DateString[4] = '/';if(hide_month<2){Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0'; }else{Time->DateString[5] = ' ';Time->DateString[6] = ' ';}Time->DateString[7] = '/';if(hide_day<2){Time->DateString[8] = Time->Day/10 + '0';Time->DateString[9] = Time->Day%10 + '0';}else{Time->DateString[8] = ' ';Time->DateString[9] = ' ';}if(hide_week<2){week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示}else{week_value[0] = ' ';}week_value[1] = '\0';Time->DateString[10] = '\0'; //字符串末尾加'\0' ,判断结束字符}void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组TimeString[];{ if(hide_hour<2){Time->TimeString[0] = Time->Hour/10 + '0';Time->TimeString[1] = Time->Hour%10 + '0';}else{Time->TimeString[0] = ' ';Time->TimeString[1] = ' ';}Time->TimeString[2] = ':';if(hide_min<2){Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; }else{Time->TimeString[3] = ' ';Time->TimeString[4] = ' ';}Time->TimeString[5] = ':';if(hide_sec<2){Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; }else{Time->TimeString[6] = ' ';Time->TimeString[7] = ' ';}Time->DateString[8] = '\0';}void Initial_DS1302(void) //时钟芯片初始化{unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) //判断时钟芯片是否关闭{Write1302(0x8e,0x00); //写入允许Write1302(0x8c,0x07); //以下写入初始化时间日期:07/07/25.星期: 3. 时间: 23:59:55 Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}}/***********ds18b20子程序*************************/ /***********ds18b20延迟子函数(晶振12MHz )*******/void delay_18B20(unsigned int i){while(i--);}/**********ds18b20初始化函数**********************/void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(80); //精确延时大于480usDQ = 1; //拉高总线delay_18B20(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}/***********ds18b20读一个字节**************/unsigned char ReadOneChar(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/*************ds18b20写一个字节****************/void WriteOneChar(uchar dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;}}/**************读取ds18b20当前温度************/void ReadTemp(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位temp_value=b<<4;temp_value+=(a&0xf0)>>4;}void temp_to_str() //温度数据转换成液晶字符显示{TempBuffer[0]=temp_value/10+'0'; //十位TempBuffer[1]=temp_value%10+'0'; //个位TempBuffer[2]=0xdf; //温度符号TempBuffer[3]='C';TempBuffer[4]='\0';}void Delay1ms(unsigned int count){unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}/*延时子程序*/void mdelay(uint delay){ uint i;for(;delay>0;delay--){for(i=0;i<62;i++) //1ms延时.{;}}}void outkey() //跳出调整模式,返回默认显示{ uchar Second;if(out==0||wireless_1==1){ mdelay(8);count=0;hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0 ;Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;while(out==0);while(wireless_1==1);}}////////////////////////////////////////////////////////////////////////////////////////////////////// //////void Upkey()//升序按键{Up=1;if(Up==0||wireless_2==1){mdelay(8);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=temp+1; //秒数加1up_flag=1; //数据调整后更新标志if((temp&0x7f)>0x59) //超过59秒,清零temp=0;break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=temp+1; //分数加1up_flag=1;if(temp>0x59) //超过59分,清零temp=0;break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=temp+1; //小时数加1up_flag=1;if(temp>0x23) //超过23小时,清零temp=0;break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数temp=temp+1; //星期数加1up_flag=1;if(temp>0x7)temp=1;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=temp+1; //日数加1up_flag=1;if(temp>0x31)temp=1;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=temp+1; //月数加1up_flag=1;if(temp>0x12)temp=1;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=temp+1; //年数加1up_flag=1;if(temp>0x85)temp=0;break;default:break;}while(Up==0);while(wireless_2==1);}}////////////////////////////////////////////////////////////////////////////////////////////////////// //////void Downkey()//降序按键{Down=1;if(Down==0||wireless_3==1){mdelay(8);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=temp-1; //秒数减1down_flag=1; //数据调整后更新标志if(temp==0x7f) //小于0秒,返回59秒temp=0x59;break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=temp-1; //分数减1down_flag=1;if(temp==-1)temp=0x59; //小于0秒,返回59秒break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=temp-1; //小时数减1down_flag=1;if(temp==-1)temp=0x23;break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数temp=temp-1; //星期数减1down_flag=1;if(temp==0)temp=0x7;;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=temp-1; //日数减1down_flag=1;if(temp==0)temp=31;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=temp-1; //月数减1down_flag=1;if(temp==0)temp=12;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=temp-1; //年数减1down_flag=1;if(temp==-1)temp=0x85;break;default:break;}while(Down==0);while(wireless_3==1);}}void Setkey()//模式选择按键{Set=1;if(Set==0||wireless_4==1){mdelay(8);count=count+1; //Setkey按一次,count就加1done=1; //进入调整模式while(Set==0);while(wireless_4==1);}}void keydone()//按键功能执行{ uchar Second;if(flag==0) //关闭时钟,停止计时{ Write1302(0x8e,0x00); //写入允许temp=Read1302(0x80);Write1302(0x80,temp|0x80);Write1302(0x8e,0x80); //禁止写入flag=1;}Setkey(); //扫描模式切换按键switch(count){case 1:do //count=1,调整秒outkey(); //扫描跳出按钮Upkey(); //扫描加按钮Downkey(); //扫描减按钮if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据{Write1302(0x8e,0x00); //写入允许Write1302(0x80,temp|0x80); //写入新的秒数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_sec++; //位闪计数if(hide_sec>3)hide_sec=0;show_time(); //液晶显示数据}while(count==2);break;case 2:do //count=2,调整分hide_sec=0;outkey();Upkey();Downkey();if(temp>0x60)temp=0;if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x82,temp); //写入新的分数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_min++;if(hide_min>3)hide_min=0;show_time();case 3:do //count=3,调整小时{hide_min=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x84,temp); //写入新的小时数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_hour++;if(hide_hour>3)hide_hour=0;show_time();case 4:do //count=4,调整星期{hide_hour=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8a,temp); //写入新的星期数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_week++;if(hide_week>3)hide_week=0;show_time();case 5:do //count=5,调整日{hide_week=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x86,temp); //写入新的日数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_day++;if(hide_day>3)hide_day=0;show_time();case 6:do //count=6,调整月{hide_day=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x88,temp); //写入新的月数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_month++;if(hide_month>3)hide_month=0;show_time();case 7:do //count=7,调整年{hide_month=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8c,temp); //写入新的年数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_year++;if(hide_year>3)hide_year=0;show_time();case 8: count=0;hide_year=0; //count8, 跳出调整模式,返回默认显示状态Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;break; //count=7,开启中断,标志位置0并退出default:break;}}void show_time() //液晶显示程序{DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据TimeToStr(&CurrentTime); //时间数据转换液晶字符DateToStr(&CurrentTime); //日期数据转换液晶字符ReadTemp(); //开启温度采集程序temp_to_str(); //温度数据转换成液晶字符GotoXY(12,1); //液晶字符显示位置Print(TempBuffer); //显示温度GotoXY(0,1);Print(CurrentTime.TimeString); //显示时间GotoXY(0,0);Print(CurrentTime.DateString); //显示日期GotoXY(15,0);Print(week_value); //显示星期GotoXY(11,0);Print("Week"); //在液晶上显示字母weekDelay1ms(400); //扫描延时}main(){flag=1; //时钟停止标志LCD_Initial(); //液晶初始化Init_DS18B20( ) ; //DS18B20初始化Initial_DS1302(); //时钟芯片初始化up_flag=0;down_flag=0;done=0; //进入默认液晶显示wireless_1=0;wireless_2=0;wireless_3=0;wireless_4=0;while(1){while(done==1)keydone(); //进入调整模式while(done==0){show_time(); //液晶显示数据flag=0;Setkey(); //扫描各功能键}}}。
DS1302编程操作1、DS1302有关日历、时间的寄存器这张表是DS1302内部的7个与时间、日期有关的寄存器图和一个写保护寄存器,我们要做的就是将初始设置的时间、日期数据写入这几个寄存器,然后再不断地读取这几个寄存器来获取实时时间和日期。
这几个寄存器的说明如下:1、秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当初始上电时该位置为1,时钟振荡器停止,DS1302处于低功耗状态;只有将秒寄存器的该位置改写为0时,时钟才能开始运行。
2、小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。
当为高时,选择12小时模式。
在12小时模式时,位5是,当为1时,表示PM。
在24小时模式时,位5是第二个10小时位3、控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7位均置为0。
在对任何的时钟和RAM的写操作之前,WP位必须为0。
当WP位为1时,写保护位防止对任一寄存器的写操作。
也就是说在电路上电的初始态WP是1,这时是不能改写上面任何一个时间寄存器的,只有首先将WP改写为0,才能进行其它寄存器的写操作。
2、我们现在就来编程看一下,如何对DS1302进行操作把时钟信息显示在1602LCD上。
1 首先要通过8EH将写保护去掉,将日期,时间的初值写入各个寄存器。
2 然后就可以对80H、82H、84H、86H、88H、8AH、8CH进行初值的写入。
同时也通过秒寄存器将位7的CH值改成0,这样DS1302就开始走时运了。
3 将写保护寄存器再写为80H,防止误改写寄存器的值。
4 不断读取80H-8CH的值,将它们格式化后显示到1602LCD液晶上void Init_DS1302(void){WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((16/10)<<4|(16%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((8/10)<<4|(8%10))); //根据写小时寄存器命令字,写入小时的初始值}3、DS1302有关RAM的地址DS1302中附加31字节静态RAM的地址4、DS1302的工作模式寄存器所谓突发模式是指一次传送多个字节的时钟信号和RAM数据。
/**************************************************************** ** DS1302时钟******************************************************************/ #include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//--定义矩阵键盘使用的IO口--//#define GPIO_DIG P0#define GPIO_KEY P1//---定义lcd1602使用的IO口---//#define DB P0//--定义全局变量--//uchar error[]="Error!!!" ;//存放字符串“Error!!!”char KeyValue=-1;//用来存放读取到的键值uchar flag=0;//用来检测是否更改过时间uchar tt0=0;//中断里面的参数uchar beeflag=0;//看看有没有开闹钟//---定义蜂鸣器使用的IO口---//sbit bee=P2^3;//定义LCD1602使用的IO口//sbit LCDE=P2^7;sbit RS=P2^6;sbit RW=P2^5;//---定义ds1302使用的IO口---//sbit DSIO=P3^4; //数据传输口sbit RST=P3^5; //进行传输时,RST必须置高sbit SCLK=P3^6; //上沿读数据,下沿写数据//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---键盘写入地址-------//uchar kyewrite[] = {0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8d,0xc0,0xc1,0xc3,0xc4,0xc6,0xc7};//用于判断增减//char addorm[]={0x01,0x10,-0x01,-0x10};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。
DS1302电子时钟1602液晶显示#include#define uchar unsigned char#define uint unsigned intsbit RS=P2^2; //1602液晶显示器456管脚sbit RW=P2^3;sbit EN=P2^4;sbit SCLK=P1^0; //1302时钟芯片756管脚sbit IO=P1^1;sbit RST=P1^2;uchar time[]=" ";uchar time1[]=" ";uchar time2[2]="--";uchar time3[2]="::";uchar miao,fen,shi,ri,yue,nian,xingqi;void delay(uchar x) //延时{uint i,j;for(i=0;i<x;i++)for(j=0;j<20;j++);}void write_com(uchar com) //写指令{RS=0;RW=0;P0=com; //写指令码delay(1);EN=1; //高脉冲delay(1);EN=0;}void write_dat(uchar dat) //写数据{RS=1;RW=0;P0=dat; //写数据delay(1);EN=1; //高脉冲delay(1);EN=0;}void lcd_init(){write_com(0x38); //初始化液晶write_com(0x0c); //显示开关;不显示光标;光标不闪烁write_com(0x06); //指针+1光标+1;整屏显示不移动write_com(0x01); //显示清屏}void write1302_byte(uchar temp) //传输时钟数据{uchar i;SCLK=0; //初始时钟线置为0delay(1);for(i=0;i<8;i++) //开始传输8个字节的数据{IO=temp&0x01; //取最低位,注意DS1302的数据和地址都是从最低位开始传输的delay(1);SCLK=1; //时钟线拉高,制造上升沿,IO的数据被传输delay(1);SCLK=0; //时钟线被拉低,为下一个上升沿做准备temp=temp>>1; //数据右移一位,准备传输下一位数据}}uchar read1302_byte() //读取时钟数据{uchar i,temp;for(i=0;i<8;i++){temp=temp>>1; //要返回的数据左移一位if(IO==1) //当数据线为高时,证时该位数据为1temp=temp|0x80; //要传输数据的当前值为1,若不是,则为0 SCLK=1; //拉高时钟线delay(1);SCLK=0; //制造下降沿 ,IO的数据被传输delay(1);}return temp; //返回读取的数据}uchar read1302(uchar com) //{uchar dat;RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE线置为1,传输开始write1302_byte(com); //传输命令字,要读取的时间/日历地址dat=read1302_byte(); //读取要得到的时间/日期SCLK=1; //时钟线拉高RST=0; //读取结束,CE置为0,结束数据的传输return dat; //返回得到的时间/日期}void write1302(uchar com,uchar dat)//写入的时间/日历{RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE线置为1,传输开始write1302_byte(com);//传输命令字,要写入的时间/日历write1302_byte(dat);//写入要修改的时间/日期SCLK=1; //时钟线拉高RST=0; //写入结束,CE置为0,结束数据的传输}void init_1302(){write1302(0x8e,0x00); //关保护write1302(0x80,0x00); //0的话开起秒write1302(0x80,0x35); //秒</x;i++)write1302(0x82,0x00); //分write1302(0x84,0x08); //时write1302(0x86,0x11); //日write1302(0x88,0x01); //月write1302(0x8a,0x01); //星期write1302(0x8c,0x16); //年write1302(0x8e,0x80); //开保护}void disp() //液晶{uchar i;write_com(0x80); //液晶第一行for(i=0;i<16;i++){write_dat(time[i]);}write_com(0xc0); //液晶第二行for(i=0;i<16;i++){write_dat(time1[i]);}}void main() //主函数{lcd_init(); //设置液晶init_1302(); //设置时间while(1) //循环{xingqi=read1302(0x8b); //读取的星期地址time[13]=xingqi+'0'; //数据转换miao=read1302(0x81);time[9]=miao/16+'0';time[10]=miao%16+'0';time[8]=time3[0];fen=read1302(0x83);time[6]=fen/16+'0';time[7]=fen%16+'0';time[5]=time3[1];shi=read1302(0x85);time[3]=shi/16+'0';time[4]=shi%16+'0';ri=read1302(0x87);time1[9]=ri/16+'0';time1[10]=ri%16+'0';time1[8]=time2[0];yue=read1302(0x89);time1[6]=yue/16+'0';time1[7]=yue%16+'0';time1[5]=time2[0];nian=read1302(0x8d);time1[3]=nian/16+'0';time1[4]=nian%16+'0';disp(); //返回时间日期在液晶中的位置及数据}}。