51单片机1302实时时钟1602显示程序
DS1302+LCD1602显示程序

/*头文件*/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define nop() _nop_()
sbit lcd_rs_port = P2^0; /*定义LCD控制端口*/
/****************************************************************
程序名称: LCD1602显示时间
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST = 0;
return(ucData);
uchar data time_data_buff[7]={0x00,0x00,0x09,0x01,0x01,0x04,0x09};/*格式为: 秒 分 时 日 月 星期 年 */
uchar data lcd1602_line1[]={" 2000/00/00 000"};
uchar data lcd1602_line2[]={" 00:00:00 "};
DS1302时钟芯片与液晶1602的程序

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(); //显示时间}}。
基于ds1302和LCD1602的日历时钟51单片机程序

#include <reg52.h>#include <intrins.h>#include <string.h>#define uint unsigned int#define uchar unsigned charsbit led = P2^3;//led代替闹铃sbit IO = P1^3; //定义1302管脚//6sbit SCLK = P1^4;//7sbit RST = P1^5; //5sbit RS = P2^2;//定义1602管脚sbit RW = P2^1;sbit EN = P2^0;sbit key1=P3^4;//选择//调时键盘sbit key2=P3^5;//加sbit key3=P3^6;//减sbit key4=P3^7;//确定sbit key11=P1^6;//选择//闹钟键盘sbit key22=P1^7;//加sbit key33=P3^0;//减sbit key44=P3^1;//确定uchar x1=0,x;int hour=8,minute=0;//闹钟的初始时间8:00uchar DateTime[9]; //秒,分,时,日,周,月,年 address,uchar lcd1[]={"DATE 00-00-00 "};uchar lcd2[]={"TIME 00:00:00 "};/***************延时*************/void delayms(uchar x)//延时毫秒程序{ uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void delayus(uchar x)//延时微秒程序{ uchar i;for(i=0;i<x;i++);}/********1302的驱动程序***********///写入数据,dat:要写入的数据void DS1302WriteByte(uchar dat){uchar i;SCLK=0;//初始时钟线置为0delayus(2);for(i=0;i<8;i++)//开始传输8个字节的数据{IO=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的delayus(2);SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输delayus(2);SCLK=0;//时钟线拉低,为下一个上升沿做准备dat>>=1;//数据右移一位,准备传输下一位数据}}/********1302的驱动程序**********///功能: 读取数据,dat:读取的数据uchar DS1302ReadByte(){ uchar i;uchar dat;delayus(2);for(i=0;i<8;i++){dat>>=1;//要返回的数据左移一位if(IO==1)//当数据线为高时,证明该位数据为1dat|=0x80;//要传输数据的当前值置为1,若不是,则为0SCLK=1;//拉高时钟线delayus(2);SCLK=0;//制造下降沿delayus(2);}return dat;//返回读取出的数据/16*10+dat%16}/*********1302的驱动程序*********///从cmd相应地址中读取一个字节的数据uchar DS1302Read(uchar cmd)//cmd:要写入的控制字节,dat:读取的数据{uchar dat;RST=0;//初始CE线置为0SCLK=0;//初始时钟线置为0RST=1;//初始CE置为1,传输开始DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址dat=DS1302ReadByte();//读取要得到的时间/日期SCLK=1;//时钟线拉高RST=0;//读取结束,CE置为0,结束数据的传输return dat;//返回得到的时间/日期}/**********1302的驱动程序*********///向cmd相应地址中写一个字节的数据void DS1302Write(uchar cmd, uint dat)//cmd:要写入的控制字,dat:要写入的数据{RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE置为1,传输开始DS1302WriteByte(cmd); //传输命令字,要写入的时间/日历地址DS1302WriteByte(dat); //写入要修改的时间/日期SCLK=1; //时钟线拉高RST=0; //读取结束,CE置为0,结束数据的传输}/*************初始化ds1302********///给1302写入日期和时钟的值void chushihuaDS1302(void){DS1302Write(0x8e,0x00);//写保护关DS1302Write(0x80,0x10); //初始秒DS1302Write(0x82,0x02);//初始分钟DS1302Write(0x84,0x15); //初始为24小时模式,初始时DS1302Write(0x86,0x01); //1日DS1302Write(0x88,0x08);//8月DS1302Write(0x8c,0x13);//2013年DS1302Write(0x8a,0x04);//星期4// DS1302Write(0x90,0x01); //充电//DS1302Write(0xc0,0xf0); //初始化一次标示//DS1302Write(0x8e,0x80);//写保护开}/************以下是1602的程序******************//******************************///向1602内写命令void write_order(uchar order){RS=0;P0=order;delayms(5);EN=1;delayms(5);EN=0;}/******************************///向1602内写数据void write_date(uchar date){RS=1;P0=date;delayms(5);EN=1;delayms(5);EN=0;}/******************************///lcd1602的初始化void chushihuaLCD1602(){ EN=0;write_order(0x38);write_order(0x0c);write_order(0x06);write_order(0x01);}/*************其他操作*****************/void gettime(){ uchar i,n;for(i=0,n=1;i<7,n<15;i++,n=n+2){ DateTime[i]=DS1302Read(0x80+n);delayus(1);}}void zhuanhuan(){ gettime();lcd1[5]=((DateTime[6]>>4)+0x30);lcd1[6]=((DateTime[6]&0x0f)+0x30);delayus(2);//年lcd1[14]=((DateTime[5]>>4)+0x30);lcd1[15]=((DateTime[5]&0x0f)+0x30);delayus(2);//周lcd1[11]=((DateTime[3]>>4)+0x30);lcd1[12]=((DateTime[3]&0x0f)+0x30);delayus(2);//日lcd1[8]=((DateTime[4]>>4)+0x30);lcd1[9]=((DateTime[4]&0x0f)+0x30);delayus(2);//月lcd2[5]=((DateTime[2]>>4)+0x30);lcd2[6]=((DateTime[2]&0x0f)+0x30);delayus(2);//时lcd2[8]=((DateTime[1]>>4)+0x30);lcd2[9]=((DateTime[1]&0x0f)+0x30);delayus(2);//分lcd2[11]=((DateTime[0]>>4)+0x30);lcd2[12]=((DateTime[0]&0x0f)+0x30);delayus(2);//秒if(DateTime[7]==DateTime[2] & DateTime[8]==DateTime[1]){led = 1;delayms(150);led = 0;}/**/}/***********************/void jianpan() //键盘调时{ uchar x2,address,max,min;int item;if(key1==0){ delayms(10);if(key1==0){ x1++;if(x1>=7) x1=1;switch(x1){ case 1: lcd2[15]='Y';x2=1;address=0x8c; max=99;min=0;break;//年case 2: lcd2[15]='M';x2=2;address=0x88; max=12;min=1;break;//月case 3: lcd2[15]='D';x2=3;address=0x86; max=31;min=1;break;//天case 4: lcd2[15]='H';x2=4;address=0x84; max=23;min=0;break;//时case 5: lcd2[15]='F';x2=5;address=0x82; max=59;min=0;break;//分case 6: lcd2[15]='W';x2=6;address=0x8A; max=7;min=1;break;//周}}while(!key1);}item=(DS1302Read(address+1)/16)*10 + (DS1302Read(address+1))%16;if(key2==0){ delayms(10);if(key2==0){ if(x2==1) {item++;}else if(x2==2) {item++;}else if(x2==3) {item++;}else if(x2==4) {item++;}else if(x2==5) {item++;}else if(x2==6) {item++;}}while(!key2);}if(key3==0){ delayms(10);if(key3==0){ if(x2==1) {item--;}else if(x2==2) {item--;}else if(x2==3) {item--;}else if(x2==4) {item--;}else if(x2==5) {item--;}else if(x2==6) {item--;}}while(!key3);}if(key4==0){ delayms(10);if(key4==0){ lcd2[15]=' ';x1=0;x2=0;}while(!key4);}//led=0;delayms(5000);led=1;if(item>max) item=min;if(item<min) item=max;DS1302Write(0x8e,0x00);//允许写操作delayms(10);DS1302Write(address,(item/10)*16+item%10); //写入DS1302 //转成BCD码delayms(20);DS1302Write(0x8e,0x80);//写保护,禁止写操作}void naozhong()//设定闹钟{ uchar da,xiao,i;if(key11==0){ delayms(10);if(key11==0){ x++;if(x>=4) x=1;switch(x){case 2: lcd2[13]='H';i=1;da=23;xiao=0;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);break;//时case 1: lcd2[13]='M';i=2;da=59;xiao=0;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);break;//分case 3: lcd2[13]=' ';lcd2[14]=' ';lcd2[15]=' ';x=0;i=0;break;}}while(!key11);}if(key22==0){ delayms(10);if(key22==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour++;if(hour>da) hour=xiao;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute++;if(minute>da) minute=xiao;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key22);}if(key33==0){ delayms(10);if(key33==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour--;if(hour<xiao) hour=da;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute--;if(minute<xiao) minute=da;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key33);}DateTime[7]=hour;DateTime[8]=minute;}/**/void wzd0() interrupt 0//外部中断0{jianpan();//}void wzd1() interrupt 2//外部中断1{naozhong();}void main(){uchar k;EA=1;EX0=1;IT0=1;PX0=1;EX1=1;IT1=1;PX1=0;RW=0;led=0;chushihuaLCD1602();if( (DS1302Read(0x81) & 0x80) ) chushihuaDS1302();//chushihuaDS1302();while(1){zhuanhuan();write_order(0x80);//lcd的第一行for(k=0;k<16;k++){ write_date(lcd1[k]);delayus(2);}write_order(0x80+0x40);//lcd的第二行for(k=0;k<16;k++){ write_date(lcd2[k]);delayus(2);}}}。
51单片机,DS1302时钟,1602显示,可调时钟剖析

基于proteus的51单片机仿真实例八十一、实时时钟芯片DS1302应用实例1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
2)X1、X2:振荡源,外接32.768kHz 晶振。
3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc>2.0V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
4)I/O为串行数据输入输出端(双向)。
5)SCLK为时钟输入端。
2、DS1302的控制字节DS1302 的控制字如下图所示。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
3、数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
DS1302的寄存器DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见数据手册。
DS1302实时时钟模块,1602显示

/******************* 说明:**************************将实时时钟数据通过LCD1602 显示基于51 单片机**************************************************/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int uchar dis_time_buf[16]={0};//LCD1602 引脚定义// 采用8 位并行方式,DB0~DB7 连接至LCDDATA0~LCDDATA7sbit RS=P2A0;sbit RW=P2A1;sbit CS=P2A2;#define LCDDATA P0//DS1302 引脚定义sbit RST=P1A3;sbit IO=P1A2;sbit SCK=P1A1;//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;RW=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, 表示在第一行显示,地址基数为0x80elseaddress=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*7dotsDelay_xms(5);Write_Instruction(0x38); Delay_xms(5);Write_Instruction(0x38);Write_Instruction(0x08); //关显示,不显光标,光标不闪烁 Write_Instruction(0x01); //清屏 Delay_xms(5);//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){Write_Instruction(0x04); // 写一字符,整屏显示不移动 // 关闭显示(不显示字符,只有背光亮) // 开显示,光标、闪烁都关闭// 开显示,不显示光标,但光标闪烁 // 开显示,显示光标,但光标不闪烁}//向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=O;〃停止 DS1302 总线}//从DS1302读出一字节数据uchar ds1302_read_byte(uchar addr) {uchar i,temp; RST=1;// 启动 DS1302 总线// 写入目标地址: addr addr = addr | 0x01;// 最低位置高,寄存器 0 位为 0 时写,为 1 时读for (i = 0; i < 8; i ++) {RST=0; SCK=0;//RST 脚置低 //SCK 脚置低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(8,0,dis_time_buf[4]+'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(6,1,dis_time_buf[10]+'0');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();}。
1602液晶显示DS1302实时时钟程序.

#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一次,看着清楚。
基于51单片机DS1302LCD1602数字时钟显示

#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="I LIKE MCU!";
sbit RS=P2^0;
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
uchar lcd_buffer2[]={"TIME 00:00:00 "};
uchar datetime[7];
void delay(uchar ms)
{
uchar i;
while(ms--)
for(i=0;i<120;i++);
}
//忙检测
uchar busy()
{
uchar test;
RW=1;
{
时钟DS1302在液晶1602显示程序

#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();}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
}
//判忙
void lcd_mang()
{
rs=0;
rw=1;
e=1;
_nop_();
_nop_();
_nop_();
_nop_();
while(P0&0x80);
e=0;
}
//1602的写
void write_lcd1602(uchar cmd,uchar i)
{
lcd_mang();
write_lcd1602(table[l_tmpdate[2]&0x0f],1);
write_lcd1602(':',1);
write_lcd1602(table[(l_tmpdate[1]>>4)&0x0f],1);
write_lcd1602(table[l_tmpdate[1]&0x0f],1);
void Read_RTC(void)//读取日历
{
unsigned char i,*p;
p=read_rtc_address;//地址传递
for(i=0;i<7;i++)//分7次读取秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************************/
/*设定时钟数据*/
/******************************************************************/
void Set_RTC(void)//设定日历
{
unsigned char i,*p,tmp;
for(i=0;i<7;i++){ //BCD处理
//l_tmpdate[7]用于初始值的设定,设定后,就不用每次上电再次修改了
unsigned char l_tmpdate[7]={0,17,19,16,3,6,12};//秒分时日月周年08-05-15 12:00:00 ,初值
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位
/*******************************************************************************
*标题:试验数码管显示时钟*
**
*通过本例程了解DS1302时钟芯片的基本原理和使用,理解并掌握DS1302时钟芯片*
*驱动程序的编写以及实现数字字符在数码管中的显示。*
void delay(uchar a);//1602分函数声明
void lcd_mang();
void write_lcd1602(uchar cmd,uchar i);
void ini_lcd1602();
/************************************************************
write_lcd1602('0',1);
write_lcd1602(table[(l_tmpdate[6]>>4)&0x0f],1);
write_lcd1602(table[l_tmpdate[6]&0x0f],1);
write_lcd1602('-',1);
write_lcd1602(table[(l_tmpdate[4]>>4)&0x0f],1);
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
while(1)
{
Read_RTC();
display();
}
}
/******************************************************************/
/*写一个字节*/
/******************************************************************/
write_lcd1602(':',1);
write_lcd1602(table[(l_tmpdate[0]>>4)&0x0f],1);
write_lcd1602(table[l_tmpdate[0]&0x0f],1);
}
//1602的初始化
void ini_lcd1602()
{
write_lcd1602(0x38,0);
temp>>=1;//右移一位
_nop_();
_nop_();
_nop_();
SCK=1;
}
RST=0;
_nop_();//以下为DS1302复位的稳定时间
_nop_();
RST=0;
SCK=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
*注意:JP1302跳线冒要短接。*
*请学员认真消化本例程,懂DS1302在C语言中的操作*
********************************************************************************/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
rs=i;
rw=0;
e=0;
_nop_();
_nop_();
e=1;
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
e=0;
}
void display(void)
{
write_lcd1602(0x80+0x01,0);
write_lcd1602('2',1);
/*主函数*/
/******************************************************************/
void main(void)
{
ini_lcd1602();// 1602初始化
Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽
RST=0;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
RST=1;
_nop_();
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++)//循环8次读取数据
{
if(SDA)
temp|=0x80;//每次传输低字节
SCK=0;
以下是1602显示模块
*************************************************************/
void delay(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
#define uint unsigned int
uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
uchar *p,TIM;
code unsigned char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
/******************************************************************/
/*函数声明*/
/******************************************************************/
void Write_Ds1302_byte(unsigned char temp);
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//注意,根据需要修改
sbit SCK=P1^0;//时钟
sbit SDA=P1^1;//数据
sbit RST = P1^2;// DS1302复位
write_lcd1602(table[l_tmpdate[4]&0x0f],1);
write_lcd1602('-',1);
write_lcd1602(table[(l_tmpdate[3]>>4)&0x0f],1);
write_lcd1602(table[l_tmpdate[3]&0x0f],1);