12864LCD万年历
- 格式:docx
- 大小:76.67 KB
- 文档页数:17
12864液晶万年历时钟改进版,代农历,24节气,生
肖,音乐)C51程序
此作品已发表在《无线电》2009年11期上
51单片机,内置汉字库12864液晶显示,4个按键,年,月,日,星期可调,代农历,温度,节日提示。
(生日等个人纪念提示需自己添加日期到程序,内置一首歌曲,可修改程序更改歌曲或添加多首歌曲)免费提供程序修改支持。
此宝贝与其他12864时钟有以下特点:
1,温度测量采用DS18B20,软件添加了负温度测量功能。
2,时钟采用DS1302,代3.6V电池,增加了秒可调功能,这样可使时间更精准。
3,增加了农历显示。
4,增加了播发歌曲功能,歌曲可以更改。
5,显示界面人性化,歌曲播放采用无源蜂鸣器,声音失真小.
对以上还有以下改进
对上次的电子时钟作来大量改进:
1,增加了生肖显示,
2,增加了24节气显示提醒
3,农历显示改成大写显示
4,丰富的节日提醒,包括了所有的,我国所有的农历节日,国际节日,国定节
日,
5,所有节日提醒和时辰提醒都在下边显示,当一天有多个节日,则在下边交替
显示,
6,你的亲人朋友的生日,纪念日都可以添加,如果与节日重合,则交替间隔1
秒显示。
感兴趣的朋友可以到这里:/auction/i ... b6a0c18efcc&;x_id=0db1
也可以加我QQ:379663387。
信息与电子工程学院《单片机技术应用实训》报告题目:电子万年历材料包括仿真图、PCB、软件、制作图片等具体可咨询T B “黎明电子ST YLE”时间:目录摘要 (1)一设计要求 (1)二芯片说明 (1)(1)STC89C52 (1)(2)DS1302 (3)(3)LED12864 (4)三系统组成 (5)四硬件单元电路设计 (6)(1)主控制模块 (6)(2)时钟振荡电路 (6)(3)蜂鸣器电路 (7)(4)按键电路 (7)(5)显示电路 (8)五系统软件 (9)六调试过程 (9)七总结 (10)参考文献: (11)摘要随着科技的快速发展,时间的流逝,至从观太阳、摆钟到现在电子钟,人类不断研究,不断创新纪录。
美国DALLAS公司推出的具有涓细电流充电能的低功耗实时时钟电路DS1302。
它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能该电路采用STC89C51单片机作为核心,功耗小,能在5V的低压工作,电压可选用3~5V电压供电。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪的发展趋势,具有广阔的市场前景。
本电路为实现电子万年历的功能,采用单片机STC89C51,辅助以必要的外围电路,用C语言编写程序,并进行模块化设计而成的电子万年历系统.它通过LCD能正确显示阳历星期和时分秒,温度等,具有功能稳定,精确度高和可调的特点。
关键词: 单片机;STC89C52;DS1302;1602LCD一设计要求利用STC89C52单片机设计一个具有如下功能的万年历:1、能够显示和更改年、月、日、时、分、秒、星期。
2、可设定指定日期、时间的闹钟。
3、可以显示和更改生肖。
4、能够显示温度。
二芯片说明(1)STC89C521.芯片介绍STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。
#include<reg52.H>#include<intrins.h>#include<math.h>////////////////////////////////////////DS18B20#define uchar unsigned char#define uint unsigned intsbit DQ = P1 ^ 0; // 定义DS18B20的单总线#define Lcd_Bus P0sbit LCD_RS=P2^7; //数据/命令选择sbit LCD_RW=P2^6; //读写控制sbit LCD_EN=P2^5; //片选信号#define LCD_DA TA P0 //8 bit数据线#define LOW 0#define HIGH 1//初始化指令#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H#define AC_INIT 0x02 //将AC设置为00H。
且游标移到原点位置#define CURSE_ADD 0x06 //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)#define FUN_MODE 0x30 //工作模式:8位基本指令集#define DISPLAY_ON 0x0c //显示开,显示游标,且游标位置反白#define DISPLAY_OFF 0x08 //显示关#define CURSE_DIR 0x14 //游标向右移动:AC=AC+1#define SET_CG_AC 0x40 //设置AC,范围为:00H~3FH#define SET_DD_AC 0x80#define FUN_MODEK 0x36 //扩展指令集,8位指令#define X1address 0x80 //上半屏X轴起始地址#define X2address 0x88 //下半屏X轴起始地址#define Y address 0x80 //Y轴起始地址#define Set_Column 0x40#define Set_Page 0xB8uchar code shu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};uchar code xingqi[]="星期";uchar code hanzishu[]="一二三四五六日";unsigned char TempData = 0;double DS18B20Data;uint jiemian=0;//////////////////////////////////////////DS1302sbit DS1302_RST = P1^4;sbit DS1302_IO = P1^3;sbit DS1302_SCK = P1^2;unsigned char table[]={0X00,0X18,0X0c,0X15,0X06,0X01,0X0a};//0s 24min 12hour 14ri 5yue 5zhou 2010nianunsigned char data table1[7];//uchar code table2[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};uchar code shuzi[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,};unsigned char aa,bb;uchar miaoge,miaoshi,fenge,fenshi,shige,shishi,rige,rishi,yuege,yueshi,zhou,niange,nianshi;uchar shezhinum=0;//unsigned char shi,ge;////////////////////////////////////////////////键盘扫描sbit key_mnue = P3^7;sbit key_jia = P2^0;sbit key_jian = P2^1;sbit key_enter= P2^2;uchar key_number=0;//int nian,yue,ri,shi,fen;/////////////////////////////////////////////////红外sbit HW_IRQ = P3 ^ 2; // 定义38KHz一体化红外接收头与CPU的连接unsigned char DT;static unsigned char data IRCode[3],IRCON,IRCON2;//////////////////////////////////////////////////蜂鸣器sbit BEEP =P1^1;/****************************************************************************** *************** 函数名称:DS18B20_Delay()* 功能:DS18B20软件延时专用* 入口参数:count 延时参数,值越大,延时越长* 出口参数:无******************************************************************************* **************/void DS18B20_Delay(uint count) //延时函数{while(count--);}/****************************************************************************** *************** 函数名称:DS18B20_Init()* 功能:DS18B20初始化* 入口参数:无* 出口参数:返回值为1则初始化成功* 返回值为0则初始化失败******************************************************************************* **************/uchar DS18B20_Init(void){uchar x = 0;DQ = 1; // DQ复位DS18B20_Delay(8); // 稍做延时DQ = 0; // 单片机将DQ拉低DS18B20_Delay(80); // 精确延时,大于480usDQ = 1; // 拉高总线DS18B20_Delay(14); // 稍做延时后x = DQ; // 若x=0则初始化成功,若x=1则初始化失败DS18B20_Delay(20);return (~x);}/****************************************************************************** *************** 函数名称:DS18B20_Read1Byte()* 功能:从DS18B20读一个字节* 入口参数:无* 出口参数:从DS18B20读出的一个字节******************************************************************************* **************/uchar DS18B20_Read1Byte(void){uchar i = 0;uchar dat = 0;for(i=8;i>0;i--){DQ = 0; // 给脉冲信号dat >>= 1;DQ = 1; // 给脉冲信号if(DQ) dat |= 0x80;DS18B20_Delay(4);}return (dat);}/****************************************************************************** *************** 函数名称:DS18B20_Write1Byte()* 功能:向DS18B20写一个字节* 入口参数:dat 要写入DS18B20的一字节数据* 出口参数:无******************************************************************************* **************/void DS18B20_Write1Byte(uchar dat){uchar i = 0;for(i=8;i>0;i--){DQ = 0;DQ = dat&0x01;DS18B20_Delay(5);DQ = 1;dat>>=1;}}/****************************************************************************** *************** 函数名称:Read_Disp_Temperature()* 功能:读取并显示温度* 入口参数:无* 出口参数:无******************************************************************************* **************/double Read_Disp_Temperature(void){uint a = 0, b = 0, c = 0,d = 0,e = 0, t = 0;double tt = 0;DS18B20_Init();DS18B20_Write1Byte(0xCC); // 跳过读序号列号的操作DS18B20_Write1Byte(0x44); // 启动温度转换DS18B20_Init();DS18B20_Write1Byte(0xCC); // 跳过读序号列号的操作DS18B20_Write1Byte(0xBE); // 读取温度寄存器a = DS18B20_Read1Byte();b = DS18B20_Read1Byte();t = b;t <<= 8;t = t | a;//tt = t * 0.0625;return t;}//***************************************************************** //函数名称:delay(uint t)延时函数。
51单片机做的12864万年历这是我花了一个星期时间做的万年历;一开始是一些图片,后面是这个制作的C语言源程序;希望大家稀饭:Main.c#include "reg52.h"#include "macroconst.h"#include "keyscan.h"#include "screen.h"#include "18b20.h"#include "ds1302.h"#include "atao_12864.h"#include "24c02.h"idata unsigned char state1[1];unsigned char screennum=1;//屏幕号#define time_task_sec 200 //节拍200Hz#define clock 24000000 //晶振#define max_task 4 //最大任务数idata unsigned char task_delay[4];#define task_delay0 time_task_sec/1 //2赫兹18b20 #define task_delay1 time_task_sec/5 //10赫兹屏幕#define task_delay2 time_task_sec/3 //4赫兹1302 #define task_delay3 time_task_sec/20 //20赫兹键盘void init(){unsigned char i;init18b20();ds1302_init();initina1(); //---------------------------LCD字库初始化程序RdFromROM(state1,8,1);state[0]=state1[0]; //-------界面RdFromROM(state1,15,1);state[1]=state1[0];//------- 闹钟RdFromROM(state1,11,1);key_sound=state1[0];//-------按键音// state[2]=state1[2];// state[3]=state1[3];screennum=1;//------默认一号屏for(i=0;i<max_task;i++)//清除任务延时{task_delay[i]=0;}TMOD=0x11;EA=1;TH0=255-clock/time_task_sec/12/526;TL0=255-clock/time_task_sec/12%526;ET0=1;TR0=1;}void main(){init();while(1){ if(task_delay[0]==0){readtemp(); task_delay[0]=task_delay0;} if(task_delay[3]==0){MenuCheckKey();task_delay[3]=task_delay1;}if(task_delay[1]==0){screen_select(screennum);task_delay[1]=task_delay1;} if(task_delay[2]==0){ds1302_read_time(); task_delay[2]=task_delay0;} }}void timer0() interrupt 1{uchar i=0;TH0=255-clock/time_task_sec/12/526;TH1=255-clock/time_task_sec/12%526;for(i=0;i<max_task;i++)if(task_delay[i]) task_delay[i]--; // miao=21,fen=33,xiaomiao=94;if(ma_start==1){tt++;if(tt==8){tt=0;xiaomiao++;if(xiaomiao==99){xiaomiao=0;miao++;if(miao==60){miao=0;fen++;if(fen==99){fen=0;}}}}}}Screen.c:#include "reg52.h"#include "macroconst.h"#include "delay.h"#include "18b20.h"#include "atao_12864.h"#include "ds1302.h"#include "24c02.h"#include "festival.h"#include "keyscan.h"idata unsigned char miao=0,fen=78,xiaomiao=0,tt=0;idata unsigned char bai,shi,ge,shinian,genian,shiyue,geyue,shiri,geri,shishi,geshi,shifen,gefen,shimi ao,gemiao;idata unsigned char Number[4];unsigned char code mainmenu[]={" 主菜单""3.查询 4.温度""1.调时 2.秒表""5.设置 6.返回"};unsigned char code setmenu[]={" 设置""3.查温 4.按键""1.界面 2.闹铃""5.报时 6.返回"};void gettime(){shinian=(time_buf1[1]%100)/10;genian=(time_buf1[1]%100)%10;shiyue=(time_buf1[2])/10;geyue=(time_buf1[2])%10;shiri=(time_buf1[3])/10;geri=(time_buf1[3])%10;shishi=(time_buf1[4])/10;geshi=(time_buf1[4])%10;shifen=(time_buf1[5])/10;gefen=(time_buf1[5])%10;shimiao=(time_buf1[6])/10;gemiao=(time_buf1[6])%10;}void screen_select(uchar num){// initina1();gettime() ;if(num==1) //----------主界面{Lcd_Set_Post(1,0);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);TransferData('/',1);TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);TransferData('/',1);TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);Lcd_Set_Post(1,4);if(state[1]==1)//----------------闹铃的状态图标{TransferData(' ',1);TransferData(14,1);}Lcd_Set_Post(1,5);if(key_sound==1){TransferData(13,1);}if(state[0]==0){Lcd_Set_Post(1,7); //----------------农历年nian(0);Lcd_Set_Post(2,0);//----------------------- 农历日月LCD_WRITE_CHAR("农历");Conversion(0,time_buf[1],time_buf[2],time_buf[3]);TransferData(month_moon/16+'0',1);TransferData(month_moon%16+'0',1);TransferData('/',1);TransferData(day_moon/16+'0',1);TransferData(day_moon%16+'0',1);}if(state[0]==1){Lcd_Set_Post(3,5);}else {Lcd_Set_Post(2,5);}LCD_WRITE_CHAR("星期");//----------------------星期if(time_buf1[7]==7) {LCD_WRITE_CHAR("日");}if(time_buf1[7]==6) {LCD_WRITE_CHAR("六");}if(time_buf1[7]==5) {LCD_WRITE_CHAR("五");}if(time_buf1[7]==4) {LCD_WRITE_CHAR("四");}if(time_buf1[7]==3) {LCD_WRITE_CHAR("三");}if(time_buf1[7]==2) {LCD_WRITE_CHAR("二");}if(time_buf1[7]==1) {LCD_WRITE_CHAR("一");}Lcd_Set_Post(3,0);TransferData(shishi+48,1);//----------------------时TransferData(geshi+48,1);TransferData(58,1);TransferData(shifen+48,1);//----------------------分TransferData(gefen+48,1);TransferData(58,1);TransferData(shimiao+48,1);//----------------------秒TransferData(gemiao+48,1);if(state[0]==0){bai=(temph/100); //---------------------------------温度shi=(temph%100)/10;ge=(temph%100)%10;Lcd_Set_Post(3,4);if(zerotemp==0){TransferData(' ',1);TransferData(' ',1);} Lcd_Set_Post(3,5);TransferData(shi+48,1);TransferData(ge+48,1);TransferData('.',1);TransferData(templ+48,1);TransferData(0xa1,1);TransferData(0xe6,1);Lcd_Set_Post(4,0);festival(time_buf[2],time_buf[3],time_buf[4]);//农历}}if(num==3)//----------主菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(mainmenu);}if(num==4)//----------设置菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(setmenu);}if(num==5)//----------时间设置{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("时间设置");Lcd_Set_Post(2,1);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);LCD_WRITE_CHAR("年");TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);LCD_WRITE_CHAR("月");TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);LCD_WRITE_CHAR("日");TransferData(time_buf1[7]+48,1);//---------------星期Lcd_Set_Post(3,2);TransferData(shishi+48,1);//--------------------时TransferData(geshi+48,1);LCD_WRITE_CHAR("时");TransferData(shifen+48,1);//---------------------分TransferData(gefen+48,1);LCD_WRITE_CHAR("分");TransferData(shimiao+48,1);//--------------------秒TransferData(gemiao+48,1);}if(num==6)//----------秒表{uchar shi1,shi2,shi3,ge1,ge2,ge3;Lcd_Set_Post(1,3);//--------设置显示位置LCD_WRITE_CHAR("秒表");Lcd_Set_Post(3,2);shi1=fen/10;ge1=fen%10;TransferData(shi1+48,1);TransferData(ge1+48,1);TransferData(':',1);shi2=miao/10;ge2=miao%10;TransferData(shi2+48,1);TransferData(ge2+48,1);TransferData(':',1);shi3=xiaomiao/10;ge3=xiaomiao%10;TransferData(shi3+48,1);TransferData(ge3+48,1);}if(num==8){Lcd_Set_Post(1,2);//--------农历查询LCD_WRITE_CHAR("温度查询");Lcd_Set_Post(3,0);//--------农历查询LCD_WRITE_CHAR("最高温度"); TransferData(':',1);RdFromROM(Number,0,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(3,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); Lcd_Set_Post(4,0);//--------农历查询LCD_WRITE_CHAR("最低温度"); TransferData(':',1);RdFromROM(Number,4,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(4,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); }if(num==9)//----------界面菜单{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("界面选择");Lcd_Set_Post(2,0);TransferData(1+48,1);TransferData('.',1);LCD_WRITE_CHAR("多功能界面");Lcd_Set_Post(3,0);TransferData(2+48,1);TransferData('.',1);LCD_WRITE_CHAR("简洁界面");}。
摘要:介绍利用单片机控制液晶显示模块显示电子万年历,给出硬件设计电路,和软件编程设计,通过Proteus软件,对硬件电路和软件编程进行仿真,具有一定的实用价值。
关键词:单片机液晶显示模块C51编程液晶显示模块在各种测量仪器、测量装置、显示仪表等日用电子产品中的应用越来越广泛,并且对器件的测量精度和显示精度的要求也越来越高,尤其是对时间的测量不但要准确,而且需要读取数值更直观更方便。
本文介绍由单片机AT89C52和DS1302控制12864点阵液晶显示模块实现电子万年历的设计,并且用Proteus软件对整个电路进行模拟和仿真。
1系统构成本系统设计中使用的单片机为AT89C52,其内部是8位的CPU,8KB片内ROM以及256B的可使用的片内RAM,32根并行I/O接口,两个16位的定时/计数器,五个中断源,两个中断优先级的内部结构。
其中单片机的外围电路有复位电路,时钟电路。
其次还用到美国DALLAS公司推出的高性能、低功耗、带RAM 的实时时钟电路DS1302,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
本系统里用12864LCD显示模块来显示万年历的年月日、星期及时间信息,该液晶模块使用KS0108控制器,5V电压驱动,带有背光,内置8192个16×16点阵,128个字符及64×128点阵显示RAM。
与外部CPU接口采用并行或者串行两种控制方式。
单片机在控制液晶显示模块的接口方式主要有两种方式,直接访问方式和间接访问方式,直接访问方式是把液晶显示模块作为存储器或I/O设备直接连接到单片机总线上。
而间接访问方式是把液晶显示模块作为终端与单片机的并行接口连接,而单片机通过对该并行接口的操作实现对液晶显示。
一般在进行液晶显示模块的控制时,采用间接访问的方式。
基于12864的万年历加温度显示设计摘要本设计将制作一种基于单片机控制的带实时温度显示、具有定时功能的电子万年历。
传统的电子日历大都体积大,功耗大,显示不准确等特点。
为了缩小体积,减小功耗,使其变得小巧灵敏,本设计加入了时钟芯片DS1302,可对时间进行准确记时,同时可设置定时时间,实现定时功能。
另外本设计具有显示实时温度的功能。
传统的温度传感器系统大都采用放大、调理、A/D转换,转换后的数字信号送入计算机处理,处理电路复杂、可靠性相对较差,占用计算机的资源比较多。
本设计将采用DS18B20一线制数字温度传感器,可将温度信号直接转换成数字信号送给微处理器,电路简单,成本低,实现了时间温度同时显示的效果。
最后,温度和时间都将通过12864液晶显示器进行显示。
测试表明系统达到了设计要求的各项功能,各部分工作正常。
关键词时钟/温度检测/单片机/温度MICROCONTROLLER-BASHED CALENDER AND TEMPERATURE DISPLAY DESIGNABSTRACTThis design creates an electronic calendar with real-time temperature display and timing function based on single chip control. Most of traditional calendars are characterized by large size, high power consumption and inaccurate display. In order to reduce volume and power consumption and make calendars become small and exquisite, the design adds a clock chip DS1302, which can accurately record the time and set a regular time to achieve timing function. In addition, this design displays real-time temperature function. Traditional temperature sensor system is mostly amplified, recuperated and A / D converted. The converted digital signal is input the computer to be processed, but the processing circuit is complicated with relatively poor reliability and occupies more resources of the computer. This design uses the DS18B20 first-line system digital temperature sensor to directly convert the temperature signal into digital signal and send it the microprocessor, whose circuit is simple and low cost, achieving the displayed effect of time and temperature simultaneously. Finally, the temperature and time will be displayed through the 12864 liquid crystal display. The test indicates that the system has reached various functions of the design requirements and each part operates smoothly.KEY WORDS clock, temperature detection, SCM, temperature目录中文摘要 (I)英文摘要.................................................................................................... I I 1概论. (1)1.1万年历发展背景 (1)1.2电子万年历的特点 (1)1.3国内外现状、发展 (1)2系统基本方案选择和论证 (2)2.1单片机芯片的选择方案和论证 (2)2.2显示模块的选择方案和论证 (3)2.3时钟芯片的选择方案和论证 (4)2.4温度传感器的选择方案和论证 (4)2.5电路设计最终方案确定 (5)3系统硬件电路设计 (6)3.1系统功能模块划分 (6)3.2各单元模块功能分析及模块电路设计 (6)3.2.1时钟模块 (6)3.2.2 温度模块 (7)3.2.3显示模块 (10)3.2.5 独立键盘模块 (18)3.2.6蜂鸣器模块 (19)3.2.7单片机模块 (20)3.3电路原理图的绘制和电路的焊接 (23)3.3.1原理图绘制软件PROTEL (23)3.3.2 PCB制作 (23)3.3.3 元器件的焊接 (24)4 系统软件设计 (26)4.1 万年历软件系统的流程图 (26)4.2温度信息的采集 (27)4.3时钟的读取 (30)4.3.1 DS1302控制字节的说明 (30)4.3.2 DS1302时间日期寄存器及相应位定义 (31)4.3.3 DS1302数据的输入和输出 (31)4.3.4 DS1302读写部分(程序)部分 (32)4.4温度的显示控制 (32)4.5键盘模块 (34)4.6蜂鸣器模块 (34)5设计总结 (35)致谢 (36)参考文献 (37)附录 (38)1 概论1.1 万年历发展背景随着电子技术的发展,人类不断研究,不断创新纪录。
12864、DS1302制作的电子万年历代码如下:/********************************************************************名称:电子万年历功能:自动计时100年,节日、时间提醒作者:甘春生实验板:KX-1N/******************************************************************** #include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FUN=P1^0;sbit OK=P1^1;sbit INC=P1^2;sbit DEC=P1^3;sbit RST=P2^5;sbit IO=P2^6;sbit SCLK=P2^7;uchar hour=10;uchar min=18;uchar sec=30;uchar year=10;uchar mon=1;uchar date=20;uchar day=3;uchar count=0;uchar flag=0;uchar num=0;uchar i=6;void delay(uint i){uint j;for(;i>0;i--)for(j=0;j<125;j++);}void Write_Ds1302_Byte(uchar temp){uchar i;for(i=0;i<8;i++)SCLK=0;IO=temp&0x01;//只传最后一位temp>>=1;SCL=1;}}void Write_Ds1302(uchar address,uchar dat) {RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);Write_Ds1302_Byte(dat);SCLK=1;RST=0;}uchar Read_Ds1302(uchar address){uchar i,temp=0x00;RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);for(i=0;i<8;i++){temp>>=1;SCLK=0;if(IO)temp=temp|0x80;SCLK=1;}RST=0;IO=0;return temp;}void Check_Busy(void){RW=1;//RW=1为读RS=0;//RS=0为指令EN=1;while(P2&0X80);}void Write_com(uchar com)Check_Busy();RW=0;RS=0;P2=com;EN=1;delay(1);EN=0;}void Write_dat(uchar dat){Check_Busy();RW=0;RS=1;P2=dat;EN=1;delay(1);EN=0;}void Lcd_Pos(uchar Xpos,uchar Ypos){uchar tmp;Xpos&=0x0f;Ypos&=0x03;tmp=Xpos;if(Ypos==0)tmp|=0x80;if(Ypos==1)tmp|=0x90;if(Ypos==2)tmp|=0x88;if(Ypos==3)tmp|=0x98;Write_com(tmp);}void Write_LCD_String(uchar x,uchar y,uchar *s) {Lcd_Pos(x,y);Lcd_Pos(x,y);while (*s!='\0'){Write_dat(*s);s++;delay(1);}void LCD_Rst(void){Write_com(0x30);Check_Busy();Write_com(0x01);Write_com(0x06);Write_com(0x0c);delay(5);}void Write_day(uchar Sel){switch (Sel){case 1:Write_LCD_String(6,1,"一");break;case 2:Write_LCD_String(6,1,"二");break;case 3:Lcd_Pos(6,1);Write_dat(0xc8);Write_dat(0xfd);break;case 4:Write_LCD_String(6,1,"四");break;case 5:Write_LCD_String(6,1,"五");break;case 6:Write_LCD_String(6,1,"六");break;case 7:Write_LCD_String(6,1,"日");break;default :break;}}void Updat_Time(void){Lcd_Pos(3,0);Write_dat(0x30+(year/10));Write_dat(0x30+(year%10)); Lcd_Pos(0,1);Write_dat(0x30+(mon/10));Write_dat(0x30+(mon%10)); Lcd_Pos(2,1);Write_dat(0x30+(date/10));Write_dat(0x30+(date%10)); Lcd_Pos(0,2);Write_dat(0x30+(hour/10));Write_dat(0x30+(hour%10)); Lcd_Pos(2,2);Write_dat(0x30+(min/10));Write_dat(0x30+(min%10)); Lcd_Pos(4,2);Write_dat(0x30+(sec/10));Write_dat(0x30+(sec%10)); Write_day(day);}void Write_Time(void){Write_Ds1302(0x8e,0x00);Write_Ds1302(0x8c,(year/10)*16+year%10);Write_Ds1302(0x88,(mon/10)*16+mon%10);Write_Ds1302(0x86,(date/10)*16+date%10);Write_Ds1302(0x84,(hour/10)*16+hour%10);Write_Ds1302(0x82,(min/10)*16+min%10);Write_Ds1302(0x80,(sec/10)*16+sec%10);Write_Ds1302(0x8a,(day/10)*16+day%10);Write_Ds1302(0x8e,0x80);}void Read_Time(void){year=(Read_Ds1302(0x8d)>>4)*10+Read_Ds1302(0x8d)%16; mon=(Read_Ds1302(0x89)>>4)*10+Read_Ds1302(0x89)%16; date=(Read_Ds1302(0x87)>>4)*10+Read_Ds1302(0x87)%16; hour=(Read_Ds1302(0x85)>>4)*10+Read_Ds1302(0x85)%16; min=(Read_Ds1302(0x83)>>4)*10+Read_Ds1302(0x83)%16; sec=(Read_Ds1302(0x81)>>4)*10+Read_Ds1302(0x81)%16; day=(Read_Ds1302(0x8b)>>4)*10+Read_Ds1302(0x8b)%16; Updat_Time();}void Set_Time(void){if(FUN==0){delay(10);if(FUN==0){while(!FUN);flag=1;num++;if(num==8)num=1;}}if(flag){if(num==1){Lcd_Pos(0,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);hour++;if(hour==24)hour=0;}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);hour--;if(hour==-1)hour=23;Updat_Time();}}}if(num==2){Lcd_Pos(2,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);min++;if(min==60)min=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);min--;if(min==-1)min=59;}}}if(num==3){Lcd_Pos(4,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);sec++;if(sec==60)sec=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);sec--;if(sec==-1)sec=59;Updat_Time();}}}if(num==4){Lcd_Pos(3,0);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);year++;year=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);year--;if(year==-1)sec=99;Updat_Time();}}}if(num==5){Lcd_Pos(0,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);mon++;if(mon==13)mon=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);mon--;if(mon==0)mon=12;Updat_Time();}}}if(num==6){Lcd_Pos(2,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);date++;if(date==32)date=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);date--;if(date==0)date=31;Updat_Time();}}}if(num==7){Lcd_Pos(6,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);day++;if(day==8)day=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);day--;if(day==0)day=7;Updat_Time();}}}}if(OK==0){delay(10);if(OK==0){while(!OK);flag=0;num=0;Write_com(0x0c);Write_Time();}}}void Festival(void){if (mon == 1 && date== 1 ) { Write_LCD_String(0,3,"Happy New Year!!"); } elseif (mon == 1 && date== 28 ) { Write_LCD_String(0,3," 世界麻风日"); } elseif (mon == 2 && date== 2 ) { Write_LCD_String(0,3," 世界湿地日"); } elseif (mon == 2 && date== 13 ) { Write_LCD_String(0,3," 明天情人节了"); } elseif (mon == 2 && date== 14 ) { Write_LCD_String(0,3," 今天是情人节"); } elseif (mon == 3 && date== 1 ) { Write_LCD_String(0,3," 国际海豹日"); }elseif (mon == 3 && date== 3 ) { Write_LCD_String(0,3," 全国爱耳日"); } elseif (mon == 3 && date== 8 ) { Write_LCD_String(0,3," 3.8妇女节"); } elseif (mon == 3 && date== 12 ) { Write_LCD_String(0,3," 植树节"); } elseif (mon == 3 && date== 14 ) { Write_LCD_String(0,3," 国际警察日"); } elseif (mon == 3 && date== 15 ) { Write_LCD_String(0,3," 消费者权益日"); } elseif (mon == 3 && date== 17 ) { Write_LCD_String(0,3," 国际航海日"); } elseif (mon == 3 && date== 21 ) { Write_LCD_String(0,3," 世界森林日"); } elseif (mon == 3 && date== 22 ) { Write_LCD_String(0,3," 世界水日"); } elseif (mon == 3 && date== 23 ) { Write_LCD_String(0,3," 世界气象日"); } elseif (mon == 3 && date== 24 ) { Write_LCD_String(0,3,"世界防治结核病日"); } elseif (mon == 4 && date== 1 ) { Write_LCD_String(0,3,"愚人节小心上当"); } elseif (mon == 4 && date== 7 ) { Write_LCD_String(0,3," 世界卫生日"); } elseif (mon == 4 && date== 8 ) { Write_LCD_String(0,3," 复活节"); } elseif (mon == 4 && date== 13 ) { Write_LCD_String(0,3," 黑色星期五"); } elseif (mon == 5 && date== 1 ) { Write_LCD_String(0,3," 劳动节放假"); } elseif (mon == 5 && date== 4 ) { Write_LCD_String(0,3," 青年节"); } elseif (mon == 5 && date== 8 ) { Write_LCD_String(0,3," 世界红十字日"); } elseif (mon == 5 && date== 12 ) { Write_LCD_String(0,3," 国际护士节"); } elseif (mon == 5 && date== 5 ) { Write_LCD_String(0,3,"近日注意母亲节"); } // &nb, , , , , sp;elseif (mon == 5 && date== 15 ) { Write_LCD_String(0,3," 国际家庭日"); } elseif (mon == 5 && date== 31 ) { Write_LCD_String(0,3," 世界无烟日"); } elseelseif (mon == 6 && date== 5 ) { Write_LCD_String(0,3," 世界环境日"); } elseif (mon == 6 && date== 26 ) { Write_LCD_String(0,3," 国际禁毒日"); } elseif (mon == 6 && date== 6 ) { Write_LCD_String(0,3," 全国爱眼日"); } elseif (mon == 6 && date== 13 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 6 && date== 15 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 7 && date== 1 ) { Write_LCD_String(0,3,"香港回归记念日"); } elseif (mon == 7 && date== 7 ) { Write_LCD_String(0,3,"抗日战争记念日"); } elseif (mon == 7 && date== 11 ) { Write_LCD_String(0,3," 世界人口日"); } elseif (mon == 8 && date== 1 ) { Write_LCD_String(0,3," 八一建军节"); } elseif (mon == 8 && date== 8 ) { Write_LCD_String(0,3," 中国男子节"); } elseif (mon == 8 && date== 15 ) { Write_LCD_String(0,3,"抗战胜利记念日"); } elseif (mon == 9 && date== 10 ) { Write_LCD_String(0,3," 中国教师节"); } elseif (mon == 9 && date== 18 ) { Write_LCD_String(0,3,"九·一八事变记念"); } elseif (mon == 9 && date== 20 ) { Write_LCD_String(0,3," 国际爱牙日"); } elseif (mon == 9 && date== 27 ) { Write_LCD_String(0,3," 世界旅游日"); } elseif (mon == 10 && date== 1 ) { Write_LCD_String(0,3," 中国国庆节"); } elseif (mon == 10 && date== 4 ) { Write_LCD_String(0,3," 世界动物日"); } elseif (mon == 10 && date== 24 ){ Write_LCD_String(0,3," 联合国日"); } elseif (mon == 10 && date== 12 ){ Write_LCD_String(0,3,"明天国际教师节"); } elseif (mon == 10 && date== 13 ){ Write_LCD_String(0,3," 国际教师节"); } elseif (mon == 11 && date== 10 ){ Write_LCD_String(0,3," 世界青年节"); } elseelseif (mon == 12 && date== 1 ) { Write_LCD_String(0,3," 世界艾滋病日"); } elseif (mon == 12 && date== 23 ){ Write_LCD_String(0,3," 明晚平安夜"); }elseif (mon == 12 && date== 24 ){ Write_LCD_String(0,3," 今晚平安夜"); }elseif (mon == 12 && date== 25 ){ Write_LCD_String(0,3," 圣诞快乐"); }elseif (mon == 12 && date== 31 ){ Write_LCD_String(0,3," 明日新年"); }else{if(hour >= 4 && hour< 6 ) { Write_LCD_String(0,3,"★★__▲▲__凌晨"); } if(hour >= 6 && hour< 8 ) { Write_LCD_String(0,3,"☆○__▲△__早晨"); } if(hour >= 8 && hour< 12 ) { Write_LCD_String(0,3,"__●__▲▲__上午"); } if(hour == 12) { Write_LCD_String(0,3,"____▲●▲__中午"); }if(hour >= 13 && hour< 18 ){ Write_LCD_String(0,3,"__▲▲__●__下午"); } if(hour >= 18 && hour< 22 ){ Write_LCD_String(0,3,"△▲__●☆__晚上"); } if(hour >= 22 && hour<= 23 ){ Write_LCD_String(0,3,"△▲__★☆__夜里"); } if(hour >= 0 && hour< 4 ) { Write_LCD_String(0,3,"__★▲▲★__深夜"); } }}void System_Init(void){LCD_Rst();Write_LCD_String(0,1,"系统初始化");Lcd_Pos(5,1);while(i--){Write_dat(0x3e);delay(300);}Write_com(0x01);Write_LCD_String(0,1,"您好!欢迎使用!");delay(1500);Write_com(0x01);Write_LCD_String(2,0,"2010年");Write_LCD_String(0,1,"01月18日星期一");Write_LCD_String(0,2,"10时17分30秒");}void main(void){System_Init();Write_Time(); while(1){Set_Time();if(!flag){Read_Time();Festival();}}}。
基于单片机和12864LCD模块的万年历设计与仿真作者:陈红李玮来源:《中小企业管理与科技·上旬刊》2011年第12期摘要:介绍利用单片机控制液晶显示模块显示电子万年历,给出硬件设计电路,和软件编程设计,通过Proteus软件,对硬件电路和软件编程进行仿真,具有一定的实用价值。
关键词:单片机液晶显示模块 C51编程液晶显示模块在各种测量仪器、测量装置、显示仪表等日用电子产品中的应用越来越广泛,并且对器件的测量精度和显示精度的要求也越来越高,尤其是对时间的测量不但要准确,而且需要读取数值更直观更方便。
本文介绍由单片机AT89C52和DS1302控制12864点阵液晶显示模块实现电子万年历的设计,并且用Proteus软件对整个电路进行模拟和仿真。
1 系统构成本系统设计中使用的单片机为AT89C52,其内部是8位的CPU,8KB片内ROM以及256B的可使用的片内RAM,32根并行I/O接口,两个16位的定时/计数器,五个中断源,两个中断优先级的内部结构。
其中单片机的外围电路有复位电路,时钟电路。
其次还用到美国DALLAS公司推出的高性能、低功耗、带RAM的实时时钟电路DS1302,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
本系统里用12864LCD显示模块来显示万年历的年月日、星期及时间信息,该液晶模块使用KS0108控制器,5V电压驱动,带有背光,内置8192个16×16点阵,128个字符及64×128点阵显示RAM。
与外部CPU接口采用并行或者串行两种控制方式。
单片机在控制液晶显示模块的接口方式主要有两种方式,直接访问方式和间接访问方式,直接访问方式是把液晶显示模块作为存储器或I/O设备直接连接到单片机总线上。
而间接访问方式是把液晶显示模块作为终端与单片机的并行接口连接,而单片机通过对该并行接口的操作实现对液晶显示。
课程设计报告题目多功能数字钟课程名称电子系统设计与工程实践院部名称电子与信息工程学院专业电子信息工程班级电子1001班学生姓名李盖(1010910101)指导教师荣峰多功能数字钟完成人:李盖(电子1001)摘要:随着人类科技文明的发展,人们对于时钟的要求在不断地提高。
时钟已不仅仅被看成一种用来显示时间的工具,在很多实际应用中它还需要能够实现更多其它的功能。
高精度、多功能、小体积、低功耗,是现代时钟发展的趋势。
在此次设计中,电路具有显示时间的其本功能,还可以实现对时间的调整。
具有小巧,价格低廉,走时精度高,使用方便,功能多等特点。
本设计的控制核心是单片机(STC90C516RD+),采用蜂鸣器、液晶显示器(LCD12864)、及其他电路构成。
实现了时间设置、闹铃设置、闹铃开和关、显示节日、显示生日、显示农历、生日时播放音乐、整点报时以及温度采集等功能。
关键词:多功能时钟,温度采集,闹铃,农历,显示节日1、设计要求1.利用LCD显示“年、月、日、星期、时、分、秒”信息,并可通过键盘修改当前时间。
2.具有闹钟时间设置和闹铃功能,利用蜂鸣器进行闹铃。
当闹铃发生时,能够通过按键取消闹铃。
3.利用温度传感器检测环境温度,并显示在LCD上。
2、总体设计2.1系统组成系统由单片机主控模块、时钟模块、测温模块、报警模块、显示模块、键盘接口模块共6个模块组成,电路系统框图下图所示:图1 系统框图2.2工作原理本设计核心器件之一时钟芯片DS1302,其主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。
采用普通32.768KHz晶振。
采用STC90C51作为主控芯片,利用它定期的读取时钟芯片DS1302中的时间并显示在LCD上;通过算法得出阴历日期并显示在LCD 上。
2.3用户至上的设计通过合理的布局,将键盘设置在LCD屏的下方,方便操作;其他的元路隐藏在LCD的后面使外观整洁简约。
从硬件连接开始,这台电子钟由三大部分组成:控制板,主板和显示板。
由于刚开始是做串口通信的,但是没有成功后来改成并口通信,所以板上比电路图上多了一只LED。
控制板通过排针与主板连接为了加固,主板用了两张万能板叠在一起,因为是做串口通信时拍的,所以还有一些痕迹。
比如蜂鸣器(在V2.1版本中都用小喇叭了)。
还有就是那两根天线,可不是用来接收信号的哦,先卖一下关子,看到后面你就明白了。
焊接中的主板长度太长的走线就用跳线,节约锡丝。
主板快要焊接完毕了主板与控制板组合在一起了图中两个2P的插座分加是接喇叭和后备电池的。
主板制作完毕显示板开工了,同样使用了两张万能板。
你要问那八只铜柱是做什么用的啊,接着往下看。
显示板背后的走线128*64液晶屏,内置汉字库。
显示板通过排线与主板连接整机图,这下知道那两根天线和八只铜柱是用来干什么用的了吧。
从这边看看再从后面看看折叠起来了效果图把程序烧录进AT89S52后试机,刚开始只有背光灯亮,按按键喇叭有相应的声音发出,说明程序正常运行了,判断是显示板的问题。
后来尝试把液晶屏的V0端接上5V的高电平后显示正常了。
资料上说的这只引脚是LCD偏压输入(一般悬空),不得其解,还望有高手不吝赐教。
附上液晶模资料:该显示模块是128*64点阵的汉字图形型液晶显示模块,可显示汉字及图形,内置国标GB2312码简体中文字库(16*16点阵),128个字符(8*16点阵)及64*256点阵显示RAM(GDRAM),可与CPU 直接接口,提供两种方式来连接CPU:8位并行及串行两种连接方式。
引脚说明:1. VSS 电源负极2. VDD 电源正极(+5V)3. V0 LCD偏压输入(悬空)4. RS(CS)数据/命令选择端(片选信号输入)5. R/W(SID)读/写控制信号(串行数据输入)6. E(SCLK)使能信号(串行移位脉冲输入)7. D0 数据08. D1 数据19. D2 数据210.D3 数据311.D4 数据412.D5 数据513.D6 数据614.D7 数据715.PSB 模式选择(H并行,L串行)16.NC 空脚17./RST 复位端(L复位)18.NC 空脚19.LED+ 背光源正极20.LED- 背光源负极。
简易12684液晶和Atmega32的电子万年历
闲来无事,又逢刮风下雨,把以前买来驱动一下就扔一边的12864液晶做
个小万年历。
哈哈……房间真差个钟~所用的原件不多:1.Atmega32单片机一
个(其实At89s51足够,手头Atmega32最多,所以高成本一下吧)2.晶振,电
容22pF3.7805,电容470uF,104若干,DC2.1电源插头。
4.DS1302,32768Hz 晶振,2012电池(座)(其他的电源都行,用作备用电源)5.12864液晶,带背光。
6.万用板一块。
先上图吧:
液晶背面就是主板了,这样结构容易站立。
也挺美观。
再来一张,关灯的效果,看上去很幽暗恐怖……:
以下是程序(包括了DS1302驱动和12864液晶驱动)tips:感谢大家的阅读,
本文由我司收集整编。
仅供参阅!。
*********************************#include<>#include<>#define LCD_Data P0#define uchar unsigned charunsigned charsec,min,hour,day,month,year,cen,week, next,aa,bb,cc,dd,mm,temp0,LunarMonth, LunarDay,LunarYear;int temp;uchar tt=1;bit c_moon;bit cenbit=1;bit w;sbit LCD_RS=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;sbit PSB=P2^3;sbit DS1302_CLK=P3^7;sbit DS1302_IO=P3^6;sbit DS1302_RST=P3^5;sbit DS18B20=P2^5;sbit speak=P2^7;sbit SetKey=P1^4; // 按键功能:设置sbit SureKey=P1^5; // 按键功能:确认sbit PlusKey=P1^6; // 按键功能:加sbit ReduceKey=P1^7; // 按键功能:减sbit scl=P1^1;sbit sda=P1^0;void DisplayShengXiao(void);void delay(unsigned int a)// 延时 1MS/ 次{unsigned char i;while(--a){for(i=0;i<125;i++) ;}}void delayb(unsigned int count){while(count--);}void delays(){ ; ;}void start(){sda=1;scl=1;delays();sda=0;delays();}void stop(){sda=0;scl=1;delays();sda=1;delays();}void response(){uchar i;while((sda==1)&&i<255)i++; //给应答信号 sda=0 ;错误( while (( sda==0 )|i<255 ) i++ ;)程序进入 while 死循环scl=1;delays();scl=0; // 没有这一步出错,如果没有 sda 将保持 0 状态,一直处于应答中。
12864LCD+DS1302万年历设计proteus仿真(2011-05-18 23:09:40)标签:it原理图程序代码//DS1302与12864设计的可调式电子日历与时钟//#include<reg51.h>#include<intrins.h>#include<string.h>#define uchar unsigned char#define uint unsigned intextern void LCD_Initialize();extern void Display_A_Char_8x16(ucharP,ucharL,uchar *M)reentrant; extern void Display_A_WORD(ucharP,ucharL,uchar *M)reentrant;//在调整日期时间时,用该位决定是否反白显示//extern bit Reverse_Display;sbit SDA =P1^0; //DS1302数据线sbit CLK =P1^1; //DS1302时钟线sbit RST =P1^2; //DS1302复位线sbit K1 =P3^4; //选择sbit K2 =P3^5; //加sbit K3 =P3^6; //减sbit K4 =P3^7; //确定uchartCount =0;//一年中每月的天数,2月的天数由年份决定ucharMonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};//所读取的日期时间ucharDateTime[7];//当前调整的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)//5对应星期,星期调节由年月日调整自动完成char Adjust_Index=-1;//水平与垂直偏移ucharH_Offset=10,V_Page_Offset=0;//年月日,星期,时分秒汉字点阵(16*16)------uchar code DATE_TIME_WORDS[]={//0x40,0x20,0x10,0x0C,0xE3,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x02,0x00,0x00, 0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00, //0x00,0x00,0x00,0x00,0x00,0xFF,0x11,0x11,0x11,0x11,0x11,0xFF,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x01,0x21,0x41,0x3F,0x00,0x00,0x00,0x00,//0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00,//0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00, 0x00,0x48,0x46,0x41,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00,//0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00,//0x00,0xFC,0x44,0x44,0x44,0xFC,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00,0x00,0x07,0x04,0x04,0x04,0x07,0x00,0x00,0x03,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,//0x80,0x40,0x20,0x98,0x87,0x82,0x80,0x80,0x83,0x84,0x98,0x30,0x60,0xC0,0x40,0x00,0x00,0x80,0x40,0x20,0x10,0x0F,0x00,0x00,0x20,0x40,0x3F,0x00,0x00,0x00,0x00,0x00,//0x12,0x12,0xD2,0xFE,0x91,0x11,0xC0,0x38,0x10,0x00,0xFF,0x00,0x08,0x10,0x60,0x00,0x04,0x03,0x00,0xFF,0x00,0x83,0x80,0x40,0x40,0x20,0x23,0x10,0x08,0x04,0x03,0x00,//0x00,0x02,0x02,0xF2,0x12,0x12,0x12,0x12,0xF2,0x02,0x02,0x02,0xFE,0x02,0x02,0x00, 0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x07,0x10,0x20,0x40,0x3F,0x00,0x00,0x00,//0x20,0x21,0xEE,0x04,0x00,0x00,0xFF,0x29,0xA9,0xBF,0xA9,0xA9,0x01,0xFF,0x00,0x00, 0x00,0x00,0x1F,0x88,0x44,0x30,0x0F,0x00,0x0F,0x04,0x04,0x4F,0x80,0x7F,0x00,0x00,//0x00,0x02,0x02,0x02,0x02,0x82,0x7E,0x22,0x22,0x22,0x22,0xF2,0x22,0x02,0x02,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x20,0x60,0x20,0x1F,0x00,0x00,0x00,0x00,//0x00,0x00,0xFE,0x02,0x22,0x22,0x22,0x22,0xFA,0x22,0x22,0x22,0xE2,0x02,0x02,0x00, 0x40,0x30,0x0F,0x00,0x40,0x20,0x18,0x06,0x01,0x00,0x20,0x60,0x3F,0x00,0x00,0x00,//0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00,0x00, 0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00,//0x42,0x42,0xFE,0x42,0x42,0xE0,0x00,0xFF,0x00,0x42,0x42,0xFE,0x42,0x42,0x42,0x00, 0x10,0x10,0x0F,0x88,0x49,0x20,0x18,0x07,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x00,//0x00,0xFE,0x22,0x52,0x8E,0x00,0xC4,0xB4,0x8C,0xE7,0x84,0x84,0x84,0x84,0x04,0x00, 0x00,0xFF,0x02,0x04,0x23,0x10,0x0C,0x40,0x80,0x7F,0x00,0x02,0x04,0x18,0x30,0x00,/0x00,0x10,0x10,0x92,0x72,0xA2,0xA2,0xF2,0xAA,0xAA,0x66,0xA2,0x12,0x18,0x00,0x00, 0x10,0x08,0x06,0x01,0x04,0x44,0x84,0x7F,0x04,0x04,0x04,0x01,0x06,0x18,0x08,0x00,};//星期几的汉字点阵(16*16)uchar code WEEKDAY[]={//0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,///0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,///0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,///0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,};//半角数字点阵(8*16)uchar code DIGITS[]={////0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,///0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,///0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,///0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, };//向DS1302写、读一字节--------//向DS1302写入一字节void Write_A_Byte_TO_DS1302(uchar x){uchar i;for (i=0;i<8;i++){SDA=x&1;CLK=1;CLK=0;x>>=1;}}//从DS1302读取一字节uchar Get_A_Byte_FROM_DS1302(){uchari,b,t;for(i=0;i<8;i++){b>>=1;t=SDA;b|=t<<7;CLK=1;CLK=0;}//BCD码转换return b/16*10+b;}//DS1302指定位置读数据ucharRead_Data(ucharaddr){uchardat;RST=0;CLK=0;RST=1;Write_A_Byte_TO_DS1302(addr);dat=Get_A_Byte_FROM_DS1302();CLK=1;RST=0;return dat;}//向DS1302某地址写入数据void Write_DS1302(ucharaddr,uchardat){CLK=0;RST=1;Write_A_Byte_TO_DS1302(addr);Write_A_Byte_TO_DS1302(dat);CLK=0;RST=0;}//设置时间void SET_DS1302(){uchar i;Write_DS1302(0x8E,0x00);//秒分时日月年依次写入for(i=0;i<7;i++){//秒的起始地址10000000(0x80),//后续依次是分,时,日,月,周,年,写入地址每次递增2 Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i])); }Write_DS1302(0x8E,0x80);}//读取当前日期时间void GetTime(){uchar i;for(i=0;i<7;i++){DateTime[i]=Read_Data(0x81+2*i);}}//判断是否为闰年ucharisLeapYear(uint y){return(y%4==0&&y0!=0)||(y@0==0);}//----------------------------------------void RefreshWeekDay(){uinti,d,w=5;for(i=2000;i<2000+DateTime[6];i++){d=isLeapYear(i)?366:365;w=(w+d)%7;}d=0;for (i=1;i<DateTime[4];i++)d+=MonthsDays[i];d+=DateTime[3];DateTime[5]=(w+d)%7+1;}//年月日时分秒++--void DateTime_Adjust(char x){switch(Adjust_Index){case 6://年00-99if(x==1&&DateTime[6]<99) DateTime[6]++;if(x==-1&&DateTime[6]>0)DateTime[6]--;//获取2月天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]])DateTime[3]=MonthsDays[DateTime[4]];RefreshWeekDay();//刷新星期break;case 4://月01-12if(x==1&&DateTime[4]<12)DateTime[4]++;if(x==-1&&DateTime[4]>1)DateTime[4]--;//获取2月天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]])DateTime[3]=MonthsDays[DateTime[4]];RefreshWeekDay();//刷新星期break;case 3://日00-28/29/30/31;调节前首先根据年份得出该年中2月的天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;//根据当前月份决定调节日期的上限if(x==1&&DateTime[3]<MonthsDays[DateTime[4]])DateTime[3]++;if(x==-1&&DateTime[3]>0)DateTime[3]--;RefreshWeekDay();//刷新星期break;case 2://时if(x==1&&DateTime[2]<23)DateTime[2]++;if(x==-1&&DateTime[2]>0)DateTime[2]--;break;case 1://分if(x==1&&DateTime[1]<59)DateTime[1]++;if(x==-1&&DateTime[1]>0)DateTime[1]--;break;case 0://秒if(x==1&&DateTime[0] <59) DateTime[0]++;if(x==-1&&DateTime[0] >0) DateTime[0]--;break;}}//定时器0每秒刷新LCD显示void T0_INT() interrupt 1{TH0=-50000/256;TL0=-50000%6;if(++tCount!=2)return;tCount=0;//年(后两位)Reverse_Display=Adjust_Index==6;Display_A_Char_8x16(V_Page_Offset,16+H_Offset,DIGITS+DateTime[6]/10*16); Display_A_Char_8x16(V_Page_Offset,24+H_Offset,DIGITS+DateTime[6]*16);//月Reverse_Display=Adjust_Index==4;Display_A_Char_8x16(V_Page_Offset,48+H_Offset,DIGITS+DateTime[4]/10*16); Display_A_Char_8x16(V_Page_Offset,56+H_Offset,DIGITS+DateTime[4]*16);//日Reverse_Display=Adjust_Index==3;Display_A_Char_8x16(V_Page_Offset,80+H_Offset,DIGITS+DateTime[3]/10*16); Display_A_Char_8x16(V_Page_Offset,88+H_Offset,DIGITS+DateTime[3]*16);//星期Reverse_Display=Adjust_Index==5;Display_A_Char_8x16(V_Page_Offset+3,104+H_Offset, WEEKDAY+DateTime[5]*16-16);//时Reverse_Display=Adjust_Index==2;Display_A_Char_8x16(V_Page_Offset+6,16+H_Offset,DIGITS+DateTime[2]/10*16); Display_A_Char_8x16(V_Page_Offset+6,24+H_Offset,DIGITS+DateTime[2]*16);//分Reverse_Display=Adjust_Index==1;Display_A_Char_8x16(V_Page_Offset+6,48+H_Offset,DIGITS+DateTime[1]/10*16); Display_A_Char_8x16(V_Page_Offset+6,56+H_Offset,DIGITS+DateTime[1]*16);//秒Reverse_Display=Adjust_Index==0;Display_A_Char_8x16(V_Page_Offset+6,80+H_Offset,DIGITS+DateTime[0]/10*16); Display_A_Char_8x16(V_Page_Offset+6,88+H_Offset,DIGITS+DateTime[0]*16);} //键盘中断(INT0)void EX_INT0() interrupt 0{if (K1 == 0) //选择调整对象{if (Adjust_Index == -1 || Adjust_Index == 0) Adjust_Index = 7;Adjust_Index--;if (Adjust_Index == 5) Adjust_Index = 4; //跳过对星期的调整}elseif (K2 == 0)DateTime_Adjust( 1); //加elseif (K3 == 0)DateTime_Adjust( -1 ); //减elseif (K4 == 0) //确定{SET_DS1302();Adjust_Index = -1;}}void main(){//液晶初始化LCD_Initialize();//显示年的固定前两位Display_A_Char_8x16(V_Page_Offset,0+H_Offset,DIGITS+2*16);Display_A_Char_8x16(V_Page_Offset,8+H_Offset,DIGITS);//显示固定汉字:年月日,星期,时分秒Display_A_WORD(V_Page_Offset,32+H_Offset,DATE_TIME_WORDS+0*32); Display_A_WORD(V_Page_Offset,64+H_Offset,DATE_TIME_WORDS+1*32); Display_A_WORD(V_Page_Offset,96+H_Offset,DATE_TIME_WORDS+2*32); Display_A_WORD(V_Page_Offset+3,72+H_Offset,DATE_TIME_WORDS+3*32); Display_A_WORD(V_Page_Offset+3,88+H_Offset,DATE_TIME_WORDS+4*32); Display_A_WORD(V_Page_Offset+6,32+H_Offset,DATE_TIME_WORDS+5*32); Display_A_WORD(V_Page_Offset+6,64+H_Offset,DATE_TIME_WORDS+6*32); Display_A_WORD(V_Page_Offset+6,96+H_Offset,DATE_TIME_WORDS+7*32); Display_A_WORD(V_Page_Offset+2,0+H_Offset,DATE_TIME_WORDS+8*32); Display_A_WORD(V_Page_Offset+2,16+H_Offset,DATE_TIME_WORDS+9*32); Display_A_WORD(V_Page_Offset+2,32+H_Offset,DATE_TIME_WORDS+10*32); Display_A_WORD(V_Page_Offset+2,48+H_Offset,DATE_TIME_WORDS+11*32); Display_A_WORD(V_Page_Offset+4,0+H_Offset,DATE_TIME_WORDS+12*32); Display_A_WORD(V_Page_Offset+4,16+H_Offset,DATE_TIME_WORDS+13*32); Display_A_WORD(V_Page_Offset+4,32+H_Offset,DATE_TIME_WORDS+14*32); Display_A_WORD(V_Page_Offset+4,48+H_Offset,DATE_TIME_WORDS+15*32);//允许INT0,T0中断IE=0x83;IP=0x01;IT0=0x01;TH0=-50000/256;TL0=-50000/256;TR0=1;while(1){//如果未执行调整操作则正常读取当前时间if(Adjust_Index==-1)GetTime();}}// 名称:12864LCD显示驱动程序(不带字库)//------------------------------------------------------------- #include <reg51.h>#include <intrins.h>#define unchar unsigned char#define uint unsigned int#define LCD_DB_PORT P0 //液晶DB0-DB7 #define LCD_START_ROW 0xC0 //起始行#define LCD_PAGE 0xB8 //页指令#define LCD_COL 0x40 //列指令//液晶引脚定义sbit DI =P2^0 ;sbit RW =P2^1 ;sbit E =P2^2 ;sbit CS1 =P2^3 ;sbit CS2 =P2^4 ;sbit rst =P2^5 ;bit Reverse_Display =0;//----------------------------------------------------------- //检查LCD是否忙//-----------------------------------------------------------bit LCD_Check_Busy (){LCD_DB_PORT =0xFF;RW =1; _nop_(); DI =0;E =1;_nop_(); E =0;return (bit) (P0 & 0x80);}//-----------------------------------------------------------// 向LCD发送命令//-----------------------------------------------------------void LCD_Write_Command( unchar c){while (LCD_Check_Busy ());LCD_DB_PORT =0xFF; RW =0; _nop_();DI =0;LCD_DB_PORT = c; E =1; _nop_();E =0;}//-----------------------------------------------------------//向LCD发送数据//-----------------------------------------------------------//向LCD发送数据void LCD_Write_Data(uchar d ){while(LCD_Check_Busy());LCD_DB_PORT = 0xFF;RW = 0; _nop_();DI = 1;//根据Reverse_Display决定是否反相显示if (! Reverse_Display) LCD_DB_PORT = d; else LCD_DB_PORT = ~d;E = 1 ;_nop_(); E = 0;}//初始化LCDvoid LCD_Initialize(){CS1 = 1; CS2 = 1;LCD_Write_Command(0x38);LCD_Write_Command(0x0F);LCD_Write_Command(0x01);LCD_Write_Command(0x06);LCD_Write_Command(LCD_START_ROW);}void Common_Show(ucharP,ucharL,ucharW,uchar *r)reentrant {uchar i;if(L<64)//显示在左半屏或左右半屏{CS1=1; CS2=0;LCD_Write_Command( LCD_PAGE+P);LCD_Write_Command(LCD_COL + L);if(L+W<64){for(i=0;i<W;i++) LCD_Write_Data(r[i]);}else//如果月结则跨越左右半屏显示{for(i=0;i<64-L;i++) LCD_Write_Data(r[i]);CS1=0;CS2=1;LCD_Write_Command(LCD_PAGE+P);LCD_Write_Command(LCD_COL);for(i=64-L;i<W;i++) LCD_Write_Data(r[i]);}}else // 全屏显示在右半屏{CS1=0;CS2=1;LCD_Write_Command(LCD_PAGE + P);LCD_Write_Command(LCD_COL+L-64);for (i=0;i<W;i++)LCD_Write_Data(r[i]);}}//显示一个8X16点阵字符//void Display_A_Char_8X16(ucharP,ucharL,uchar *M) reentrant {Common_Show( P, L, 8, M );Common_Show( P +1,L,8,M+8 );}//显示一个16x16点阵汉字void Display_A_WORD(ucharP,ucharL,uchar *M) reentrant {Common_Show( P, L, 16, M); //显示汉字上半部分Common_Show( P + 1,L, 16, M +16); //显示汉字下半部分}。