ds1302用12864显示
- 格式:docx
- 大小:16.96 KB
- 文档页数:6
以下是我写的12864LCD并行口时钟显示程序,时钟用按键可调/***************12864.h头文件******************************/#ifndef _12864_h#define _12864_h/*****包含头文件**************/#include<reg51.h>#include"string.h"#include"DS1302.h"/********定义I/0口**********/#define LCD12864_DATA P0sbit LCD12864_E = P2^7;sbit LCD12864_RW = P2^5;sbit LCD12864_RS = P2^6;sbit LCD12864_RET= P2^0;sbit LCD12864_PSB =P2^2;/******声明全局函数*********/void Delay1ms(unsigned int); //声明延时函数void BusyChk_12864(void); //声明忙检测函数void WrCom(unsigned char); //声明写入命令函数//unsigned char ReDat(void); //声明读数据函数void WrDat(unsigned char); //声明写数据函数void LcdInit(void); //12864初始化函数void SetAddress(unsigned char ,unsigned char); //设置地址转换void DisplayString(unsigned char ,unsigned char,unsigned char *p);//行显示字符void DisplayTime();void DisplayDay();void DisplayWeek();#endif/*****************************12864.c***********************************/#include"12864.h"/****************************************************************************** ** 函数名: Delay1ms* 函数功能: 延时函数,延时1ms* 输入: c* 输出 e : 无* 说名: 该函数是在12MHZ晶振下,12分频单片机的延时。
一.绪言1.在信息显示技术中,人们发现了信息数字化的重要作用和意义。
数字化的信息更加准确,同一性,更易传输和识别。
很多信息可以直接由数字表示,从而数字化信息显示又成为信息显示的又一个重要内容。
又从数字化显示发展到字符显示,它把人类特有的语言文字用于显示,这种显示与数字显示合在一起用途更广用量更大。
在这同时,人们还希望用图形和图像进行显示,且显示的内容为五彩缤纷,并且可以实时活动和具有三维立体效果。
这些在二十世纪尾声时都已经陆续实现。
LCD的计算机器,半导体发光数码管显示(LED)的汽车计价器,商场的大屏幕广告。
这零零总总的各类显示正为你做着各种各样的服务,相信在不久的将来显示技术的发展将会为人类做出更大的贡献。
Ds1302时钟芯片现在流行的串行时钟电路很多,如DS1302、 DS1307、PCF8485等。
这些电路的接口简单、价格低廉、使用方便,被广泛地采用。
本文介绍的实时时钟电路DS1302是DALLAS公司的一种具有涓细电流充电能力的电路,主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。
采用普通32.768kHz晶振。
(一)设计任务本课题采用ds1302的时钟芯片为主要的的设计来源,采用显示是1cd1602的图形点阵液晶显示。
,(二)提出方案及方案论证在设计中,我主要是考虑ds1302的时间显示问题,因为网上也有ds1302的读写和显示程序,但是至于怎样才能显示详细信息,我提出了两个方案,一个是LCD1602来显示,一个是LCD12864,其中1602是个字符型的点阵,而1CD12864是个图形的点阵,相比之下12864能够更好显示数据,而CPU都采用89C52的单片机(三)原理说明:原理其实很简单,LCD12864的各种指令先进行宏定义和ds1302的读写指令也进行宏定义,从ds1302的读出数据显示在lcd上(二)程序流程图(三)C51程序设计,重要的代码要有注释。
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{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)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
/****************************************************************************/ //头文件#include <AT89X52.h>#include <string.h>/*****************************************************************************/ //灯与蜂鸣器定义sbit led_b = P2^7;sbit led_r = P1^4;sbit led_g1 = P1^3;sbit led_g2 = P1^2;sbit led_g3 = P1^0;sbit led_g4 = P1^1;sbit beep = P3^1;/*****************************************************************************/ //温度传感器定义sbit DQ = P3 ^ 0;//ds18B20/*****************************************************************************/ //键盘引脚定义sbit KEY_1 = P2^3; //左上sbit KEY_2 = P2^4; //左下sbit KEY_3 = P2^6; //右上sbit KEY_4 = P2^5; //右下sbit KEY_I = P3^2; //常0/****************************************************************************/ //引脚定义sbit SID = P2^1; //数据sbit SCLK = P2^2; //时钟/*****************************************************************************/ //定义DS1302时钟接口sbit clock_clk = P3 ^ 5;//ds1302_clk(时钟线)sbit clock_dat = P3 ^ 4;//ds1302_dat(数据线)sbit clock_Rst = P3 ^ 3;//ds1302_Rst(复位线)/*****************************************************************************/ //定义累加器A中的各位sbit a0 = ACC ^ 0;sbit a1 = ACC ^ 1;sbit a2 = ACC ^ 2;sbit a3 = ACC ^ 3;sbit a4 = ACC ^ 4;sbit a5 = ACC ^ 5;sbit a6 = ACC ^ 6;sbit a7 = ACC ^ 7;/****************************************************************************/ //定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss;//定义时间映射全局变量(专用寄存器)bit w = 0; //调时标志位static unsigned char menu = 0;//定义静态小时更新用数据变量static unsigned char keys = 0;//定义静态小时更新用数据变量static unsigned char timecount = 0;//定义静态软件计数器变量/****************************************************************************/ void DelayM(unsigned int a){//延时函数1MS/次unsigned char i;while( --a != 0){for(i = 0; i < 125; i++); //一个; 表示空语句,CPU空转。
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{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)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
学士学位毕业论文(设计)题目:基于单片机的12864时钟显示摘要电子时钟是一种非常广泛日常计时工具,给人们的带来了很大的方便,在社会上越来越流行。
它可以对年、月、日、星期、时、分、秒进行计时,采用直观的数字显示,可以同时显示年月日时分秒等信息,还有时间校准等功能。
该电子时钟主要采用STC89C52单片机作为主控核心,用DS1302时钟芯片作为时钟、液晶12864显示屏显示。
STC89C52单片机是由深圳宏晶科技公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的12864液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒等信息。
此外,该电子时钟还具有时间校准等功能。
关键词:STC89C51单片机,DS1302时钟芯片,液晶12864AbstractElectronic clock is a very extensive daily timing tool, to the people has brought great convenience, more and more popular in the community. It can be the year, month, date, day, hour, minute, second for a time, using intuitive digital display, can display information such as year, month, day, hour, and time alignment functions. The electronic clock is used mainly as a master STC89C52 microcontroller core, with theDS1302 clock chip as a clock, LCD display12864. STC89C52 SCM is a Shenzhen Hong Crystal Technology has introduced, power consumption, voltage can be selected 4 ~ 6V voltage power supply; DS1302 clock chip is American DALLAS company launched with a fine current charging low-power real-time clock chip, it can year, month, date, day, hour, minute, second for a time, also has a leap year compensation and other functions, DS1302 and long life, small error; 12864 LCD digital display isused to display that can display year, month, date, day, hour, minute, second and so on. In addition, the electronic clock also has a time calibration function.Key Words:STC89C51 microcontroller, DS1302 clock chip, LCD 12864目录1绪论 (3)1.1时钟发展史 (3)1.2 目前的研究现状 (4)1.3研究目的及意义 (4)2 总体方案设计 (5)2.1 方案的选择 (5)2.1.1设计要求 (5)2.1.2方案的选择 (5)2.2总体方案组成框图 (6)3系统硬件设计 (6)3. 1主芯片模块 (6)3.1.1 中断系统 (8)3.1.2常用寄存器 (8)3.2晶振和复位电路 (10)3.2.1晶振电路 (10)3.2.2复位电路 (11)3.3 DS1302时钟芯片电路 (11)3.3.1 DS1302引脚图 (11)3.3.2 DS1302寄存器 (12)3.3.3 DS1302外围电路 (13)3.4 LCD12864显示模块 (13)3.4.1 LCD12864引脚功能 (13)3.4.2 LCD12864指令说明 (14)3.4.3 LCD12864电路接线 (15)3.5 红外遥控模块 (16)4 系统软件设计 (17)4.1 主程序设计 (17)4.2 LCD12864驱动程序 (19)4.3 DS1302驱动程序 (21)4.4 红外遥控程序 (24)5 调试结果 (25)5.1 正常显示日期时间画面 (26)5.2 进入调整时间日期画面 (26)5.3图片显示画面 (26)6总结 (27)致谢 (28)参考文献 (29)附录一 (31)附录二 (32)1绪论1.1时钟发展史很早以前,人类主要是利用天文现象和流动物质的连续运动来计时。
#include <REG51.H>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^0; //实时时钟时钟线引脚sbit DS1302_IO = P1^1; //实时时钟数据线引脚sbit DS1302_RST = P1^2; //实时时钟复位线引脚sbit DQ = P3^3; //温度传送数据IO口sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;uchar hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P1^4; //模式切换键对应实验板K5sbit Up = P1^5; //加法按钮对应实验板K6sbit Down= P1^6; //减法按钮对应实验板K7sbit out = P1^7; //立刻跳出调整模式按钮对应实验板K8uchar done,count,temp,up_flag,down_flag;uchar temp_value,temp1_value; //temp_value温度值正数部分temp1_value温度值小数部分uchar TempBuffer[8],week_value[3];void show_time(); //液晶显示程序//****************************************//12864液晶显示部分子程序模块//****************************************sbit rs = P2^0;sbit rw = P2^1;sbit e = P2^2;#define lcddata P0sbit busy=P0^7; //lcd busy bitvoid wr_d_lcd(uchar content);void wr_i_lcd(uchar content);void clrram_lcd (void);void init_lcd(void);void busy_lcd(void);void rev_row_lcd(uchar row);void rev_co_lcd(uchar row,uchar col,uchar mode);void clr_lcd(void);void wr_co_lcd(uchar row,uchar col,uchar lcddata1,uchar lcddtta2);void wr_row_lcd(uchar row,char *p);//**********************************//液晶初始化//**********************************void init_lcd(void){wr_i_lcd(0x06); /*光标的移动方向*/wr_i_lcd(0x0c); /*开显示,关游标*/ }//*********************************** //填充液晶DDRAM全为空格//********************************** void clrram_lcd (void){wr_i_lcd(0x30);wr_i_lcd(0x01);}//*********************************** //对液晶写数据//content为要写入的数据//*********************************** void wr_d_lcd(uchar content){busy_lcd();rs=1;rw=0;lcddata=content;e=1;;e=0;}//********************************//对液晶写指令//content为要写入的指令代码//*****************************void wr_i_lcd(uchar content){busy_lcd();rs=0;rw=0;lcddata=content;e=1;;e=0;}//********************************//液晶检测忙状态//在写入之前必须执行//******************************** void busy_lcd(void){lcddata=0xff;rs=0;rw=1;e =1;while(busy==1);e =0;}//********************************//指定要显示字符的坐标//*******************************void gotoxy(unsigned char y, unsigned char x) {if(y==1)wr_i_lcd(0x80|x);if(y==2)wr_i_lcd(0x90|x);if(y==3)wr_i_lcd((0x80|x)+8);if(y==4)wr_i_lcd((0x90|x)+8);}//********************************** //液晶显示字符串程序//********************************** void print(uchar *str){while(*str!='\0'){wr_d_lcd(*str);str++;}}//*********************************** //DS1302时钟部分子程序模块//*********************************** typedef struct __SYSTEMTIME__{uchar Second;uchar Minute;uchar Hour;uchar Week;uchar Day;uchar Month;uchar Year;uchar DateString[11];uchar TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME CurrentTime;#define AM(X) X#define PM(X) (X+12) // 转成24小时制#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84#define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C//**********************************//实时时钟写入一字节(内部函数)//**********************************void DS1302InputByte(uchar d){uchar i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC >> 1;}}//*************************************//实时时钟读取一字节(内部函数)//*************************************uchar DS1302OutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;}return(ACC);}//**************************************//ucAddr: DS1302地址, ucData: 要写的数据//**************************************void Write1302(uchar ucAddr, uchar ucDa){DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0;}//**************************************//读取DS1302某地址的数据//**************************************uchar Read1302(uchar ucAddr){uchar ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);}//******************************************//获取时钟芯片的时钟数据到自定义的结构型数组//******************************************void DS1302_GetTime(SYSTEMTIME *Time){uchar ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//转换为相应的10进制数ReadValue = Read1302(DS1302_MINUTE);Time->Minute = ((ReadV alue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time->Hour = ((ReadV alue&0x70)>>4)*10 + (ReadV alue&0x0F);ReadValue = Read1302(DS1302_DAY);Time->Day = ((ReadV alue&0x70)>>4)*10 + (ReadV alue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time->Week = ((ReadValue&0x10)>>4)*10 + (ReadV alue&0x0F);ReadValue = Read1302(DS1302_MONTH);Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time->Year = ((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F);}//******************************************//将时间年,月,日,星期数据转换成液//晶显示字符串,放到数组里DateString[]//******************************************void DateToStr(SYSTEMTIME *Time){uchartab[ ]={0XD2,0XBB,0XB6,0XFE,0XC8,0XFD,0XCB,0XC4,0XCE,0XE5,0XC1,0XF9,0XC8,0X D5};if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为2007/07/22{Time->DateString[0] = '2';Time->DateString[1] = '0';Time->DateString[2] = Time->Year/10 + '0';Time->DateString[3] = Time->Year%10 + '0';}else{Time->DateString[0] = ' ';Time->DateString[1] = ' ';Time->DateString[2] = ' ';Time->DateString[3] = ' ';}Time->DateString[4]='-';if(hide_month<2){Time->DateString[5] = Time->Month/10 + '0';Time->DateString[6] = Time->Month%10 + '0';}else{Time->DateString[5] = ' ';Time->DateString[6] = ' ';}Time->DateString[7]='-';if(hide_day<2){Time->DateString[8] = Time->Day/10 + '0';Time->DateString[9] = Time->Day%10 + '0';}else{Time->DateString[8] = ' ';Time->DateString[9] = ' ';}if(hide_week<2){week_value[0] =tab[2*(Time->Week%10)-2]; //星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示week_value[1] =tab[2*(Time->Week%10)-1];}else{week_value[0] = ' ';week_value[1]=' ';}week_value[2] = '\0';Time->DateString[10] = '\0'; //字符串末尾加'\0' ,判断结束字符}//******************************************//将时,分,秒数据转换成液晶//显示字符放到数组TimeString[]//*****************************************void TimeToStr(SYSTEMTIME *Time){ if(hide_hour<2){Time->TimeString[0] = Time->Hour/10 + '0';Time->TimeString[1] = Time->Hour%10 + '0';}else{Time->TimeString[0] = ' ';Time->TimeString[1] = ' ';}Time->TimeString[2] = ':';if(hide_min<2){Time->TimeString[3] = Time->Minute/10 + '0';Time->TimeString[4] = Time->Minute%10 + '0';}else{Time->TimeString[3] = ' ';Time->TimeString[4] = ' ';}Time->TimeString[5] = ':';if(hide_sec<2){Time->TimeString[6] = Time->Second/10 + '0';Time->TimeString[7] = Time->Second%10 + '0';}else{Time->TimeString[6] = ' ';Time->TimeString[7] = ' ';}Time->TimeString[8] = '\0';}//******************************//时钟芯片初始化//******************************void Initial_DS1302(void){uchar Second=Read1302(DS1302_SECOND);if(Second&0x80) //判断时钟芯片是否关闭{Write1302(0x8e,0x00); //写入允许Write1302(0x8c,0x07); //以下写入初始化时间日期:07/07/25.星期: 3. 时间: 23:59:55 Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}}//****************************************//ds18b20子程序模块//****************************************/***********ds18b20子程序*************************//***********ds18b20延迟子函数(晶振12MHz )*******/void delay_18B20(unsigned int i){while(i--);}/**********ds18b20初始化函数**********************/void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(40); //精确延时大于480usDQ = 1; //拉高总线delay_18B20(7);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(10);}/***********ds18b20读一个字节**************/uchar ReadOneChar(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/*************ds18b20写一个字节****************/void WriteOneChar(uchar dat){uchar i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;}}/**************读取ds18b20当前温度************/void ReadTemp(void){uchar a=0;uchar b=0;uchar t;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(50);a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位t=b&0xf8;if(t){TempBuffer[0]=':';TempBuffer[1]='-';temp_value=b<<4;temp_value+=(a&0xf0)>>4;temp_value=~temp_value+1;temp1_value=~a&0x0f;}else{temp_value=b<<4;temp_value+=(a&0xf0)>>4;temp1_value=a&0x0f;TempBuffer[0]=':';TempBuffer[1]=temp_value/100+'0'; //百位if(TempBuffer[1]=='1'){TempBuffer[1]='1';}else{TempBuffer[1]=' ';}}}void temp_to_str() //温度数据转换成液晶字符显示{TempBuffer[2]=temp_value%100/10+'0'; //十位TempBuffer[3]=temp_value%10+'0'; //个位TempBuffer[4]='.';TempBuffer[5]=temp1_value*625/1000%10+'0'; TempBuffer[6]=temp1_value*625/100%10+'0'; TempBuffer[7]=temp1_value*625/10%10+'0';//TempBuffer[8]=temp1_value*625%10+'0'; TempBuffer[8]='\0';}//********************************************** //延时子程序模块//********************************************** void mdelay(uint delay){ uint i;for(;delay>0;delay--){for(i=0;i<80;i++) //1ms延时.{;}}}//************************************************//按键设置程序模块//************************************************//************************************//跳出调整模式,返回默认显示//************************************void outkey(){ uchar Second;if(out==0){ mdelay(5);count=0;hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;}}//////////////////////////////////////////////////////////////////////////////////////////////////////////////*************************//升序按键//*************************void Upkey(){Up=1;if(Up==0){mdelay(5);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //秒数加1up_flag=1; //数据调整后更新标志if((temp)>59) //超过59秒,清零temp=0;temp=temp/10*16+temp%10;break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //分数加1up_flag=1;if(temp>59) //超过59分,清零temp=0;temp=temp/10*16+temp%10;break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //小时数加1up_flag=1;if(temp>23) //超过23小时,清零temp=0;temp=temp/10*16+temp%10;break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //星期数加1up_flag=1;if(temp>7)temp=1;temp=temp/10*16+temp%10;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //日数加1up_flag=1;if(temp>31)temp=1;temp=temp/10*16+temp%10;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp+1; //月数加1up_flag=1;if(temp>12)temp=1;temp=temp/10*16+temp%10;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=((temp&0xf0)>>4)*10 + (temp&0x0F);temp=temp+1; //年数加1up_flag=1;if(temp>99)temp=0;temp=temp/10*16+temp%10;break;default:break;}// while(Up==0);}}//////////////////////////////////////////////////////////////////////////////////////////////////////////////************************//降序按键//************************void Downkey(){Down=1;if(Down==0){mdelay(5);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //秒数减1down_flag=1; //数据调整后更新标志if(temp==-1) //小于0秒,返回59秒temp=59;temp=temp/10*16+temp%10;break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //分数减1down_flag=1;if(temp==-1)temp=59; //小于0秒,返回59秒temp=temp/10*16+temp%10;break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //小时数减1down_flag=1;if(temp==-1)temp=23;temp=temp/10*16+temp%10;break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数;temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //星期数减1down_flag=1;if(temp==0)temp=7;temp=temp/10*16+temp%10;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //日数减1down_flag=1;if(temp==0)temp=31;temp=temp/10*16+temp%10;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=((temp&0x70)>>4)*10 + (temp&0x0F);temp=temp-1; //月数减1down_flag=1;if(temp==0)temp=12;temp=temp/10*16+temp%10;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=((temp&0xf0)>>4)*10 + (temp&0x0F);temp=temp-1; //年数减1down_flag=1;if(temp==-1)temp=99;temp=temp/10*16+temp%10;break;default:break;}// while(Down==0);}}//**************************//模式选择按键//**************************void Setkey(){Set=1;if(Set==0){mdelay(5);count=count+1; //Setkey按一次,count就加1done=1; //进入调整模式while(Set==0);}}//*************************//按键功能执行//*************************void keydone(){ uchar Second;/* if(flag==0) //关闭时钟,停止计时{ Write1302(0x8e,0x00); //写入允许temp=Read1302(0x80);Write1302(0x80,temp|0x80);Write1302(0x8e,0x80); //禁止写入flag=1;}*/Setkey(); //扫描模式切换按键switch(count){case 1:do //count=1,调整秒{outkey(); //扫描跳出按钮Upkey(); //扫描加按钮Downkey(); //扫描减按钮if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据{Write1302(0x8e,0x00); //写入允许Write1302(0x80,temp); //写入新的秒数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_sec++;if(hide_sec>3)hide_sec=0;}else hide_sec=0;show_time(); //液晶显示数据}while(count==2);break;case 2:do //count=2,调整分{hide_sec=0;outkey();Upkey();Downkey();if(temp>0x60)temp=0;if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x82,temp); //写入新的分数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_min++;if(hide_min>3)hide_min=0;}else hide_min=0;show_time();}while(count==3);break;case 3:do //count=3,调整小时{hide_min=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x84,temp); //写入新的小时数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_hour++;if(hide_hour>3)hide_hour=0;}else hide_hour=0;show_time();}while(count==4);break;case 4:do //count=4,调整星期{hide_hour=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8a,temp); //写入新的星期数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_week++;if(hide_week>3)hide_week=0;}else hide_week=0;show_time();}while(count==5);break;case 5:do //count=5,调整日{hide_week=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x86,temp); //写入新的日数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_day++;if(hide_day>3)hide_day=0;}else hide_day=0;show_time();}while(count==6);break;case 6:do //count=6,调整月{hide_day=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x88,temp); //写入新的月数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_month++;if(hide_month>3)hide_month=0;}else hide_month=0;show_time();}while(count==7);break;case 7:do //count=7,调整年{hide_month=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8c,temp); //写入新的年数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}if(Down!=0&&Up!=0){hide_year++;if(hide_year>3)hide_year=0;}else hide_year=0;show_time();}while(count==8);break;case 8: count=0;hide_year=0; //count8, 跳出调整模式,返回默认显示状态Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;break; //count=7,开启中断,标志位置0并退出default:break;}}//***************************************//液晶显示主程序模块//***************************************void show_time(){DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据TimeToStr(&CurrentTime); //时间数据转换液晶字符DateToStr(&CurrentTime); //日期数据转换液晶字符ReadTemp(); //开启温度采集程序temp_to_str(); //温度数据转换成液晶字符gotoxy(4,0);print("温度");gotoxy(4,2); //液晶字符显示位置print(TempBuffer); //显示温度gotoxy(4,6);print("℃");gotoxy(3,0);print("时间:");gotoxy(3,3);print(CurrentTime.TimeString); //显示时间gotoxy(2,3);print(CurrentTime.DateString); //显示日期gotoxy(2,0);print("星期");gotoxy(2,2);print(week_value); //显示星期gotoxy(1,1);print("【锐志电子】");mdelay(500); //扫描延时}//************************************//主程序//*************************************main(){// flag=1; //时钟停止标志init_lcd();clrram_lcd();Init_DS18B20( ) ; //DS18B20初始化Initial_DS1302(); //时钟芯片初始化up_flag=0;down_flag=0;done=0; //进入默认液晶显示while(1){while(done==1)keydone(); //进入调整模式while(done==0){show_time(); //液晶显示数据// flag=0;Setkey(); //扫描各功能键}}}。
51单片机+带字库液晶12864+DS1302数字时钟C 源程序(无按键修改功 能)过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了 这个程序。
目前还不能修改时间与日期,只是以预定时间以始。
适用于开发板:51单片机(AT89S52 +带字库液晶12864(ST7920)+DS1302实时时钟)实现功能:简单,数字时钟 +日期(以后会不断完美)。
C 语言源程序如下:#include <reg52.h>#include <intrins.h> #define uchar unsigned char #define uint unsigned int /*DS1302 端 口设置 */sbit SCK=P3A 6;sbit SDA=P3A4;sbit RST = P3A5;bitReadRTC_Flag;/* 12864 端口定义 */ #define LCD_data P0 sbit LCD_RS = P2A4;sbit LCD_RW = P2A5; sbit LCD_EN = P2A 6;//液晶使能控制sbit PSB 二卩2八1; //并口控制 //DS1302 时钟 //DS1302 IO // DS1302 复位 //读DS1302全局变量//带字库液晶 12864数据口// 寄存器选择输入// 液晶读/写控制sbit RES=P2A3;uchar code dis1[] = {"电子设计天地"};// 液晶显示的汉字uchar code dis2[] = {"有志者,事竟成!"};uchar code dis4[] = {'0','1','2','3','4','5','6','7','8','9'};unsigned char temp;#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};void lcd_pos(uchar X,uchar Y); //确定显示位置unsigned char l_tmpdate[7]={0,7,16,19,10,1,9};〃秒分时日月周年09-10-19 16:07:00code unsigned charwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned charread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat );unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/*******************************************************************//**//* 延时函数 *//* *//******************************************************************* /void delay(unsigned int m) // 延时程序 {unsigned int i,j;for(i=0;i<m;i++)**************************************************//*检查LCD 忙状态*//*lcd_busy 为1时,忙,等待。
#include <reg52.h>
#include <intrins.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_data P0
#define DS1302_W_ADDR 0x80
#define DS1302_R_ADDR 0x81
sbit SCK = P3^6; //时钟
sbit SDA = P3^4; //数据
sbit RST = P3^5; //DS1302复位(片选)
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_EN=P1^2;
sbit LCD_PSB=P3^7;
uchar time[7]={50,59,23,15,8,7,10};//秒分时日月周年10-08-15 23:59:50 uchar flag;
uchar code table1[]="时分秒";
uchar code table2[]="星期";
uchar code table3[]="年月日";
void delay(uint n)
{
uint i,j;
for(i=1;i<n;i++)
for(j=1;j<110;j++);
}
void cmd(uchar cmd)
{
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
P0=cmd;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
void date(uint date)
{
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=date;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
void init()
{
LCD_PSB=1;
cmd(0x30);
delay(5);
cmd(0x0c);
delay(5);
cmd(0x01);
delay(5);
}
void write_ds1302_byte(uchar dat) {
uchar i;
for (i=0;i<8;i++)
{
SDA = dat & 0x01;
SCK = 1;
dat >>= 1;
SCK = 0;
}
}
/** * 读一个字节*/
uchar read_ds1302_byte(void)
{
uchar i,j, dat=0;
for (i=0;i<8;i++)
{
dat >>= 1;
if (SDA)
dat |= 0x80;
SCK = 1;
SCK = 0;
}
j=((dat&0xf0)>>4)*10+(dat&0x0f);
return j;
}
void reset_ds1302(void)
{
RST = 0;
SCK = 0;
RST = 1;
}
/** * 清除写保护*/
void clear_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0);
SDA = 0;
RST = 0;
}
/** * 设置写保护*/
void set_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x80);
SDA = 0;
RST = 0;
}
/** * 写入DS1302*/
void write_ds1302(uchar addr, uchar dat) {
reset_ds1302();
RST = 1;
write_ds1302_byte(addr);
write_ds1302_byte(dat);
SDA = 0;
RST = 0;
}
/** * 读出DS1302数据*/
uchar read_ds1302(uchar addr)
{
uchar temp=0;
reset_ds1302();
RST = 1;
write_ds1302_byte(addr);
temp = read_ds1302_byte();
SDA = 0;
RST = 0;
return (temp);
}
/** * 设定时钟数据*/
void set_time(uchar *timedata)
{
uchar i, tmp;
for (i=0; i<7; i++) // 转化为BCD格式
{
tmp = timedata[i] / 10;
timedata[i] = timedata[i] % 10;
timedata[i] = timedata[i] + tmp*16;
}
clear_ds1302_WP();
tmp = DS1302_W_ADDR; //传写地址
for (i=0; i<7; i++) //7次写入秒分时日月周年{
write_ds1302(tmp, timedata[i]);
tmp += 2;
}
set_ds1302_WP();
}
/** * 读时钟数据(BCD格式)*/
void read_time(uchar *timedata)
{
uchar i, tmp;
tmp = DS1302_R_ADDR;
for (i=0; i<7; i++) //分7次读取秒分时日月周年
{
timedata[i] = read_ds1302(tmp);
tmp += 2;
}
}
void display()
uchar num1,num2,num3,num4,num5,num6,i; num1=time[2]/10;
num2=time[2]%10;
num3=time[1]/10;
num4=time[1]%10;
num5=time[0]/10;
num6=time[0]%10;
cmd(0x98);
date(0x30+num1);
date(0x30+num2);
for(i=0;i<2;i++)
{date(table1[i]);}
date(0x30+num3);
date(0x30+num4);
for(i=2;i<4;i++)
{date(table1[i]);}
date(0x30+num5);
date(0x30+num6);
for(i=4;i<6;i++)
{date(table1[i]);}
}
void main()
{
init();
//set_time(&time); //设定时间值TMOD=0x01;
TH0=0xf5;
TL0=0xe0;
EA=1;
ET0=1;
TR0=1;
while(1)
{
if(flag==1)
{
flag=0;
read_time(&time);
display();
}
}
}
void T0_time() interrupt 1
TH0=0xf5;
TL0=0xe0;
flag=1;
}
/*剩下的星期,年月日,按键控制大家看懂了自己去做*/。