1602液晶显示DS1302实时时钟程序
- 格式:doc
- 大小:131.50 KB
- 文档页数:30
#include<at89x52.h>#include"xianshi.h"sbit io=P1^0; // 1302通信允许sbit SCLK=P1^1; // 1302串行数据的位同步脉冲信号sbit RST=P1^2; // 1302双向串行数据传送sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchar tab[7];uchar year[12]={2,0,0,0,0x2d-0x30,0,0,0x2d-0x30,0,0,0x20-0x30,0x20-0x30};uchar week[7][3]={"mon","tue","wen","thu","fri","sat","sun"};uchar date[8]={0,0,0x3a-0x30,0,0,0x3a-0x30,0,0};void write1302(uchar date)//向ds1302写数据{uchar i;SCLK=0; //初始时钟线置为0ACC=date;for(i=8;i>0;i--) //开始传输8个字节的数据{io=ACC0; //取最低位,注意DS1302的数据和地址都是从最低位开始传输的SCLK=0; //时钟线拉低,为下一个上升沿做准备ACC=ACC>>1; //数据右移一位,准备传输下一位数据}}uchar read1302()//读ds1302数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1; //要返回的数据左移一位ACC7=io; //从1302由低位到高位逐渐取数据,存入ACC中SCLK=1; //拉高时钟线SCLK=0; //制造下降沿}return(ACC); //返回读取出的数据}void write1302_b(unsigned char add,unsigned char date){RST=0; //初始rst线置为0SCLK=0; //初始时钟sclk线置为0RST=1; //初始rst置为1,传输开始write1302(add); //传输命令字,要写入的时间/日历地址write1302(date); //写入要修改的时间/日期SCLK=1; //时钟线拉高RST=0; //读取结束,rst置为0,结束数据的传输}uchar read1302_b(uchar add){uchar date=0x00;RST=0;SCLK=0;RST=1;write1302(add); //传输命令字,要读取的时间/日历地址date=read1302(); //读取要得到的时间/日期RST=0;SCLK=1;return(date); //返回得到的时间/日期}/*****************初始化DS1302********************************/void init_ds1302(){if((((tab[6]=read1302_b(0x81))>>7)&&0x01)==1)/*秒寄存器的BIT7 定义为时间暂停位,当BIT1 为1 时,时钟振荡器停止工作,器启动,DS1302 正常工作。
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(); //显示时间}}。
#include <reg51.h>#include <intrins.h>unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"}; unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月参变数unsigned char data dis_buf1[16]; //lcd上排显示缓冲区unsigned char data dis_buf2[16]; //lcd下排显示缓冲区unsigned char data year,month,date,week;//年、月、日、星期unsigned char data armhour,armmin,armsec;//闹钟时、分、秒unsigned char data hour,min,sec,sec100; //时、分、秒、百分之一秒unsigned char data flag,vkey,skey;//设置状态计数标志、按键先前值、按键当前值bit alarm; //标识是否启用闹钟,1--启用,0--关闭sbit rs = P2^0; //LCD数据/命令选择端(H/L)sbit rw = P2^1; //LCD读/写选择端(H/L)sbit ep = P2^2; //LCD使能控制sbit PRE = P1^6; //调整键(k3)sbit SET = P1^7; //调整键(k4)sbit SPK = P3^7;void delayms(unsigned char ms); //延时程序bit lcd_busy(); //测试LCD忙碌状态程序void lcd_wcmd(char cmd); //写入指令到LCD程序void lcd_wdat(char dat); //写入数据到LCD程序void lcd_pos(char pos); //LCD数据指针位置程序void lcd_init(); //LCD初始化设定程序void pro_timedate(); //时间日期处理程序void pro_display(); //显示处理程序void pro_key(); //按键处理程序void time_alarm(); //定时报警功能(闹钟) unsigned char scan_key(); //按键扫描程序unsigned char week_proc(); //星期自动计算与显示函数bit leap_year(); //判断是否为闰年void lcd_sef_chr(); //LCD自定义字符程序void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s);//更新显示缓冲区函数// 延时程序void delay(unsigned char ms){ while(ms--){ unsigned char i;for(i = 0; i 250; i++){_nop_(); //执行一条_nop_()指令为一个机器周期_nop_();_nop_();_nop_();}}}//测试LCD忙碌状态bit lcd_busy(){bit result;rs = 0;rw = 1;ep = 1;_nop_();_nop_();_nop_();_nop_();result =(bit)(P0&0x80); //LCD的D0--D7中,D7=1为忙碌,D7=0为空闲ep = 0;return result;}//写入指令到LCDvoid lcd_wcmd(char cmd){while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写指令rs = 0;rw = 0;ep = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//写入数据到LCDvoid lcd_wdat(char dat){while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写数据rs = 1;rw = 0;ep = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//LCD数据指针位置程序void lcd_pos(char pos){lcd_wcmd(pos|0x80); //数据指针=80+地址码(00H~27H,40H~67H)}//设定二个自定义字符,(注意:LCD1602中自定义字符的地址为0x00--0x07,即可定义8个字符)//这里我们设定把一个自定义字符放在0x00位置(000),另一个放在0x01位子(001)void lcd_sef_chr(){ //第一个自定义字符lcd_wcmd(0x40); //"01 000 000" 第1行地址 (D7D6为地址设定命令D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))lcd_wdat(0x1f); //"XXX 11111" 第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭) lcd_wcmd(0x41); //"01 000 001" 第2行地址lcd_wdat(0x11); //"XXX 10001" 第2行数据lcd_wcmd(0x42); //"01 000 010" 第3行地址lcd_wdat(0x15); //"XXX 10101" 第3行数据lcd_wcmd(0x43); //"01 000 011" 第4行地址lcd_wdat(0x11); //"XXX 10001" 第4行数据lcd_wcmd(0x44); //"01 000 100" 第5行地址lcd_wdat(0x1f); //"XXX 11111" 第5行数据lcd_wcmd(0x45); //"01 000 101" 第6行地址lcd_wdat(0x0a); //"XXX 01010" 第6行数据lcd_wcmd(0x46); //"01 000 110" 第7行地址lcd_wdat(0x1f); //"XXX 11111" 第7行数据lcd_wcmd(0x47); //"01 000 111" 第8行地址lcd_wdat(0x00); //"XXX 00000" 第8行数据//第二个自定义字符lcd_wcmd(0x48); //"01 001 000" 第1行地址lcd_wdat(0x01); //"XXX 00001" 第1行数据lcd_wcmd(0x49); //"01 001 001" 第2行地址lcd_wdat(0x1b); //"XXX 11011" 第2行数据lcd_wcmd(0x4a); //"01 001 010" 第3行地址lcd_wdat(0x1d); //"XXX 11101" 第3行数据lcd_wcmd(0x4b); //"01 001 011" 第4行地址lcd_wdat(0x19); //"XXX 11001" 第4行数据lcd_wcmd(0x4c); //"01 001 100" 第5行地址lcd_wdat(0x1d); //"XXX 11101" 第5行数据lcd_wcmd(0x4d); //"01 001 101" 第6行地址lcd_wdat(0x1b); //"XXX 11011" 第6行数据lcd_wcmd(0x4e); //"01 001 110" 第7行地址lcd_wdat(0x01); //"XXX 00001" 第7行数据lcd_wcmd(0x4f); //"01 001 111" 第8行地址lcd_wdat(0x00); //"XXX 00000" 第8行数据}//LCD初始化设定void lcd_init(){lcd_wcmd(0x38); //设置LCD为16X2显示,5X7点阵,八位数据借口delay(1);lcd_wcmd(0x0c); //LCD开显示及光标设置(光标不闪烁,不显示"-")delay(1);lcd_wcmd(0x06); //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)delay(1);lcd_wcmd(0x01); //清除LCD的显示内容delay(1);}//闰年的计算bit leap_year(){bit leap;if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件leap=1;elseleap=0;return leap;}//星期的自动运算和处理unsigned char week_proc(){ unsigned char num_leap;unsigned char c;num_leap=year/4-year/100+year/400;//自00年起到year所经历的闰年数if( leap_year()&& month=2 ) //既是闰年且是1月和2月c=5;elsec=6;week=(year+para_month[month]+date+num_leap+c)%7;//计算对应的星期return week;}//更新显示缓冲区void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s){ dis_buf1[0]=t1; //dis_buf1[1]=0x20; //空格dis_buf1[2]=50; //'2'dis_buf1[3]=48; //'0'dis_buf1[4]=year/10+48;dis_buf1[5]=year%10+48;dis_buf1[6]=0x2d;dis_buf1[7]=month/10+48;dis_buf1[8]=month%10+48;dis_buf1[9]=0x2d; //'-'dis_buf1[10]=date/10+48;dis_buf1[11]=date%10+48;dis_buf1[12]=0x20;dis_buf1[13]=dis_week[4*week];dis_buf1[14]=dis_week[4*week+1];dis_buf1[15]=dis_week[4*week+2];dis_buf2[0]=t2[0];dis_buf2[1]=t2[1];dis_buf2[2]=t2[2];dis_buf2[3]=t2[3];dis_buf2[4]=t2[4];dis_buf2[5]=t2[5];dis_buf2[6]=0x20; //空格if (alarm)dis_buf2[7]=0x01; //alarm=1,显示闹钟启用标致(第二个自定义字符)elsedis_buf2[7]=0x20; //alarm=0,不显示闹钟启用标致dis_buf2[8]=dis_h/10+48;dis_buf2[9]=dis_h%10+48;dis_buf2[10]=0x3a; //':'dis_buf2[11]=dis_m/10+48;dis_buf2[12]=dis_m%10+48;dis_buf2[13]=0x3a;dis_buf2[14]=dis_s/10+48;dis_buf2[15]=dis_s%10+48;}//时间和日期处理程序void pro_timedate(){sec++;if(sec > 59){sec = 0;min++;if(min>59){min=0;hour++;if(hour>23){hour=0;date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31){date=1;month++;} //大月31天if(month==4||month==6||month==9||month==11)if (date>30){date=1;month++;} //小月30天if (month==2){if( leap_year())//闰年的条件{if (date>29){date=1;month++;}} //闰年2月为29天else{if (date>28){date=1;month++;}} //平年2月为28天}if (month>12) {month=1;year++;}if (year>99) year=0;}}}week_proc();if (sec==armsec && min==armmin &&hour==armhour){if (alarm)TR1=1; //闹钟启用时,报警时间到,启动Timer1}}//显示处理程序void pro_display(){ unsigned char i;lcd_pos(0x00);for (i=0;i=15;i++){lcd_wdat(dis_buf1[i]);}lcd_pos(0x40);for (i=0;i=15;i++){lcd_wdat(dis_buf2[i]);}}//Timer0中断处理程序,秒的产生void timer0() interrupt 1{TH0=0xdc; //Timer0置10ms定时初值dc00H(2^16=65536D,dc00H=56320D)TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)sec100++;if(sec100 >= 100) //1秒时间 (100*10ms=1000ms=1s){sec100 = 0;pro_timedate();//调用时间和日期处理程序}if(sec&0x01) / /"willar"闪一秒,停一秒update_disbuf(0x00," ",hour,min,sec); //0x0 0表示显示00位置的自定义字符elseupdate_disbuf(0x00,"willar",hour,min,sec);pro_display(); //调用显示处理函数}//按键扫描程序unsigned char scan_key(){skey=0x00; //给变量vkey置初值skey|=PRE; //读取PRE键的状态skey=skey<<1; //将PRE键的状态存于skey的B1位skey|=SET; //读取SET键的状态,并存于skey的B0位return skey; //返回skey的键值(即PRE,SET的状态)//外部中断INT0中断处理程序void int0() interrupt 0{TR0=0;//禁止Timer0IE=0;//禁止中断lcd_wcmd(0x0e); //显示光标"_",整个光标不闪烁alarm=1;update_disbuf(0x50,"alarm:",armhour,armmin,armsec); //更新显示数据,0x50表示要显示"P"pro_display(); //调用显示处理程序lcd_pos(0x47); //使光标位于第一个调整项下flag=0;vkey=0x03;while(flag^0x0a){skey = scan_key(); //扫描按键状态if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体{ delay(10); //去按键抖动skey = scan_key(); //转回扫描按键状态if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体{ vkey=skey; //将skey的值付给vkeyif (skey==0x01) //PRE 键按下{ flag++; / /调整标志位加1switch (flag) //将光标置于相应调整位置{cas e 1: lcd_pos(0x49);break; //光标置小时报警设置位置cas e 2: lcd_pos(0x4c);break; //光标置分钟报警设置位置cas e 3: lcd_pos(0x4f);break; //光标置秒时报警设置位置cas e 4: update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x05);break; //光标置年调整位置cas e 5: lcd_pos(0x08);break; //光标置月调整位置cas e 6: lcd_pos(0x0b);break; //光标置日调整位置cas e 7: lcd_pos(0x49);break; //光标置时调整位置cas e 8: lcd_pos(0x4c);break; //光标置分调整位置cas e 9: lcd_pos(0x4f);break; //光标置秒调整位置def ault:break;}}if(skey==0x02) //SET键按下{ pro_key();//转设置按键处理程序}}}}lcd_wcmd(0x0c); //设置LCD开显示及光标不闪烁,不显示"-"lcd_wcmd(0x01); //清除LCD的显示内容IE=0x8f; / /CPU开中断,INT0,INT1,开中断TR0=1;//Timer0启动}//主程序,初始化及初值设定void main(){lcd_init(); //初始化LCDlcd_sef_chr(); //写入自定义字符号hour=0;min=0;sec=0; //开机时的时,分,秒显示armhour=0;armmin=0;armsec=0; //开机时的时,分,秒报警初值year= 5; month=1;date=1; //开机时的年,月,日,星期显示week_proc();alarm=1; //初始开机,启用闹钟IE = 0x8f; //CPU开中断,INT0,INT1,Timer0,Timer1开中断IP = 0x04; //设置INT0为中断最高优先级IT0=0;IT1=0; //外部INT0,INT1设置为电平触发方式(注意,触发不要选边沿方式,易误动) TMOD = 0x11; //Timer0,Timer1工作于模式1, 16位定时方式TH0 = 0xdc;TL0 = 0x00; //Timer0置10ms定时初值TH1 = 0xff;TL1 = 0x00; //Timer1置初值TR0 = 1; //Timer0启动TR1 = 0;while(1);}//设置按键处理程序void pro_key(){switch (flag){case 0:alarm=!alarm; //启用或关闭闹钟(alarm=1:启用,alarm=0:关闭)update_disbuf(0x50,"alarm:",armhour,armmin,ar msec); //更新显示数据pro_display();//调用显示处理lcd_pos(0x47);break;//光标回到原调整位置case 1:armhour++;if (armhour>23) armhour=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec); //更新显示数据pro_display();//调用显示处理lcd_pos(0x49);break;//光标回到原调整位置case 2:armmin++;if (armmin>59) armmin=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec);pro_display();lcd_pos(0x4c);break;case 3:armsec++;if (armsec>59) armsec=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec);pro_display();lcd_pos(0x4f);break;case 4:year++;if (year> 99) year= 0;week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x05);break;case 5:month++;if (month>12) month=1;week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x08);break;case 6:date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31) date=1; //大月31天if(month==4||month==6||month==9||month==11)if (date>30) date=1; //小月30天if (month==2){if(leap_year())//闰年的条件{if (date>29) date=1;} //闰年2月为29天else{if (date>28) date=1;}} //平年2月为28天week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x0b);break;case 7:hour++;if (hour>23) hour=0;update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x49);break;case 8:min++;if (min>59) min=0;update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x4c);break;case 9:sec++;if (sec>59) sec=0;update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x4f);break;default:break ;}}//Timer1中断处理程序,产生报警的声音void timer1() interrupt 3{TH1=0xff;TL1=0x00;SPK=~SPK;}//外部中断INT1中断处理程序,停止报警声音void int1() interrupt 2{if(TR1)TR1=0;}//DS1302时钟程序#include <stc89c52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/******************************************************************** ///少占鱼制作河北正定欢迎您长沙航空职业技术学院//2010 年QQ:411656434//版权所有:#define LCD1602_RS P2_5 //定义引脚#define LCD1602_RW P2_6#define LCD1602_E P2_7#define LCD1602_IO P0#define Busy 0x80 //用于检测LCD1602状态字中的Busy标识const uchar num[]=" 3456789+";uchar code a[] = {" E N v"};void WriteData(uchar DAT);void WriteCommand(uchar command,BuysC);uchar ReadData(void);void Readbusy(void);void LCD1602_Init(void);void DisplayOneChar(uchar X, uchar Y, uchar DData);void Displaystring(uchar X, uchar Y, uchar *DData);void Delay5Ms(void);void Delay400Ms(void);void delayms(uint);void delays(uint m) ;void delayus(uchar x) ;sbit DS1302_CLK =P2^0;// P1^0;sbit DS1302_IO =P2^1;// P1^1;sbit DS1302_RST =P2^2;// P1^2;uchar shuju;unsigned char time[]={0x11,0x03,0x28,0x01,0x12,0x39,0x00};// 初始化时间年月日星期时分秒uchar Display_Buffer[12]={"12:25:00"};//时、分、秒的格式uchar riqi[12]={"11-03-28"};//年、月、日的格式uchar xingqi[5]="week";//星期unsigned char second,minute,hour,week,day,month,year;/******************1602函数********************************//******************************************************************** /void delays(uint m){uint i,j;for(i=0;i<m;i++){for(j=0;j<1000;j++){;}}}void Delay(void){unsigned char i;unsigned int j;for(i=0;i<200;i++)for(j=300;j>0;j--);/******************************************************************** *********函数功能:向DS1302送一字节数据子程序入口参数:出口参数:********************************************************************* ********/void InputByte(unsigned char BYTE){char i;for(i=8;i>0;i--){ //前面在read_ds1302()函数里已经把CLK清0了DS1302_CLK=0;//这里再清0一次,看着清楚。
#include <AT89X51.H>#include<absacc.h>#define WRITE_SECOND 0x80#define WRITE_MINUTE 0x82#define WRITE_HOUR 0x84#define READ_SECOND 0x81#define READ_MINUTE 0x83#define READ_HOUR 0x85#define WRITE_PROTECT 0x8E//位寻址寄存器定义sbit p17=P1^7;//管脚定义sbit SCLK = P3^3; // DS1302时钟信号7脚sbit DIO= P3^4; // DS1302数据信号6脚sbit CE = P3^5; // DS1302片选5脚/////////**********定义引脚************************//////#define lcd_db P0sbit lcd_rs=P2^4;sbit lcd_rw=P2^5;sbit lcd_e=P2^6;unsigned char table[]=" ";unsigned char tabl[]="0123456789";//////////********定义函数*********************/////////#define uchar unsigned char#define uint unsigned intvoid lcd_chushi(void);///////初始化函数void lcd_command(uchar command); /////写指令函数void lcd_data(uchar dat); ////写数据函数void lcd_disp_char(uchar x,uchar y);///显示函数void delay(uint n); ////延时函数////////////********初始化函数**************////////void lcd_chushi(void){lcd_command(0x38);lcd_command(0x38);lcd_command(0x06);lcd_command(0x0c);lcd_command(0x01);delay(100);}////////**************写指令函数***************/////////////// void lcd_command(uchar dat){lcd_db=dat;lcd_rs=0;lcd_rw=0;lcd_e=1;lcd_e=0;delay(10);}///////////////*******数据写入*********************///////////void lcd_data(uchar dat){lcd_db=dat;lcd_rs=1;lcd_rw=0;lcd_e=1;delay(100);lcd_e=0;delay(100);}/////////*******显示函数********************////////////////////void lcd_disp_char(uchar x,uchar y){uchar address;if(y==1)address=0x80+x;elseaddress=0xc0+x;lcd_command(address);}/////////////****************延时*********************////////////// void delay(uint n){uint i;uchar j;for(i=n;i>0;i--)for(j=0;j<10;j++);}void xianshi(uint i,k,l)//////显示{uchar j;table[9]=tabl[l%16];///////显示第几位table[8]=tabl[l/16%10];///////显示第几位table[5]=tabl[k%16];///////显示第几位table[4]=tabl[k/16%10];///////显示第几位table[1]=tabl[i%16];///////显示第几位table[0]=tabl[i/16%10];///////显示第几位for(j=0;j<10;j++){lcd_data(table[j]);}}void Write1302 ( unsigned char addr,dat ){unsigned char i,temp;CE=0; //CE引脚为低,数据传送中止SCLK=0; //清零时钟总线CE = 1; //CE引脚为高,逻辑控制有效//发送地址for ( i=8; i>0; i-- ) //循环8次移位{SCLK = 0;temp = addr;DIO = (bit)(temp&0x01); //每次传输低字节addr >>= 1; //右移一位SCLK = 1;}//发送数据for ( i=8; i>0; i-- ){SCLK = 0;temp = dat;DIO = (bit)(temp&0x01);dat >>= 1;SCLK = 1;}CE = 0;}unsigned char Read1302 ( unsigned char addr ){unsigned char i,temp,dat1;CE=0;SCLK=0;CE = 1;//发送地址for ( i=8; i>0; i-- ) //循环8次移位{SCLK = 0;temp = addr;DIO = (bit)(temp&0x01); //每次传输低字节addr >>= 1; //右移一位SCLK = 1;}//读取数据for ( i=8; i>0; i-- ){p17=DIO;SCLK=1;P1>>=1;SCLK=0;}CE=0;dat1=P1;return dat1;}void Initial(void){Write1302 (WRITE_PROTECT,0x00); //禁止写保护Write1302 (WRITE_SECOND,0x56); //秒位初始化Write1302 (WRITE_MINUTE,0x12); //分钟初始化Write1302 (WRITE_HOUR,0x09); //小时初始化Write1302 (WRITE_PROTECT,0x80); //允许写保护}void main(){uint shi,fen,miao;lcd_chushi();////////////初始化Initial();while(1){miao=Read1302 (READ_SECOND);fen=Read1302 (READ_MINUTE);shi=Read1302 (READ_HOUR);lcd_disp_char(0,1);////显示位置xianshi(shi,fen,miao); ///显示内容lcd_disp_char(0,0);///显示位置xianshi(shi,fen,miao); //显示内容}}。
#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 <AT89x51.h>#include <string.h>#include<intrins.h>#define LCM_RS P2_0 //定义引脚#define LCM_RW P2_1#define LCM_E P2_2#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识 #define uchar unsigned charuchar id,timecount,dipsmodid;bit lmcinit_or_not; //是否需要清屏标志位“1”为需要“0”为不需要 bit flag,sflag; //flag是时钟冒号闪烁标志,sflag是温度负号显示标志 void Disp_line1(void); //显示屏幕第一行void Disp_line2(void); //显示屏幕第二行void id_case1_key();void Disp_mod0(void);//显示模式0void Disp_mod1(void);//显示模式//*********** DS1302 时间显示定义部分sbit T_CLK=P1^0;sbit T_IO =P1^1;sbit T_RST=P1^2;sbit ACC0=ACC^0;sbit ACC7=ACC^7;void Set(uchar,uchar); //根据选择调整相应项目void RTInputByte(uchar); /* 输入 1Byte */uchar RTOutputByte(void); /* 输出 1Byte */void W1302(uchar, uchar); // 向DS1302写入一个字节 uchar R1302(uchar); // 从DS1302读出一个字节 void Set1302(unsigned char * ); // 设置时间bit sec,min,hour,year,mon,day,weekk; //闪烁标志位//初始化后设置为:04年12月2日星期4 0点0分0秒unsigned char inittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04};// 秒分钟小时日月年星期//***** 18B20温度显示定义部sbit DQ=P3^3; //18B20 接P07口 typedef unsigned char byte; typedef unsigned int word; Read_Temperature(char,char); void mychar(void);。
#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);}}。
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。
/* 时间:4月19日功能:使用ds1302实时时钟芯片,用共阴数码管显示时,分,秒*/#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit io=P3^4;sbit cs=P3^5;sbit clk=P3^6;uchar code table1[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80};uchar code table2[]={ //译码器与单片机的接线引脚P2.4 P2.3 P2.20xe3,0xe7,0xeb,0xef,0xf3,0xf7,0xfb,0xff};uchar time[7]={14,2,3,25,23,59,50}; //初始化实时时钟时间uchar register_wr[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};uchar register_re[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; uchar temp1[7];uchar shi,ge;void delay_ms(uchar t);void delay(); //大约10usvoid spi_writebyte(uchar dat);uchar spi_readbyte();void ds1302_spiwrite(uchar add,uchar dat);uchar ds1302_spiread(uchar add);void ds1302_init();void ds1302_run(); //ds1302全运行过程void display(); //共阴数码管显示过程void main(){ds1302_init();while(1){ds1302_run();display();}}void delay_ms(uchar t){uchar x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}void ds1302_run(){ //ds1302全运行过程uchar i;for(i=0;i<7;i++){ds1302_spiwrite(0x8e,0x80);//写保护,不让写temp1[i]=ds1302_spiread(register_re[i]); //将十六进制数转换成相同数字的十进制shi=temp1[i]/16;ge=temp1[i]%16;time[i]=shi*10+ge;}}void display(){P0=table1[time[4]/10]; P2=table2[0];delay_ms(1);P0=table1[time[4]%10]; P2=table2[1];delay_ms(1);P0=table1[16];P2=table2[2];delay_ms(1);P0=table1[time[5]/10]; P2=table2[3];delay_ms(1);P0=table1[time[5]%10]; P2=table2[4];delay_ms(1);P0=table1[16];P2=table2[5];delay_ms(1);P0=table1[time[6]/10];P2=table2[6];delay_ms(1);P0=table1[time[6]%10];P2=table2[7];delay_ms(1);}void ds1302_init(){uchar i;ds1302_spiwrite(0x8e,0x00); //wp是写允许位。
/*******************说明:**************************将实时时钟数据通过LCD1602显示--------------------------------------------------基于51单片机**************************************************/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar dis_time_buf[16]={0};//LCD1602引脚定义//采用8位并行方式,DB0~DB7连接至LCDDATA0~LCDDATA7 sbit RS=P2^0;sbit RW=P2^1;sbit CS=P2^2;#define LCDDATA P0//DS1302引脚定义sbit RST=P1^3;sbit IO=P1^2;sbit SCK=P1^1;//DS1302地址定义#define ds1302_sec_add 0x80 //秒数据地址#define ds1302_min_add 0x82 //分数据地址#define ds1302_hr_add 0x84 //时数据地址#define ds1302_date_add 0x86 //日数据地址#define ds1302_month_add 0x88 //月数据地址#define ds1302_day_add 0x8a //星期数据地址#define ds1302_year_add 0x8c //年数据地址#define ds1302_control_add 0x8e //控制数据地址#define ds1302_charger_add 0x90#define ds1302_clkburst_add 0xbe//初始时间定义uchar time_buf[8] = {0x20,0x10,0x06,0x01,0x23,0x59,0x55,0x02};//初始时间2010年6月1号23点59分55秒星期二//功能:延时1毫秒//入口参数:x//出口参数:无//说明:当晶振为12M时,j<112;当晶振为11.0592M时,j<122void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++)for(j=0;j<112;j++);}//功能:12us延时//STC89C52为1T单片机,即1个时钟/机器周期,速度为AT89C52的12倍void Delay_xus(uint t){for(;t>0;t--){_nop_();}}//控制LCD写时序void LCD_en_write(void){CS=1;Delay_xus(20);CS=0;Delay_xus(20);}//写指令函数void Write_Instruction(uchar command){RS=0;CS=1;LCDDATA=command;LCD_en_write();//写入指令数据}//写数据函数void Write_Data(uchar Wdata){RS=1;RW=0;CS=1;LCDDATA=Wdata;LCD_en_write();//写入数据}//字符显示初始地址设置void LCD_SET_XY(uchar X,uchar Y){uchar address;if(Y==0)address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0xC0 Write_Instruction(address);//写指令,设置显示初始地址}//在第X行Y列开始显示Wdata所对应的单个字符void LCD_write_char(uchar X,uchar Y,uchar Wdata){LCD_SET_XY(X,Y);//写地址Write_Data(Wdata);//写入当前字符并显示}//清屏函数void LCD_clear(void){Write_Instruction(0x01);Delay_xms(5);}//显示屏初始化函数void LCD_init(void){Write_Instruction(0x38); //8bit interface,2line,5*7dots Delay_xms(5);Write_Instruction(0x38);Delay_xms(5);Write_Instruction(0x38);Write_Instruction(0x08); //关显示,不显光标,光标不闪烁Write_Instruction(0x01); //清屏Delay_xms(5);Write_Instruction(0x04); //写一字符,整屏显示不移动//Write_Instruction(0x05); //写一字符,整屏右移//Write_Instruction(0x06); //写一字符,整屏显示不移动//Write_Instruction(0x07); //写一字符,整屏左移Delay_xms(5);//Write_Instruction(0x0B); //关闭显示(不显示字符,只有背光亮)Write_Instruction(0x0C); //开显示,光标、闪烁都关闭//Write_Instruction(0x0D); //开显示,不显示光标,但光标闪烁//Write_Instruction(0x0E); //开显示,显示光标,但光标不闪烁//Write_Instruction(0x0F); //开显示,光标、闪烁均显示}//DS1302初始化函数void ds1302_init(void){RST=0; //RST脚置低SCK=0; //SCK脚置低}//向DS1302写入一字节数据void ds1302_write_byte(uchar addr, uchar d){uchar i;RST=1; //启动DS1302总线//写入目标地址:addraddr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读for (i = 0; i < 8; i ++) {if (addr & 0x01) {IO=1;}else {IO=0;}SCK=1; //产生时钟SCK=0;addr = addr >> 1;}//写入数据:dfor (i = 0; i < 8; i ++) {if (d & 0x01) {IO=1;}else {IO=0;}SCK=1; //产生时钟SCK=0;d = d >> 1;}RST=0; //停止DS1302总线}//从DS1302读出一字节数据uchar ds1302_read_byte(uchar addr) {uchar i,temp;RST=1; //启动DS1302总线//写入目标地址:addraddr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读for (i = 0; i < 8; i ++) {if (addr & 0x01) {IO=1;}else {IO=0;}SCK=1;SCK=0;addr = addr >> 1;}//输出数据:tempfor (i = 0; i < 8; i ++) { temp = temp >> 1;if (IO) {temp |= 0x80;}else {temp &= 0x7F;}SCK=1;SCK=0;}RST=0; //停止DS1302总线return temp;}//向DS302写入时钟数据void ds1302_write_time(void){ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护ds1302_write_byte(ds1302_sec_add,0x80); //暂停时钟//ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电ds1302_write_byte(ds1302_year_add,time_buf[1]); //年ds1302_write_byte(ds1302_month_add,time_buf[2]); //月ds1302_write_byte(ds1302_date_add,time_buf[3]); //日ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时ds1302_write_byte(ds1302_min_add,time_buf[5]); //分ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒ds1302_write_byte(ds1302_day_add,time_buf[7]); //周ds1302_write_byte(ds1302_control_add,0x80); //打开写保护}//从DS302读出时钟数据void ds1302_read_time(void){time_buf[1]=ds1302_read_byte(ds1302_year_add); //年time_buf[2]=ds1302_read_byte(ds1302_month_add); //月time_buf[3]=ds1302_read_byte(ds1302_date_add); //日time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时time_buf[5]=ds1302_read_byte(ds1302_min_add); //分time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59time_buf[7]=ds1302_read_byte(ds1302_day_add); //周}void Display(void){LCD_write_char(3,0,dis_time_buf[0]+'0');LCD_write_char(4,0,dis_time_buf[1]+'0');LCD_write_char(5,0,dis_time_buf[2]+'0');LCD_write_char(6,0,dis_time_buf[3]+'0');LCD_write_char(7,0,'/');LCD_write_char(9,0,dis_time_buf[5]+'0'); LCD_write_char(10,0,'/');LCD_write_char(11,0,dis_time_buf[6]+'0');LCD_write_char(12,0,dis_time_buf[7]+'0');LCD_write_char(15,0,dis_time_buf[14]+'0'); //第2行显示LCD_write_char(3,1,dis_time_buf[8]+'0'); LCD_write_char(4,1,dis_time_buf[9]+'0'); LCD_write_char(5,1,':');LCD_write_char(7,1,dis_time_buf[11]+'0');LCD_write_char(8,1,':');LCD_write_char(9,1,dis_time_buf[12]+'0');LCD_write_char(10,1,dis_time_buf[13]+'0');}//定时器中断函数void Timer2() interrupt 5 //定时器2是5号中断{static uchar t;TF2=0;t++;if(t==4) //间隔200ms(50ms*4)读取一次时间{t=0;ds1302_read_time(); //读取时间dis_time_buf[0]=(time_buf[0]>>4); //年dis_time_buf[1]=(time_buf[0]&0x0f);dis_time_buf[2]=(time_buf[1]>>4);dis_time_buf[3]=(time_buf[1]&0x0f);dis_time_buf[4]=(time_buf[2]>>4); //月dis_time_buf[5]=(time_buf[2]&0x0f);dis_time_buf[6]=(time_buf[3]>>4); //日dis_time_buf[7]=(time_buf[3]&0x0f);dis_time_buf[14]=(time_buf[7]&0x07); //星期//第2行显示dis_time_buf[8]=(time_buf[4]>>4); //时dis_time_buf[9]=(time_buf[4]&0x0f);dis_time_buf[10]=(time_buf[5]>>4); //分dis_time_buf[11]=(time_buf[5]&0x0f);dis_time_buf[12]=(time_buf[6]>>4); //秒dis_time_buf[13]=(time_buf[6]&0x0f);}}//定时器2初始化void Init_timer2(void){RCAP2H=0x3c;//赋T2初始值0x3cb0,溢出20次为1秒,每次溢出时间为50ms RCAP2L=0xb0;TR2=1; //启动定时器2ET2=1; //打开定时器2中断EA=1; //打开总中断}//主函数void main(void)Delay_xms(50);//等待系统稳定LCD_init(); //LCD初始化LCD_clear(); //清屏ds1302_init(); //DS1302初始化Delay_xms(10);ds1302_write_time(); //写入初始值Init_timer2(); //定时器2初始化while(1){Display();}}。
#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit k1=P1^0; //开关的位置sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit clk=P3^6; //时钟线sbit en=P3^5; //使能端sbit io=P3^4; //DS1302的IO口sbit lcden=P2^7; //液晶使能端sbit lcdrd=P2^6; //数据命令端sbit lcdwr=P2^5; //读写选择端sbit beep=P2^4; //蜂鸣器位置bit flag; //按键标志位uchar code t[]="LCD LOCK"; //第一行显示字符uchar code b[]="****"; //第二行显示字符uchar c[8] ={0x00}; //定义显示缓冲区uchar d[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、uchar e[2]={0}; //用来存放分钟小时的中间值void delay(uint x) //延时函数{ uint i,j;for(i=0;i<x;i++)for(j=0;j<115;j++); //延时X*MS}void write_com(uchar com) //命令函数{ lcdrd=0; //选择命令端P0=com; //要写的命令送到P0口delay(5);lcden=1; //开启使能端delay(5);lcden=0; //关闭使能端}void write_data(uchar dat) //数据函数{ lcdrd=1; //数据选择端P0=dat;delay(5);lcden=1; //开使能delay(5);lcden=0;}bit busy() //忙碌检查函数{ bit result;lcdrd=0;lcdwr=1;lcden=1;_nop_(); //延时几微秒_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result;}void lcdclr() //LCD清屏函数{ write_com(0x01); //清零显示,数据指针清零delay(5);}void init() //初始化函数{ delay(15);write_com(0x38); //16*2显示,5*7点阵,8位数据delay(15);write_com(0x38);write_com(0x06); //写一个字符地址指针加1 delay(5);write_com(0x0c); //设置显示,不显示光标delay(5);write_com(0x01); //显示清零,数据指针清零}void write_byte(uchar date) //写一个字节函数{ uchar i;for(i=0;i<8;i++){ clk=0; //低电平改变数据if(date&0x01)io=1;elseio=0;clk=1; //高电平写入1302_nop_();date=date>>1;}}uchar read_byte() //读一个字节函数{uchar i,temp=0;io=1;for(i=0;i<7;i++){clk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;clk=1; //产生下跳沿temp=temp>>1;}return temp;}void write1302(uchar com,uchar dat) //写1302函数在某个地址写数据{ clk=0;en=1;write_byte(com);write_byte(dat);clk=0;en=0;}uchar read1302(uchar add) //读1302函数,从地址读数据{ uchar d;clk=0;en=1;write_byte(add); //先写地址d=read_byte(); //后读数据clk=0;en=0;return d;}void set1302(uchar add,uchar *p,uchar n) //时间初始化{ write1302(0x80,0x00); //写控制,允许写操作for(;n>0;n--){ write1302(add,*p);p++;add=add+2;}write1302(0x8e,0x80); //写保护,不允许写操作}void get1302(uchar add,uchar *p,uchar n) //读取当前数据{ for(;n>0;n--){ *p=read1302(add);p++;add=add+2;}}void init1302() //初始化1302函数{ en=0;clk=0;write1302(0x80,0x00); //写秒寄存器write1302(0x90,0xab); //写充电器write1302(0x8e,0x80); //写保护,禁止写}void BEEP() //蜂鸣器函数{ beep=0; //响蜂鸣器delay(100); //响0.1sbeep=1;delay(100);}void lcdcon(uchar m1,m2,m3) //将数据转化成适合LCD显示的数据{ c[0]=m1/10+0x30; //小时十位数据c[1]=m1%10+0x30; //小时个位数据c[2]=m2/10+0x30; //分钟十位数据c[3]=m2%10+0x30; //分钟个位数据c[4]=m3/10+0x30; //秒十位c[5]=m3%10+0x30; //秒个位}void lcddis() //LCD显示函数{ write_com(0x44|0x80); //第二行第四列write_data(c[0]); //小时十位write_data(c[1]); //小时个位write_data(':'); //显示:write_data(c[2]); //显示分钟十位write_data(c[3]); //显示分钟个位write_data(':');write_data(c[4]); //显示秒十位write_data(c[5]); //显示秒个位}void keyscan() //按键函数{ uchar fen,shi; //定义两个16位分钟和小时write1302(0x8e,0x00); //1302写保护,允许写write1302(0x80,0x80); //时钟停止运行if(k2==0) //按键2被按下{ d elay(10); //去抖动if(k2==0) //确认被按下{ while(!k2); //等待按键释放BEEP(); //蜂鸣器函数d[2]=d[2]+1; //小时加1if(d[2]==24) //满24清零d[2]=0;shi=d[2]/10*16+d[2]%10; //将小时转化成16进制write1302(0x84,shi); //调整后写入1302}}if(k3==0) //按键3被按下{ delay(10); //抖动if(k3==0) //确认被按下{ while(!k3); //等待按键放开BEEP(); //蜂鸣器函数d[1]=d[1]+1; //分钟加1if(d[1]==60) //满60清零d[1]=0;fen=d[1]/10*16+d[1]%10; //将分钟转化为16进制write1302(0x82,fen); //调整后,写入1302}}if(k4==0) //按键4被按下{ d elay(10); //去抖动if(k4==0) //确认被按下{ while(!k4); //等待按键释放BEEP(); //蜂鸣器函数write1302(0x80,0x00); //调整后,启动时钟运行write1302(0x8e,0x80); //写保护,禁止写flag=0; //按键1标志位清零}}}void gettime() //读取当前时间,转化为10进制{ uchar miao,fen,shi;write1302(0x8e,0x00); //控制命令,0表示允许写write1302(0x90,0xab); //电流控制miao=read1302(0x81); //读取秒fen=read1302(0x83); //读取分shi=read1302(0x85); //读取小时d[0]=miao/16*10+miao%16; //转化为10进制d[1]=fen/16*10+fen%16; //转化为10进制d[2]=shi/16*10+shi%16; //转换为10进制}void main() //主函数{ uchar i;P0=0xff;P2=0xff;init1302(); //1302初始化函数lcdclr(); //1302清屏函数write_com(0x00|0x80); //第一行第0列i=0;while(t[i]!=0){ write_data(t[i]); //第一个字符显示i++;}write_com(0x40|0x80); //第二行显示第0列i=0;while(b[i]!=0);{ write_data(b[i]);i++;}init1302();while(1){ gettime();if(k1==0) //按键1按下{ delay(10); //去抖动if(k1==0) //确认按下{ while(!k1); //等待按键释放BEEP(); //蜂鸣器函数flag=1; //按键1标志位置位,进行时钟调整}}if(flag==1) //如为1,则进行调整keyscan();lcdcon(d[2],d[1],d[0]); //将1302的数据送到函数转换lcddis(); //调整LCD显示,显示小时,分钟,秒}}。
#include <reg51.h>#include <intrins.h>unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"}; unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月参变数unsigned char data dis_buf1[16]; //lcd上排显示缓冲区unsigned char data dis_buf2[16]; //lcd下排显示缓冲区unsigned char data year,month,date,week;//年、月、日、星期unsigned char data armhour,armmin,armsec;//闹钟时、分、秒unsigned char data hour,min,sec,sec100; //时、分、秒、百分之一秒unsigned char data flag,vkey,skey;//设置状态计数标志、按键先前值、按键当前值bit alarm; //标识是否启用闹钟,1--启用,0--关闭sbit rs = P2^0; //LCD数据/命令选择端(H/L)sbit rw = P2^1; //LCD读/写选择端(H/L)sbit ep = P2^2; //LCD使能控制sbit PRE = P1^6; //调整键(k3)sbit SET = P1^7; //调整键(k4)sbit SPK = P3^7;void delayms(unsigned char ms); //延时程序bit lcd_busy(); //测试LCD忙碌状态程序void lcd_wcmd(char cmd); //写入指令到LCD程序void lcd_wdat(char dat); //写入数据到LCD程序void lcd_pos(char pos); //LCD数据指针位置程序void lcd_init(); //LCD初始化设定程序void pro_timedate(); //时间日期处理程序void pro_display(); //显示处理程序void pro_key(); //按键处理程序void time_alarm(); //定时报警功能(闹钟) unsigned char scan_key(); //按键扫描程序unsigned char week_proc(); //星期自动计算与显示函数bit leap_year(); //判断是否为闰年void lcd_sef_chr(); //LCD自定义字符程序void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s);//更新显示缓冲区函数// 延时程序void delay(unsigned char ms){ while(ms--){ unsigned char i;for(i = 0; i 250; i++){_nop_(); //执行一条_nop_()指令为一个机器周期_nop_();_nop_();_nop_();}}}//测试LCD忙碌状态bit lcd_busy(){bit result;rs = 0;rw = 1;ep = 1;_nop_();_nop_();_nop_();_nop_();result =(bit)(P0&0x80); //LCD的D0--D7中,D7=1为忙碌,D7=0为空闲ep = 0;return result;}//写入指令到LCDvoid lcd_wcmd(char cmd){while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写指令rs = 0;rw = 0;ep = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//写入数据到LCDvoid lcd_wdat(char dat){while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写数据rs = 1;rw = 0;ep = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//LCD数据指针位置程序void lcd_pos(char pos){lcd_wcmd(pos|0x80); //数据指针=80+地址码(00H~27H,40H~67H)}//设定二个自定义字符,(注意:LCD1602中自定义字符的地址为0x00--0x07,即可定义8个字符)//这里我们设定把一个自定义字符放在0x00位置(000),另一个放在0x01位子(001)void lcd_sef_chr(){ //第一个自定义字符lcd_wcmd(0x40); //"01 000 000" 第1行地址 (D7D6为地址设定命令形式 D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))lcd_wdat(0x1f); //"XXX 11111" 第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭) lcd_wcmd(0x41); //"01 000 001" 第2行地址lcd_wdat(0x11); //"XXX 10001" 第2行数据lcd_wcmd(0x42); //"01 000 010" 第3行地址lcd_wdat(0x15); //"XXX 10101" 第3行数据lcd_wcmd(0x43); //"01 000 011" 第4行地址lcd_wdat(0x11); //"XXX 10001" 第4行数据lcd_wcmd(0x44); //"01 000 100" 第5行地址lcd_wdat(0x1f); //"XXX 11111" 第5行数据lcd_wcmd(0x45); //"01 000 101" 第6行地址lcd_wdat(0x0a); //"XXX 01010" 第6行数据lcd_wcmd(0x46); //"01 000 110" 第7行地址lcd_wdat(0x1f); //"XXX 11111" 第7行数据lcd_wcmd(0x47); //"01 000 111" 第8行地址lcd_wdat(0x00); //"XXX 00000" 第8行数据//第二个自定义字符lcd_wcmd(0x48); //"01 001 000" 第1行地址lcd_wdat(0x01); //"XXX 00001" 第1行数据lcd_wcmd(0x49); //"01 001 001" 第2行地址lcd_wdat(0x1b); //"XXX 11011" 第2行数据lcd_wcmd(0x4a); //"01 001 010" 第3行地址lcd_wdat(0x1d); //"XXX 11101" 第3行数据lcd_wcmd(0x4b); //"01 001 011" 第4行地址lcd_wdat(0x19); //"XXX 11001" 第4行数据lcd_wcmd(0x4c); //"01 001 100" 第5行地址lcd_wdat(0x1d); //"XXX 11101" 第5行数据lcd_wcmd(0x4d); //"01 001 101" 第6行地址lcd_wdat(0x1b); //"XXX 11011" 第6行数据lcd_wcmd(0x4e); //"01 001 110" 第7行地址lcd_wdat(0x01); //"XXX 00001" 第7行数据lcd_wcmd(0x4f); //"01 001 111" 第8行地址lcd_wdat(0x00); //"XXX 00000" 第8行数据}//LCD初始化设定void lcd_init(){lcd_wcmd(0x38); //设置LCD为16X2显示,5X7点阵,八位数据借口delay(1);lcd_wcmd(0x0c); //LCD开显示及光标设置(光标不闪烁,不显示"-")delay(1);lcd_wcmd(0x06); //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)delay(1);lcd_wcmd(0x01); //清除LCD的显示内容delay(1);}//闰年的计算bit leap_year(){bit leap;if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件leap=1;elseleap=0;return leap;}//星期的自动运算和处理unsigned char week_proc(){ unsigned char num_leap;unsigned char c;num_leap=year/4-year/100+year/400;//自00年起到year所经历的闰年数if( leap_year()&& month=2 ) //既是闰年且是1月和2月c=5;elsec=6;week=(year+para_month[month]+date+num_leap+c)%7;//计算对应的星期return week;}//更新显示缓冲区void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s){ dis_buf1[0]=t1; //dis_buf1[1]=0x20; //空格dis_buf1[2]=50; //'2'dis_buf1[3]=48; //'0'dis_buf1[4]=year/10+48;dis_buf1[5]=year%10+48;dis_buf1[6]=0x2d;dis_buf1[7]=month/10+48;dis_buf1[8]=month%10+48;dis_buf1[9]=0x2d; //'-'dis_buf1[10]=date/10+48;dis_buf1[11]=date%10+48;dis_buf1[12]=0x20;dis_buf1[13]=dis_week[4*week];dis_buf1[14]=dis_week[4*week+1];dis_buf1[15]=dis_week[4*week+2];dis_buf2[0]=t2[0];dis_buf2[1]=t2[1];dis_buf2[2]=t2[2];dis_buf2[3]=t2[3];dis_buf2[4]=t2[4];dis_buf2[5]=t2[5];dis_buf2[6]=0x20; //空格if (alarm)dis_buf2[7]=0x01; //alarm=1,显示闹钟启用标致(第二个自定义字符)elsedis_buf2[7]=0x20; //alarm=0,不显示闹钟启用标致dis_buf2[8]=dis_h/10+48;dis_buf2[9]=dis_h%10+48;dis_buf2[10]=0x3a; //':'dis_buf2[11]=dis_m/10+48;dis_buf2[12]=dis_m%10+48;dis_buf2[13]=0x3a;dis_buf2[14]=dis_s/10+48;dis_buf2[15]=dis_s%10+48;}//时间和日期处理程序void pro_timedate(){sec++;if(sec > 59){sec = 0;min++;if(min>59){min=0;hour++;if(hour>23){hour=0;date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31){date=1;month++;} //大月31天if(month==4||month==6||month==9||month==11)if (date>30){date=1;month++;} //小月30天if (month==2){if( leap_year())//闰年的条件{if (date>29){date=1;month++;}} //闰年2月为29天else{if (date>28){date=1;month++;}} //平年2月为28天}if (month>12) {month=1;year++;}if (year>99) year=0;}}}week_proc();if (sec==armsec && min==armmin &&hour==armhour){if (alarm)TR1=1; //闹钟启用时,报警时间到,启动Timer1}}//显示处理程序void pro_display(){ unsigned char i;lcd_pos(0x00);for (i=0;i=15;i++){lcd_wdat(dis_buf1[i]);}lcd_pos(0x40);for (i=0;i=15;i++){lcd_wdat(dis_buf2[i]);}}//Timer0中断处理程序,秒的产生void timer0() interrupt 1{TH0=0xdc; //Timer0置10ms定时初值dc00H(2^16=65536D,dc00H=56320D)TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)sec100++;if(sec100 >= 100) //1秒时间 (100*10ms=1000ms=1s){sec100 = 0;pro_timedate();//调用时间和日期处理程序}if(sec&0x01) / /"willar"闪一秒,停一秒update_disbuf(0x00," ",hour,min,sec); //0x0 0表示显示00位置的自定义字符elseupdate_disbuf(0x00,"willar",hour,min,sec);pro_display(); //调用显示处理函数}//按键扫描程序unsigned char scan_key(){skey=0x00; //给变量vkey置初值skey|=PRE; //读取PRE键的状态skey=skey<<1; //将PRE键的状态存于skey的B1位skey|=SET; //读取SET键的状态,并存于skey的B0位return skey; //返回skey的键值(即PRE,SET的状态)//外部中断INT0中断处理程序void int0() interrupt 0{TR0=0;//禁止Timer0IE=0;//禁止中断lcd_wcmd(0x0e); //显示光标"_",整个光标不闪烁alarm=1;update_disbuf(0x50,"alarm:",armhour,armmin,armsec); //更新显示数据,0x50表示要显示"P"pro_display(); //调用显示处理程序lcd_pos(0x47); //使光标位于第一个调整项下flag=0;vkey=0x03;while(flag^0x0a){skey = scan_key(); //扫描按键状态if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体{ delay(10); //去按键抖动skey = scan_key(); //转回扫描按键状态if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体{ vkey=skey; //将skey的值付给vkeyif (skey==0x01) //PRE 键按下{ flag++; / /调整标志位加1switch (flag) //将光标置于相应调整位置{cas e 1: lcd_pos(0x49);break; //光标置小时报警设置位置cas e 2: lcd_pos(0x4c);break; //光标置分钟报警设置位置cas e 3: lcd_pos(0x4f);break; //光标置秒时报警设置位置cas e 4: update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x05);break; //光标置年调整位置cas e 5: lcd_pos(0x08);break; //光标置月调整位置cas e 6: lcd_pos(0x0b);break; //光标置日调整位置cas e 7: lcd_pos(0x49);break; //光标置时调整位置cas e 8: lcd_pos(0x4c);break; //光标置分调整位置cas e 9: lcd_pos(0x4f);break; //光标置秒调整位置def ault:break;}}if(skey==0x02) //SET键按下{ pro_key();//转设置按键处理程序}}}}lcd_wcmd(0x0c); //设置LCD开显示及光标不闪烁,不显示"-"lcd_wcmd(0x01); //清除LCD的显示内容IE=0x8f; / /CPU开中断,INT0,INT1,开中断TR0=1;//Timer0启动}//主程序,初始化及初值设定void main(){lcd_init(); //初始化LCDlcd_sef_chr(); //写入自定义字符号hour=0;min=0;sec=0; //开机时的时,分,秒显示armhour=0;armmin=0;armsec=0; //开机时的时,分,秒报警初值year= 5; month=1;date=1; //开机时的年,月,日,星期显示week_proc();alarm=1; //初始开机,启用闹钟IE = 0x8f; //CPU开中断,INT0,INT1,Timer0,Timer1开中断IP = 0x04; //设置INT0为中断最高优先级IT0=0;IT1=0; //外部INT0,INT1设置为电平触发方式(注意,触发不要选边沿方式,易误动) TMOD = 0x11; //Timer0,Timer1工作于模式1, 16位定时方式TH0 = 0xdc;TL0 = 0x00; //Timer0置10ms定时初值TH1 = 0xff;TL1 = 0x00; //Timer1置初值TR0 = 1; //Timer0启动TR1 = 0;while(1);}//设置按键处理程序void pro_key(){switch (flag){case 0:alarm=!alarm; //启用或关闭闹钟(alarm=1:启用,alarm=0:关闭)update_disbuf(0x50,"alarm:",armhour,armmin,ar msec); //更新显示数据pro_display();//调用显示处理lcd_pos(0x47);break;//光标回到原调整位置case 1:armhour++;if (armhour>23) armhour=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec); //更新显示数据pro_display();//调用显示处理lcd_pos(0x49);break;//光标回到原调整位置case 2:armmin++;if (armmin>59) armmin=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec);pro_display();lcd_pos(0x4c);break;case 3:armsec++;if (armsec>59) armsec=0;update_disbuf(0x50,"alarm:",armhour,armmin,ar msec);pro_display();lcd_pos(0x4f);break;case 4:year++;if (year> 99) year= 0;week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x05);break;case 5:month++;if (month>12) month=1;week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x08);break;case 6:date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31) date=1; //大月31天if(month==4||month==6||month==9||month==11)if (date>30) date=1; //小月30天if (month==2){if(leap_year())//闰年的条件{if (date>29) date=1;} //闰年2月为29天else{if (date>28) date=1;}} //平年2月为28天week_proc();//星期自动运算update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x0b);break;case 7:hour++;if (hour>23) hour=0;update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x49);break;case 8:min++;if (min>59) min=0;update_disbuf(0x50,"time:",hour,min,sec);pro_display();lcd_pos(0x4c);break;case 9:sec++;if (sec>59) sec=0;update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x4f);break;default:break ;}}//Timer1中断处理程序,产生报警的声音void timer1() interrupt 3{TH1=0xff;TL1=0x00;SPK=~SPK;}//外部中断INT1中断处理程序,停止报警声音void int1() interrupt 2{if(TR1)TR1=0;}//DS1302时钟程序#include <stc89c52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/******************************************************************** ///少占鱼制作河北正定欢迎您长沙航空职业技术学院//2010 年QQ:411656434//版权所有:#define LCD1602_RS P2_5 //定义引脚#define LCD1602_RW P2_6#define LCD1602_E P2_7#define LCD1602_IO P0#define Busy 0x80 //用于检测LCD1602状态字中的Busy标识const uchar num[]=" 3456789+";uchar code a[] = {" E N v"};void WriteData(uchar DAT);void WriteCommand(uchar command,BuysC);uchar ReadData(void);void Readbusy(void);void LCD1602_Init(void);void DisplayOneChar(uchar X, uchar Y, uchar DData);void Displaystring(uchar X, uchar Y, uchar *DData);void Delay5Ms(void);void Delay400Ms(void);void delayms(uint);void delays(uint m) ;void delayus(uchar x) ;sbit DS1302_CLK =P2^0;// P1^0;sbit DS1302_IO =P2^1;// P1^1;sbit DS1302_RST =P2^2;// P1^2;uchar shuju;unsigned char time[]={0x11,0x03,0x28,0x01,0x12,0x39,0x00};// 初始化时间年月日星期时分秒uchar Display_Buffer[12]={"12:25:00"};//时、分、秒的格式uchar riqi[12]={"11-03-28"};//年、月、日的格式uchar xingqi[5]="week";//星期unsigned char second,minute,hour,week,day,month,year;/******************1602函数********************************//******************************************************************** /void delays(uint m){uint i,j;for(i=0;i<m;i++){for(j=0;j<1000;j++){;}}}void Delay(void){unsigned char i;unsigned int j;for(i=0;i<200;i++)for(j=300;j>0;j--);/******************************************************************** *********函数功能:向DS1302送一字节数据子程序入口参数:出口参数:********************************************************************* ********/void InputByte(unsigned char BYTE){char i;for(i=8;i>0;i--){ //前面在read_ds1302()函数里已经把CLK清0了DS1302_CLK=0;//这里再清0一次,看着清楚。