12864时钟
- 格式:doc
- 大小:60.50 KB
- 文档页数:16
以下是我写的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程序设计,重要的代码要有注释。
杜洋工作室 DoYoung Studio∙- 杜洋工作室DoClock电子时钟系列∙- FutureTimer4未来时钟(FT4)- 所需元器件∙- 电源使用电脑USB接口或USB电源适配器∙- FT4亮黑镀金PCB板正面- PCB板背面∙- STC12C5A32S2-35I-DIP40单片机∙- LCD12864汉字显示液晶屏- DS1302时钟芯片、32.768kHz 6pF晶体、3V贴片钮扣电池- DS18B20温度传感器- 5547光敏电阻器- 40PIN军品芯片座- 军品排针 20PIN*1 - 军品排孔 20PIN*2- 12*12mm微动开关 4个- 微型压电蜂鸣器∙- 电路原理图∙- 将20PIN排孔插入液晶屏模块的背面接口处∙- 向内倾斜一定角度并在背面焊接∙- 倾斜的角度为向内倾斜的最大极限∙- 把军品排针插入到排孔中∙- 插好后的样品- 液晶屏的正面没有任何焊点保证了正面的美观∙- 把4个微动开关一侧的2个引脚和凸出点剪掉∙- 剪后的样子∙- 余下的引脚对应单片机的20到40脚一侧如上图摆放- 把微动开关引脚与相邻的单片机引脚焊接在一起∙- 焊好后的样子∙- PCB板上共有2个miniUSB接口左右各1个- 适合不同方向的接线- 把miniUSB接头焊接在您喜欢方向的焊盘上- 把DS18B20温度传感器摆放在miniUSB接口上方的焊接上- DS18B20有字的一面朝上焊接(用于温度数据的采集)- 焊接贴片三极管和电阻(用于液晶屏背光的驱动)- 按图焊接DS1302时钟芯片(用于时间数据的生成)- 按图焊接32.768KHz晶体(用于时间的基准频率产生)- 按图焊接光敏电阻不分正负极(用于自动背光控制的采集)- 按图焊接钮扣电池(用于掉电后维持时间的走时)- 按图焊接压电蜂鸣器(用于提示音和闹钟报警)- 背面焊接后的样子- 转向正面焊接- 焊接0.1uF(104)滤波电容(用于电源高频干扰滤波)- 按图焊接100uF电容注意正负极不要焊反(用于电源低频滤波)- 按图焊接12.00MHz晶体(用于单片机时钟源)- 按图焊接2个30pF电容(用于晶体负载电容)- 插入40PIN军品芯片座- 在背面将芯片座焊在板上- 取20PIN军品排孔并剪掉一半的细针部分∙- 剪好后的样子∙- 把剪好后的排孔插入PCB背面- 插入后的样子- 从PCB背面焊接以保证正面的美观- 背面全部焊接完毕的样子- 将单片机插入到芯片座中- 再将PCB板插入到液晶屏上- 小角度立放- 大角度躺放- 制作完成后的时钟背面- 因为时钟底面有大量焊点所以不要摆放在金属板面上- 液晶屏前面焊盘不在焊接以保证最佳的外观- 侧面的光敏电阻可以感知环境光线来调节液晶背面的亮度。
第一章方案论证1.1 单片机型系统的选择与论证方案一:此方案采用AT89C51八位单片机实现。
它内存较小,只有4K字节Flash闪速存储器,128字节内部RAM,32个I/O口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,无在线下载编程功能,也无在线仿真功能。
只能通过编程器烧写成以.hex为后缀名的文件。
方案二:此方案采用AT89S52八位单片机实现。
它内存较大,有8K的字节Flash闪速存储器,比AT89C51要多4K。
它可在线编程,可在线仿真的功能,这让调试变得方便。
单片机软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制。
而且体积小,硬件实现简单,安装方便。
另外AT89S52在工业控制上也有着广泛的应用,编程技术及外围功能电路的配合使用都很成熟。
综上所述,我们采用了第二个方案,即AT89S52。
1.2显示模块的选择与论证方案一:采用LED点阵显示,用来显示文字、图形、图像、等各种信息的显示屏幕。
它均由LED矩阵块组成。
图文显示屏可与计算机同步显示汉字、英文文本和图形,该方案简单易行。
但所需的元件较多,且不容易进行操作,可读性差,一旦设定后,很难再加入其他的功能,当加上日期、时间时增加了编程的难度。
方案二:采用液晶(JHD529M1)显示器件,该液晶显示器件与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该器件的价格也略低于相同点阵的图形液晶模块。
而且此液晶显示平稳、省电、美观,更容易实现题目要求,对后续的功能兼容性高,同时有中文字库,也可以实现图像显示。
只需将软件作修改即可,可操作性强,也易于读数,能同时显示日期、时间、星期且易于修改。
综上分析,我们采用了第二个方案。
1.3 时钟实现方案一:采用软件实现,直接用单片机的定时器编程以实现时钟,优点节省硬件,缺点是编程复杂程序运行的每一步都需要时间,多一步或少一步程序都会影响记时的准确度,准确度较差。
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汉字液晶显示--按键电子时钟程序(具有闪烁,移位,加一,减一功能)#include <reg52.h>#include <intrins.h>#define uchar unsigned charvoid lcd_ini();void ascii_change(void);void delay();void wri_add(uchar com);void wri_dat(uchar com1);void shan(void);void disp();void tkey(void);sbit cs=P1^7;sbit sid=P1^6;sbit sclk=P1^5;bit flag=1;uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态uchar data clock[3]={23,45,12};uchar code clockname[10]={"北京时间:"};uchar data num[6];/*******主程序*************/void main(){lcd_ini();count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒TMOD=0x01;TL0=0XB0;TH0=0X3C;EA=1;ET0=1;IT0=1;EX0=1;TR0=1;while(1){back:ascii_change();disp();delay();if(flag==1)goto back;tkey();shan();delay();}}/****lcd初始化*******/void lcd_ini(){wri_add(0x30);delay();wri_add(0x0c);delay();wri_add(0x01);delay();wri_add(0x06);delay();}/********定时程序*************/ void timer1() interrupt 1 using 2 {TL0=0XB0;TH0=0X3C;count--;if(count==0){count=10;clock[2]++;//秒//}elsegoto out;if(clock[2]==60){clock[2]=0;clock[1]++;//分//}if(clock[1]==60){clock[1]=0;clock[0]++;}if(clock[0]==24)//时//clock[0]=0;out:_nop_();}/*******十位个位转换成ASCII码************/ void ascii_change(void){num[5]=clock[2]-(clock[2]/10)*10+0x30;num[4]=clock[2]/10+0x30;num[3]=clock[1]-(clock[1]/10)*10+0x30;num[2]=clock[1]/10+0x30;num[1]=clock[0]-(clock[0]/10)*10+0x30;num[0]=clock[0]/10+0x30;}/********廷时程序*************/void delay(){uchar i,j;for (i=250;i>0;i--)for (j=250;j>0;j--);}/*****Write address*********/void wri_add(uchar com){uchar i,j,k;cs=0;cs=1;dat=0xf8;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/*********Write data*************/ void wri_dat(uchar com1){uchar i,j,k;cs=0;cs=1;dat=0xfa;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/******display program***********/ void disp(){uchar i,k=0;wri_add(0x80);for (i=1;i<=9;i++)wri_dat(clockname[i-1]);wri_add(0x90);for (i=1;i<=6;i++) {k++;if(k==3||k==5)wri_dat(clockname[8]);//时间之间的冒号。
《单片机原理及应用》课程设计说明书题目LCD12864 液晶显示电子钟设计系(部)专业(班级)姓名学号指导教师起止日期课程设计任务书系(部):专业:目录一、12864液晶的工作原理 (4)二、方案设计 (5)实物硬件设计 (5)系统硬件设计 (5)主芯片模块 (5)晶振和复位模块 (6)按钮模块 (7)系统软件设计 (7)主程序设计 (7)三、仿真和分析 (8)四、总结体会 (8)参考文献 (9)一、12864液晶的工作原理液晶显示屏中的业态光电显示材料,利用液晶的电光效应把电信号转换成数字符、图像等可见信号。
如图1-1,液晶正常情况下,其分子排列很有秩序,显得清澈透明,一旦加上直流电场后,分子的排列被打乱,一部分液晶变的不透明,颜色加深因而能显示数字和图像。
管脚一共1个CS1左半屏片选端,CS2右半屏片选端;V0液晶显示驱动电压,通过一个电位器接到VCC;RS数据指令选择信号,H为数据,L为指令,也叫D/I;R/W读写选择信号,H为读,L为写,。
E为LCD使能端,R/W为L时,E信号下降沿锁存DB7-DB0;R/W为H时,E为H,DDRAM数据读到DB7-DB0。
DB0-DB7数据传输端口。
RST复位信号。
-VOUT和V0为液晶显示驱动电压。
12864是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128×64全点阵液晶显示器组成。
可完成图形显示,也可以显示8×4个(16×16点阵)汉字。
图1-1 12864LCD液晶显示屏二、方案设计实物硬件设计单片机控制液晶显示屏系统总共可分为六个环节,分别是单片机控制系统、12864字符显示模块、控制开关模块、晶振控制模块、复位电路模块和DS1302时钟控制模块。
通过这六个模块的协调工作就可以完成相应的液晶屏控制和显示功能。
这六个模块的相互连接如图2-1:图2-1 硬件组成框图系统硬件设计本硬件电路主要由四大模块组成:主芯片模块;晶振和复位电路模块;控制接钮模块;显示电路模块。
基于12864的指针式时钟设计【摘要】LCD12864是基于点阵式的,像素为128×64的液晶显示屏,基本满足指针式时钟的显示要求。
本系统采用时钟芯片DS1302、单片机、12864设计一款可以切换数字式和指针式显示的电子时钟。
【关键词】指针式时钟;LCD12864;DS1302The Design of a Point Clock Based on 12864MENGMing-ming(Computer Science and Technology School, China University of Mining and TechnologyJiangSuXuzhou221000)【Abstract】The 12864 is a liquid crystal display of 128×64 dots, which can be used to display a point clock. In this paper, the design takes a sort of clock chip named DS1302 and 12864 to make a clock that can switch between point display and digital display.【Key words】Key Words: Point Clock; LCD12864;DS1302采用单片机与时钟芯片DS1302设计电子时钟时,通常是数字显示,这是由于选用数码管和1602等器件的显示能力有限。
而12864是基于点阵式的液晶屏,其像素点为128×64,基本达到指针式时钟显示要求。
本系统在时钟表盘、指针绘制及时钟走时和时间的准确性方面都基本实现要求。
虽然12864自身像素较低,使其显示指针式时钟效果远低于大屏幕LED,但两者所基于的原理相同,对于点阵设计的学习有较大帮助。
学士学位毕业论文(设计)题目:基于单片机的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时钟发展史很早以前,人类主要是利用天文现象和流动物质的连续运动来计时。
信息工程学院课程设计报告书题目: LCD显示的指针式电子钟专业:电子信息的科学与技术班级: 0311410学号: 031141012学生姓名:何标指导教师:高林2014年 5 月 15 日信息工程学院课程设计任务书2014年5月20 日信息工程学院课程设计成绩评定表目录1 任务提出与方案论证 (6)1.1设计要求 (6)1.2原理说明 (6)2 总体设计 (7)3 详细设计 (8)3.1 AT89C51单片机简介 (8)3.2时钟模块设计 (9)3.3 显示模块设计 (10)3.4 设置模块 (10)3.5 振荡电路 (10)3.6 复位设置 (11)4 总结 (12)参考文献 (13)附录仿真电路图 (14)摘要单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。
单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。
本设计就是应用单片机强大的控制功能制作而成的指针式电子钟,该指针式电子钟实现如下功能:液晶屏模拟表盘与时分秒指针显示当前时钟,K1键用于选择调节对象,K2键用于调整时分秒,在按下K4键时确定调节值,时钟继续运行。
本设计采用的是AT89C51单片机,AT89C51单片机内部带有定时/计数功能,此定时功能是通过对外部晶振的脉冲进行计数,从而达到计时功能,只要使用11.0592的晶振就能实现零误差的计时,因此可以利用此功能实现计时。
芯片采用DALLAS公司的涓细充电时钟芯片DS1302,该芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时分、秒信息,采用双电源供电,当外部电源掉电时能够利用后备电池准确计时。
显示器件采用PG12864LCD液晶,12864是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128×64全点阵液晶显示器组成。
可完成图形显示,也可以显示8×4个(16×16点阵)汉字。
stm3212864lcd显示时间和温度#include "stm32f10x.h"#include "stdio.h"//-------------------------------------------------------------------------------------------------#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键0#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键1 #define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键2#define KEY0_PRES 1 //KEY0#define KEY1_PRES 2 //KEY1#define WKUP_PRES 3 //WK_UP//-------------------------------------------------------------------------------------------------//位带操作,实现51类似的GPIO控制功能//具体实现思想,参考<>第五章(87页~92页).//IO口操作宏定义#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))//IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08//IO口操作,只对单一的IO口!//确保n的值小于16!#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入//-------------------------------------------------------------------------------------------------#define LED0 PAout(8) // PA8#define LED1 PDout(2) // PD2#define LED2 PAout(2)#define LED3 PAout(3)//-------------------------------------------------------------------------------------------------// lcd12864//-------------------------------------------------------------------------------------------------#define SID_H GPIOC->BSRR=GPIO_Pin_7#define SID_L GPIOC->BRR=GPIO_Pin_7#define CS_H GPIOC->BSRR=GPIO_Pin_8#define CS_L GPIOC->BRR=GPIO_Pin_8#define SCLK_H GPIOC->BSRR=GPIO_Pin_6#define SCLK_L GPIOC->BRR=GPIO_Pin_6#define x1 0x80#define x2 0x88#define y 0x80#define comm 0#define dat1 1u8 const num_lcd[]={"0123456789"};void Clr_Scr(void);void LCD_Write_String(u8 X,u8 Y,uc8 *s);//12864u8 A,B,C,D;void display_temp_time(void);void display_main(void);void display_1(void);//-------------------------------------------------------------------------------------------------// DS1302//-------------------------------------------------------------------------------------------------#define ds1302clk GPIO_Pin_12#define ds1302dat GPIO_Pin_13#define ds1302rst GPIO_Pin_14uint8_ttime_ds1302[7]={0x00,0x54,0x10,0x08,0x12,0x01,0x08};uint8_t read[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址uint8_t write[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址//按键中断按下显示时间,所以需要全局变量uint8_t i=0,g[7];void ds1302_data(uint8_t *read);uint8_t DSPH[]={"00"};uint8_t DSPM[]={"00"};uint8_t DSPS[]={"00"};uint8_t DSPN[]={"00"};uint8_t DSPY[]={"00"};uint8_t DSPR[]={"00"};//-------------------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------------------// DS18b20//-------------------------------------------------------------------------------------------------float DS18B20_Get_Temp(void);uint8_t DS18B20_Init(void);//-------------------------------------------------------------------------------------------------#define HIGH 1#define LOW 0//-------------------------------------------------------------------------------------------------#define DS18B20_CLK RCC_APB2Periph_GPIOC#define DS18B20_PIN GPIO_Pin_13#define DS18B20_PORT GPIOC//带参宏,可以像内联函数一样使用,输出高电平或低电平#define DS18B20_DATA_OUT(a) if (a) \GPIO_SetBits(GPIOC,GPIO_Pin_13);\else \GPIO_ResetBits(GPIOC,GPIO_Pin_13)//读取引脚的电平#define DS18B20_DATA_IN() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)uint8_t DSPWD[]={"00"};uint8_t str[2]={0};uint8_t temp;//-------------------------------------------------------------------------------------------------typedef struct{uint8_t humi_int; //湿度的整数部分uint8_t humi_deci; //湿度的小数部分uint8_t temp_int; //温度的整数部分uint8_t temp_deci; //温度的小数部分uint8_t check_sum; //校验和}DS18B20_Data_TypeDef;//---------------------------------------------------------------------------------------------------------------------------------------------------------------------static u8 fac_us=0;//us延时倍乘数static u16 fac_ms=0;//ms延时倍乘数//-------------------------------------------------------------------------------------------------volatile u32 time = 0;//-------------------------------------------------------------------------------------------------unsigned char sz[5]={0x00,0x01,0x02,0x03,0x04};//-------------------------------------------------------------------------------------------------void delay_init(void);void delay_ms(u16 nms);void delay_us(u32 nus);void KEY_Init(void);//void Delay_us(__IO u32 nTime);void delay_init(void);//-------------------------------------------------------------------------------------------------// 系统定时器初始化//-------------------------------------------------------------------------------------------------void delay_init(void){SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8fac_us=SystemCoreClock/8000000; //为系统时钟的1/8fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数}//-------------------------------------------------------------------------------------------------void delay_us(u32 nus){u32 temp;SysTick->LOAD=nus*fac_us; //时间加载SysTick->VAL=0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16))); //等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器}//--------------------------------------------------------------------//延时nms//注意nms的范围//SysTick->LOAD为24位寄存器,所以,最大延时为://nms<=0xffffff*8*1000/SYSCLK//SYSCLK单位为Hz,nms单位为ms//对72M条件下,nms<=1864//--------------------------------------------------------------------void delay_ms(u16 nms){u32 temp;SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)SysTick->VAL =0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器}//-------------------------------------------------------------------------------------------------// 中断优先级配置//-------------------------------------------------------------------------------------------------void NVIC_Configuration1(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级}//-------------------------------------------------------------------------------------------------// 外部中断初始化函数//-------------------------------------------------------------------------------------------------void EXTIX_Init(void){EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中断,需要使能AFIO时钟KEY_Init(); //初始化按键对应io模式GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSour ce5); //GPIOC.5 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line5;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSour ce15); //GPIOA.15 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line15;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSour ce0); //GPIOA.0 中断线以及中断初始化配置EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);}//-----------------------------------------------------------------// 按键中断函数//-----------------------------------------------------------------void EXTI0_IRQHandler(void){delay_ms(10);if(WK_UP==1){LED0=!LED0;LED1=!LED1;Clr_Scr();A=1;Clr_Scr();//===================================== ============================//printf("测试");//printf("\r\n 现在温度 %.1f 度\r\n",DS18B20_Get_Temp());}EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起位}//-----------------------------------------------------------------void EXTI9_5_IRQHandler(void){delay_ms(10);if(KEY0==0){LED0=!LED0;A=0;//printf("稍等");//adcx=Get_Adc_Average(ADC_Channel_1,10);//temp =(float) adcx/4096*3.3;//printf("\r\n The current AD value = 0x%04X \r\n",adcx);//printf("\r\n The current AD value = %f V \r\n",temp);}EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中断标志位}//-----------------------------------------------------------------void EXTI15_10_IRQHandler(void){delay_ms(10);if(KEY1==0){LED1=!LED1;A=2;//printf("硕硕");// ds1302_data(read);//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[ 3],g[3],//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[ 0],g[5]);}EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15线路挂起位}//===================================== ========================================= ===================//-------------------------------------------------------------------------------------------------// LED GPIO 初始化//-------------------------------------------------------------------------------------------------void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_2|GPIO_Pin_3; //LED0-->PA.8 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出,IO口速度为50MHzGPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高}//-------------------------------------------------------------------------------------------------// GPIO 按键初始化//-------------------------------------------------------------------------------------------------void KEY_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP B2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0}//-------------------------------------------------------------------------------------------------// 串口配置//-------------------------------------------------------------------------------------------------void USART1_Config(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_/doc/400b4fab7c1cfad6185fa 744.html ART_BaudRate = 9600;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_WordLength = USART_WordLength_8b;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_StopBits = USART_StopBits_1;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Parity = USART_Parity_No ;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_HardwareFlowControl =USART_HardwareFlowControl_None;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_Cmd(USART1, ENABLE);}//--------------------------------------------------------------------// 配置USART1接收中断//--------------------------------------------------------------------void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}//--------------------------------------------------------------------//--------------------------------------------------------------------// 重定向c库函数printf到USART1//--------------------------------------------------------------------int fputc(int ch, FILE *f){//发送一个字节数据到USART1USART_SendData(USART1, (uint8_t) ch);//等待发送完毕while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return (ch);}// 重定向c库函数scanf到USART1int fgetc(FILE *f){while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);}//--------------------------------------------------------------------// 串口3配置//--------------------------------------------------------------------void USART3_Config(void){NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);USART_/doc/400b4fab7c1cfad6185fa 744.html ART_BaudRate = 9600;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_WordLength = USART_WordLength_8b;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_StopBits = USART_StopBits_1;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Parity = USART_Parity_No ;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_/doc/400b4fab7c1cfad6185fa 744.html ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART3, &USART_InitStructure);USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);USART_Cmd(USART3, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}//===================================== ========================================= ========================================= ========================================= =====// DS1302//===================================== ========================================= ========================================= ========================================= =====void DS1302_GPIO(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStruct.GPIO_Pin = ds1302clk|ds1302rst; //clk、rst配置为输出GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin = ds1302dat;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //IO配置为双向GPIO_Init(GPIOB, &GPIO_InitStruct);}//-------------------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------------------void write_1302byte(uint8_t dat){uint8_t i = 0;GPIO_ResetBits(GPIOB,ds1302clk);delay_us(2);//延时大约2usfor(i = 0;i < 8;i ++){GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;if(dat&0x01)GPIO_SetBits(GPIOB,ds1302dat);else GPIO_ResetBits(GPIOB,ds1302dat);delay_us(2);GPIO_SetBits(GPIOB,ds1302clk);dat >>= 1;delay_us(1);}}//-----------------------------------------------uint8_t read_1302(uint8_t add){uint8_t i=0;uint8_t Return_dat=0x00;GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk);delay_us(3);GPIO_SetBits(GPIOB,ds1302rst);delay_us(3);write_1302byte(add);for(i=0;i<8;i++){GPIO_SetBits(GPIOB,ds1302clk);Return_dat >>= 1;GPIO_ResetBits(GPIOB,ds1302clk);if(GPIO_ReadInputDataBit(GPIOB,ds1302dat)==1) //数据线此时为高电平{Return_dat = Return_dat|0x80;}}delay_us(1);GPIO_ResetBits(GPIOB,ds1302rst); //ds1302rst=0;释放总线return Return_dat;}//-----------------------------------------------void write_1302(uint8_t add,uint8_t dat) //向指定寄存器写入一个字节的数据{GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk); //ds1302rst=0;//ds1302clk=0;delay_us(1);GPIO_SetBits(GPIOB,ds1302rst); //ds1302rst=1;delay_us(2);write_1302byte(add);write_1302byte(dat);GPIO_ResetBits(GPIOB,ds1302rst);GPIO_ResetBits(GPIOB,ds1302clk); //ds1302clk=0;//ds1302rst=0;delay_us(1);}//-----------------------------------------------void ds1302_init(uint8_t*write,uint8_t*time) //初始化1302 {uint8_t i=0,j=0;write_1302(0x8e,0x00);for(i=0;i<7;i++){j=time_ds1302[i]%10;time_ds1302[i]=(time_ds1302[i]/10)*16+j;}for(i=0;i<7;i++){write_1302(write[i],time_ds1302[i]);}write_1302(0x8e,0x80);//-----------------------------------------------void ds1302_data(uint8_t *read){//中断按键按下显示时间,所以定义为全局变量//uint8_t i=0,g[7],time_ds1302[7];//static uint8_t s = 1;for(i=0;i<7;i++){time_ds1302[i]=read_1302(read[i]);}//===================================== ==========/*for(i=0;i<7;i++){g[i]=time_ds1302[i]%16; time_ds1302[i]=time_ds1302[i]/16;}*///此时已转换成10进制数,g[i]里面存放的是秒分时日月周年的各个位数据//而此时的time[i]存放的是十位数据//if(s != (time[0]+g[0]))//printf("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time_ds1302[6],g[6],time_ds1302[4],g[4],time_ds1302[ 3],g[3],//time_ds1302[2],g[2],time_ds1302[1],g[1],time_ds1302[0],g[ 0],g[5]);//s = time[0]+g[0];//---------------------------------------------------------------------------------------------------------------------------------------------------------------------// DS18B20温度传感器//-------------------------------------------------------------------------------------------------void DS18B20_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE); //开启DS18B20_PORT的外设时钟GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHzGPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORTGPIO_SetBits(DS18B20_PORT, DS18B20_PIN);}//-------------------------------------------------------------------------------------------------void DS18B20_Mode_IPU(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置引脚模式为浮空输入模式GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT}//-------------------------------------------------------------------------------------------------void DS18B20_Mode_Out_PP(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; //选择要控制的DS18B20_PORT引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为通用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置引脚速率为50MHzGPIO_Init(DS18B20_PORT, &GPIO_InitStructure); //调用库函数,初始化DS18B20_PORT}//-------------------------------------------------------------------------------------------------void DS18B20_Rst(void){DS18B20_Mode_Out_PP(); //主机设置为推挽输出DS18B20_DATA_OUT(LOW);delay_us(750); // 主机至少产生480us的低电平复位信号DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲}//-------------------------------------------------------------------------------------------------//检测从机给主机返回的存在脉冲//0:成功//1:失败//-------------------------------------------------------------------------------------------------uint8_t DS18B20_Presence(void){uint8_t pulse_time = 0;DS18B20_Mode_IPU(); //主机设置为上拉输入//等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号//如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲while( DS18B20_DATA_IN() && pulse_time<100 ){pulse_time++;delay_us(1); //经过100us后,存在脉冲都还没有到来}if( pulse_time >=100 )return 1;elsepulse_time = 0;while( !DS18B20_DATA_IN() && pulse_time<240 ) //存在脉冲到来,且存在的时间不能超过240us{pulse_time++;delay_us(1);}if( pulse_time >=240 )return 1;elsereturn 0;}//从DS18B20读取一个bituint8_t DS18B20_Read_Bit(void){uint8_t dat; //读0和读1的时间至少要大于60usDS18B20_Mode_Out_PP();DS18B20_DATA_OUT(LOW); //读时间的起始:必须由主机产生 >1us <15us 的低电平信号delay_us(10);DS18B20_Mode_IPU(); //设置成输入,释放总线,由外部上拉电阻将总线拉高//Delay_us(2);if( DS18B20_DATA_IN() == SET )dat = 1;elsedat = 0;delay_us(45); //这个延时参数请参考时序图return dat;}//从DS18B20读一个字节,低位先行uint8_t DS18B20_Read_Byte(void){uint8_t i, j, dat = 0;for(i=0; i<8; i++){j = DS18B20_Read_Bit();dat = (dat) | (j<<i);}return dat;}//写一个字节到DS18B20,低位先行void DS18B20_Write_Byte(uint8_t dat) {uint8_t i, testb;DS18B20_Mode_Out_PP();for( i=0; i<8; i++ ){testb = dat&0x01;dat = dat>>1;//写0和写1的时间至少要大于60us if (testb){DS18B20_DATA_OUT(LOW);//1us < 这个延时 < 15usdelay_us(8);DS18B20_DATA_OUT(HIGH);delay_us(58);}else{DS18B20_DATA_OUT(LOW);//60us < Tx 0 < 120usdelay_us(70);DS18B20_DATA_OUT(HIGH);//1us < Trec(恢复时间) < 无穷大delay_us(2);}}}//-------------------------------------------------------------------------------------------------void DS18B20_Start(void){DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0X44); // 开始转换}//-------------------------------------------------------------------------------------------------uint8_t DS18B20_Init(void){DS18B20_GPIO_Config();DS18B20_Rst();return DS18B20_Presence();}//温度 = 符号位 + 整数 + 小数*0.0625float DS18B20_Get_Temp(void){uint8_t tpmsb, tplsb;short s_tem;float f_tem;DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0X44); // 开始转换DS18B20_Rst();DS18B20_Presence();DS18B20_Write_Byte(0XCC); // 跳过 ROMDS18B20_Write_Byte(0XBE); // 读温度值tplsb = DS18B20_Read_Byte();tpmsb = DS18B20_Read_Byte();s_tem = tpmsb<<8;s_tem = s_tem | tplsb;if( s_tem < 0 ) // 负温度f_tem = (~s_tem+1) * 0.0625;elsef_tem = s_tem * 0.0625;return f_tem;}//===================================== ========================================= ===void Show_Temperature(void){</i);temp=DS18B20_Get_Temp();str[0]=temp/10;str[1]=temp%10;DSPWD[0]=str[0]+0x30;DSPWD[1]=str[1]+0x30;}//-------------------------------------------------------------------------------------------------//---------------------------------------------------------------------------------------------------------------------------------------------------------------------// LCD12864//---------------------------------------------------------------------------------------------------------------------------------------------------------------------void Lcds_Config(void){// SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);/*PC4-A0*/// GPIO_SetBits(GPIOC, GPIO_Pin_12);//预置为高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;。
#include<reg52.h>#include<intrins.h>sbit SCLK=P3^7;sbit IO=P3^6;sbit CE=P3^5;sbit DQ = P3^4;sbit FM=P2^7;sbit RS=P2^3;sbit RW=P2^4;sbit EN=P2^5;sbit PSB=P2^2;sbit key=P1^0;sbit key1=P1^1;sbit key2=P1^2;sbit key3=P1^3;#define uchar unsigned char#define uint unsigned intuchar S1num,flag,second,minute,hour,week,day,month,year; bit keyflag=0;uchar num1[]="王厚谊加油";uchar num2[]="世上无难事";uchar num3[]="只要肯攀登";void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void delay_us(){_nop_();_nop_();_nop_();_nop_();void fs_FM(){FM=0;delay(20);FM=1;}/*************************************************12864程序*************************************************/ void write_12864com(uchar com){RS=0;RW=0;P0=com;delay(5);EN=1;delay(5);EN=0;}void write_12864dat(uchar dat){RS=1;RW=0;P0=dat;delay(5);EN=1;delay(5);EN=0;}void write_12864(uchar add,uchar dat){write_12864com(add);write_12864dat(dat);}void Write_zfc(uchar *p){while(*p!=0)write_12864dat(*p++);}void init_12864(){PSB=1;write_12864com(0x30);delay(5);write_12864com(0x0f);delay(5);write_12864com(0x01);delay(5);// write_12864(0x81,'20');}void disp(){write_12864com(0x80);Write_zfc("日期:");write_12864com(0x90);Write_zfc("时间:");write_12864com(0x88);Write_zfc("星期:");write_12864com(0x98);Write_zfc("温度:");write_12864(0x84,'-');write_12864(0x86,'-');write_12864(0x94,':');write_12864(0x96,':');}void disp0(){uchar i;write_12864com(0x81);for(i=0;i<10;i++){write_12864dat(num1[i]);delay(4);}}void disp1()uchar i;write_12864com(0x91);for(i=0;i<10;i++){write_12864dat(num2[i]);delay(4);}}void disp2(){uchar i;write_12864com(0x89);for(i=0;i<10;i++){write_12864dat(num3[i]);delay(4);}}/***************************************************1302程序****************************************************/ void write_1302byte(uchar dat){uchar i;SCLK=0;delay_us();for(i=8;i>0;i--){IO=dat&0x01;delay_us();SCLK=1;delay_us();SCLK=0;dat>>=1;}}uchar read_1302byte(){uchar i,dat;delay_us();for(i=8;i>0;i--){dat>>=1;if(IO==1){dat|=0x80;}SCLK=1;delay_us();SCLK=0;delay_us();}return dat;}void write_1302(uchar add,uchar dat) {CE=0;delay_us();SCLK=0;delay_us();CE=1;write_1302byte(add);delay_us();write_1302byte(dat);delay_us();CE=0;}uchar read_1302add(uchar add){uchar timedat;CE=0;_nop_();SCLK=0;_nop_();CE=1;write_1302byte(add);timedat=read_1302byte();SCLK=1;_nop_();CE=0;return timedat;}void init_1302(){flag=read_1302add(0x81);if(flag&0x80){write_1302(0x8e,0x00);write_1302(0x80,((55/10)<<4|(55%10)));write_1302(0x82,((59/10)<<4|(59%10)));write_1302(0x84,((23/10)<<4|(23%10)));write_1302(0x86,((31/10)<<4|(31%10)));write_1302(0x88,((12/10)<<4|(12%10)));write_1302(0x8a,((2/10)<<4|(2%10)));write_1302(0x8c,((12/10)<<4|(12%10)));write_1302(0x90,0xa5);write_1302(0x8e,0x80);}}uchar readsecond(){uchar dat;dat=read_1302add(0x81);second=((dat&0x70)>>4)*10+(dat&0x0f);return second;}uchar readminute(){uchar dat;dat=read_1302add(0x83);minute=((dat&0x70)>>4)*10+(dat&0x0f);return minute;}uchar readhour(){uchar dat;dat=read_1302add(0x85);hour=((dat&0x70)>>4)*10+(dat&0x0f);return hour;}uchar readday()uchar dat;dat=read_1302add(0x87);day=((dat&0x70)>>4)*10+(dat&0x0f);return day;}uchar readmonth(){uchar dat;dat=read_1302add(0x89);month=((dat&0x70)>>4)*10+(dat&0x0f);return month;}uchar readweek(){uchar dat;dat=read_1302add(0x8b);week=((dat&0x70)>>4)*10+(dat&0x0f);return week;}uchar readyear(){uchar dat;dat=read_1302add(0x8d);year=((dat&0xf0)>>4)*10+(dat&0x0f);return year;}void write_second(){uchar shi,ge;shi=second/10;ge=second%10;write_12864com(0x97);write_12864dat(0x30+shi);write_12864dat(0x30+ge);}void write_minute(){uchar shi,ge;shi=minute/10;ge=minute%10;write_12864com(0x95);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_hour(){uchar shi,ge;shi=hour/10;ge=hour%10;write_12864com(0x93);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_day(){uchar shi,ge;shi=day/10;ge=day%10;write_12864com(0x87);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_month(){uchar shi,ge;shi=month/10;ge=month%10;write_12864com(0x85);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_year(){uchar shi,ge;shi=year/10;ge=year%10;write_12864com(0x83);write_12864dat(0x30+shi);write_12864dat(0x30+ge);}void write_week(){write_12864com(0x8b);write_12864dat(0x30+week);}/*****************************************************按键程序*****************************************************/ void keycan(){if(key==0){delay(5);if(key==0){S1num++;while(!key);fs_FM();switch(S1num){case 1:keyflag=1;write_1302(0x8e,0x00);write_1302(0x80,0x80);write_12864com(0x97);write_12864com(0x0f);break;case 2:write_12864com(0x95);break;case 3:write_12864com(0x93);break;case 4:write_12864com(0x87);break;case 5:write_12864com(0x85);break;case 6:write_12864com(0x83);break;case 7:write_12864com(0x8b);break;case 8:S1num=0;keyflag=0;write_12864com(0x0c);write_1302(0x80,0x00);write_1302(0x80,(second/10)<<4|second%10);write_1302(0x82,(minute/10)<<4|minute%10);write_1302(0x84,(hour/10<<4)|hour%10);write_1302(0x86,(day/10<<4)|day%10);write_1302(0x88,(month/10<<4)|month%10);write_1302(0x8a,(week/10<<4)|week%10);write_1302(0x8c,(year/10<<4)|year%10);write_1302(0x8e,0x80);break;}}}if(S1num!=0){if(key1==0){delay(5);while(!key1);fs_FM();switch(S1num){case 1:second++;if(second==60)second=0;write_second();write_12864com(0x97);break;case 2:minute++;if(minute==60)minute=0;write_minute();write_12864com(0x95);break;case 3:hour++;if(hour==24)hour=0;write_hour();write_12864com(0x93);break;case 4:day++;if(day==32)day=1;write_day();write_12864com(0x87);break;case 5:month++;if(month==13)month=1;write_month();write_12864com(0x85);break;case 6:year++;if(year==99)year=0;write_year();write_12864com(0x83);break;case 7:week++;if(week==8)week=1;write_week();write_12864com(0x8b);break;}}}if(S1num!=0){if(key2==0){delay(5);while(!key2);fs_FM();switch(S1num){case 1:second--;if(second==-1)second=59;write_second();write_12864com(0x97);break;case 2:minute--;if(minute==-1)minute=59;write_minute();write_12864com(0x95);break;case 3:hour--;if(hour==-1)hour=23;write_hour();write_12864com(0x93);break;case 4:day--;if(day==0)day=31;write_day();write_12864com(0x87);break;case 5:month--;if(month==0)month=12;write_month();write_12864com(0x85);break;case 6:year--;if(year==-1)year=99;write_year();write_12864com(0x83);break;case 7:week--;if(week==0)week=7;write_week();write_12864com(0x8b);break;}}}}/*****************************************************18B20程序*******************************************************/uint temp; //温度值variable of temperaturevoid delay2(unsigned char i) //延时函数{while(--i);}void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command{DQ = 1; //DQ复位,不要也可行。
用51单片机控制12864显示数字时钟用51单片机控制12864显示数字时钟里面有128564显示汉字的程序,自己研究下,不过是用msp430控制的,你改改端口i就可以了。
#include "msp430x26x.h"#define uchar unsigned char#define uint unsigned int#define iDat 1 //数据标志#define iCmd 0 //指令标志#define LCDb_RS 0x20 //定义四个控制引脚#define LCDb_RW 0x40#define LCDb_E 0x80#define LCDb_RST 0x04#define LCDb_L1 0x80 //第一行的地址#define LCDb_L2 0x90 //第二行的地址#define LCDb_L3 0x88 //第三行的地址#define LCDb_L4 0x98 //第四行的地址#define LCDb_SET_RS P1OUT|=LCDb_RS //四个控制管脚的控制操作#define LCDb_SET_RW P1OUT|=LCDb_RW#define LCDb_SET_E P1OUT|=LCDb_E#define LCDb_SET_RST P8OUT|=LCDb_RST#define LCDb_CLR_RS P1OUT&=~LCDb_RS#define LCDb_CLR_RW P1OUT&=~LCDb_RW#define LCDb_CLR_E P1OUT&=~LCDb_E#define LCDb_CLR_RST P8OUT&=~LCDb_RST#define LCDb_DO P4OUT //输出数据总线端口定义#define LCDb_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符#define LCDb_BASCMD 0x30 // 基本指令集#define LCDb_CLS 0x01 // 清屏#define LCDb_HOME 0x02 // 地址返回原点,不改变DDRAM 内容#define LCDb_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动#define LCDb_C2L 0x10 // 光标左移#define LCDb_C2R 0x14 // 光标右移#define LCDb_D2L 0x18 // 屏幕左移#define LCDb_D2R 0x1C // 屏幕又移#define LCDb_ON 0x0C // 打开显示#define LCDb_OFF 0x08 // 关闭显示unsigned char RXData;unsigned char Seg_Data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x 6f} ; //数码管编码unsigned char Result[5]; //整数转化成字符串,给LCD显示void Delayms(uint MS){uint i,j;for( i=0;i<ms;i++)< bdsfid="104" p=""></ms;i++)<>for(j=0;j<1141;j++);}void Delayus(uint US){uint i;US=US*5/4;for( i=0;i<us;i++);< bdsfid="112" p=""></us;i++);<>}void LCD12864_portini()P1DIR=0xFF;P4DIR=0xFF;P5DIR=0xFF;P8DIR=0xFF;P8OUT |=LCDb_RST;// P1OUT=0xFF;}/*函数名称: LCD12864_sendbyte功能: 向12864液晶写入一个字节数据或者指令*/void LCD12864_sendbyte(uchar DatCmd, uchar dByte) {if (DatCmd == iCmd) //指令操作LCDb_CLR_RS;elseLCDb_SET_RS;LCDb_CLR_RW; //写操作LCDb_SET_E;LCDb_DO = dByte; //写入数据//Delayus(500);Delayms(1);LCDb_CLR_E;}/*函数名称: LCD12864_sendstr功能: 向12864液晶写入一个字符串参数: ptString--字符串指针返回值 : 无*/void LCD12864_sendstr(uchar *ptString)while((*ptString)!='\0') //字符串未结束一直写{LCD12864_sendbyte(iDat, *ptString++);}}/*函数名称: LCD12864_clear功能: 12864液晶清屏参数: 无返回值 : 无*/void LCD12864_clear(void){LCD12864_sendbyte(iCmd,LCDb_CLS);Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的}/*函数名称: LCD12864_gotoXY功能: 移动到指定位置参数: Row--指定的行Col--指定的列返回值 : 无*/void LCD12864_gotoXY(uchar Row, uchar Col){switch (Row) //选择行{case 2:LCD12864_sendbyte(iCmd, LCDb_L2 + Col); break; //写入第2行的指定列case 3:LCD12864_sendbyte(iCmd, LCDb_L3 + Col); break; //写入第3行的指定列case 4:LCD12864_sendbyte(iCmd, LCDb_L4 + Col); break; //写入第4行的指定列default:LCD12864_sendbyte(iCmd, LCDb_L1 + Col); break; //写入第1行的指定列}}/*函数名称: LCD12864_initial功能: 12864液晶初始化*/void LCD12864_initial(void){Delayms(100); // 等待内部复位LCD12864_portini(); //端口初始化LCD12864_sendbyte(iCmd, LCDb_FUNCTION); //功能、模式设定LCD12864_sendbyte(iCmd, LCDb_ON); //打开显示LCD12864_clear(); //清屏LCD12864_sendbyte(iCmd, LCDb_ENTRY); // 输入模式设定}void Int_char(int data){if(data/1000){Result[0]=data/1000+'0';Result[1]=data/100%10+'0';Result[2]=data/10%10+'0';Result[3]=data%10+'0';Result[4]=0;}else if(data/100){Result[0]=data/100+'0';Result[1]=data/10%10+'0';Result[2]=data%10+'0';Result[3]=0;}else if(data/10){Result[0]=data/10%10+'0';Result[1]=data%10+'0';Result[2]=0;}else{Result[0]=data%10+'0';Result[1]=0;}}unsigned char Key_Press(void){P7OUT=0xF0;if((P7IN&0x10)&&(P7IN&0x20)&&(P7IN&0x40)&&(P7IN&0 x80)) return 0x00; else return 0xFF;}unsigned char Get_Keycode(void){while(1)P7OUT=0xFE; //扫描第一列if((P7IN&0x10)==0) return 0;else if((P7IN&0x20)==0) return 4;else if((P7IN&0x40)==0) return 8;else if((P7IN&0x80)==0) return 12;P7OUT=0xFD; //扫描第二列if((P7IN&0x10)==0) return 1;else if((P7IN&0x20)==0) return 5;else if((P7IN&0x40)==0) return 9;else if((P7IN&0x80)==0) return 13;P7OUT=0xFB; //扫描第三列if((P7IN&0x10)==0) return 2;else if((P7IN&0x20)==0) return 6;else if((P7IN&0x40)==0) return 10;else if((P7IN&0x80)==0) return 14;P7OUT=0xF7; //扫描第四列if((P7IN&0x10)==0) return 3;else if((P7IN&0x20)==0) return 7;else if((P7IN&0x40)==0) return 11;else if((P7IN&0x80)==0) return 15;}}void Init_compa(){CACTL1 = CAON+CAREF_2+CARSEL; // Enable Comp, ref = 0.5*Vcc = Vin- CACTL2 = P2CA0; // Pin to CA0P1DIR |= 0x01; // P1.0 = o/p direction(CAOUT - LED) P1SEL |= 0x01; // P1.0 - CAOUT, option select}** 函数名称:初始化函数*/void Init_IIC(void){P3SEL |= 0x06; // Assign I2C pins to USCI_B0UCB0CTL1 |= UCSWRST; // Enable SW resetUCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous modeUCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW resetUCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHzUCB0BR1 = 0;UCB0I2CSA = 0x50; // Slave Address is 048hUCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt_BIS_SR(GIE);// RXCompare = 0x0; // Used to check incoming data }/** 函数名称:字节写函数*/void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word){while (UCB0CTL1 & UCTXSTP); // 确定总线空闲UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为发送模式UCB0TXBUF = high_Address; // 发送高位地址while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = low_Address; // 发送低位地址while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = Word; // 发送数据while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0CTL1 |= UCTXSTP; // 发送停止位while((UCB0CTL1 & UCTXSTP)==1); // 判断停止位是否发送完毕}/**** 函数名称:字节读函数*/void EEPROM_readmore(){UCB0CTL1 &= ~UCTR; // 确定为读while (UCB0CTL1 & UCTXSTP); // 总线是否空闲UCB0CTL1 |= UCTXSTT; // 发送开始位}/*** 函数名称:字节写函数**/void EEPROM_read(unsigned char high_Address,unsigned char low_Address){while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为写UCB0TXBUF = high_Address; // 发送地址位高位while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = low_Address; // 发送地址位低位while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0CTL1 &= ~UCTR; // 确定为接收while (UCB0CTL1 & UCTXSTP); //UCB0CTL1 |=UCTXSTT ;while((UCB0CTL1 & UCTXSTT)==1);for(unsigned char i=0x0;i<0x2f;i++); // 延时确定数据已经被发送出去UCB0CTL1 |=UCTXSTP + UCTXNACK; // 发送停止位和NACK 位}/*** 函数名称:接收中断函数**/// USCI_B0 Data ISR#pragma vector = USCIAB0TX_VECTOR__interrupt void USCIAB0TX_ISR(void){RXData = UCB0RXBUF; // Get RX dataInt_char(RXData);LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr(Result);/*key_code[0]=RXData%10+'0';key_code[1]=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr(key_code);*/// __bic_SR_register_on_exit(CPUOFF); // Exit LPM0}void Init_UART(){P3OUT &= ~(BIT4+BIT5+BIT6+BIT7);P3SEL = 0xF0; // P3.4,5,6,7 = USCI_A0 TXD/RXD USCI_A1 TXD/RXDUCA0CTL1 |= UCSSEL_1; // CLK = ACLKUCA0BR0 = 0x03; // 32kHz/9600 = 3.41UCA0BR1 = 0x00; //UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt UCA1CTL1 |= UCSSEL_1; // CLK = ACLKUCA1BR0 = 0x03; // 32kHz/9600 = 3.41UCA1BR1 = 0x00; //UCA1MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UC1IE |= UCA1RXIE; // Enable USCI_A0 RX interrupt _BIS_SR(GIE); //使能中断}void Init_ADC(){ADC12CTL0 = SHT0_2 + ADC12ON; // Set sampling time, turn on ADC12 ADC12CTL1 = SHP; // Use sampling timer ADC12IE = 0x01; // Enable interruptADC12CTL0 |= ENC; // Conversion enabledP6DIR &= 0x01; // P6.0, i/pP6SEL |= 0x01; // P6.0-ADC option select_BIS_SR(GIE); //使能中断}void Start_ADC(){ADC12CTL0 |= ADC12SC; // Start convn, software controlled }#pragma vector=USCIAB0RX_VECTOR__interrupt void USCI0RX_ISR(void){while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // TX -> RXed characterLCD12864_sendbyte(iDat,UCA0RXBUF);}#pragma vector=USCIAB1RX_VECTOR__interrupt void USCI1RX_ISR(void){while (!(UC1IFG&UCA1TXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = UCA1RXBUF; // TX -> RXed characterLCD12864_sendbyte(iDat,UCA0RXBUF);//UCA1TXBUF = 'z';}// ADC12 interrupt service routine#pragma vector=ADC12_VECTOR__interrupt void ADC12_ISR (void){int i=ADC12MEM0;Int_char(i);LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr(Result);/*key_code[0] =i/1000+'0';key_code[1] =i/100%10+'0';key_code[2] =i/10%10+'0';key_code[3] =i%10+'0';key_code[4] =0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr(key_code);*/}void Init_all(){LCD12864_initial(); //LCD初始化,包含了数码管和LED灯初始化P7DIR=0x0F; //键盘扫描初始化P7REN=0xF0; //输入上下拉电阻使能,输出上下拉不使能P7OUT=0xF0; //输入上拉Init_UART(); //串口初始化Init_compa(); //比较器初始化Init_ADC(); //ADC初始化Init_IIC(); //IIC初始化}void Test_Led(){unsigned char i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("1.Test_LED");for(;i<16;i++){P8OUT=0xF0|i;Delayms(50);}}void Test_Seg(){int i;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("2.Test_SEG");for(i=0;i<500;i++){//4,3,2,1P1OUT&=~0x02;P1OUT|=0x10|0x08|0x04;P5OUT=Seg_Data[9]; //清楚数码管显示Delayms(1); P1OUT&=~0x04;P1OUT|=0x10|0x08|0x02;P5OUT=Seg_Data[8]; //清楚数码管显示Delayms(1); P1OUT&=~0x08;P1OUT|=0x10|0x04|0x02;P5OUT=Seg_Data[7]; //清楚数码管显示Delayms(1); P1OUT&=~0x10;P1OUT|=0x08|0x04|0x02;P5OUT=Seg_Data[6]; //清楚数码管显示Delayms(1); }P5OUT=0x00; //熄灭所有数码管}void Test_Key(){unsigned char i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("3.Test_KEY");LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr("按键:");for(;i<16;i++){Int_char(Get_Keycode());LCD12864_gotoXY(2,3);LCD12864_sendstr(" ");LCD12864_gotoXY(2,3);LCD12864_sendstr(Result);Delayms(100); //防抖}}void Test_Uart(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("4.Test_UART");LCD12864_gotoXY(2,0); //第2行,第1列显示}void Test_Compa(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("5.Test_COMPA");}void Test_ADC(){int i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("6.Test_ADC");for(;i<200;i++){Start_ADC();Delayms(10);}}void Test_IIC(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("7.Test_IIC");EEPROM_Write(0x00,0x40,7); // 字节写Delayms(10);EEPROM_read(0x00,0x40);}void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;//关闭看门狗Init_all();while(1){Test_Led(); //1.测试LEDLCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Seg(); //2.测试数码管LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Key(); //3.测试按键扫描LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();LCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("请按16键!");Test_Uart(); //4.测试串口while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Compa(); //5.测试比较器LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_ADC(); //6.测试ADCLCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_IIC(); //7.测试IICDelayms(100);LCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("测试完成");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();}}。
长沙学院《单片机原理及应用》课程设计说明书题目 LCD12864液晶显示电子钟设计系(部)专业(班级)姓名学号指导教师起止日期《单片机原理及应用》课程设计任务书系(部):专业:课题名称LCD12864液晶显示电子钟设计设计内容及要求1、课题内容:设计一种基于AT89S52 单片机的液晶显示电子时钟,要求如下:(1)、能正确显示时间、日期和星期显示格式为:时间:XX 小时:XX 分:XX 秒;日期:XX 年:XX 月:XX 日;星期:X。
(2)、时间能够由按键调整,误差小于1S。
(3)、闹钟功能:时间运行到与闹钟设定时间时,闹钟响(持续响3秒)。
(4)、报时功能:时间运行到正点时间时,闹钟响,几点钟就响几声(每声持续响2 秒,每两声之间时间间隔1 秒)。
液晶显示器第一行显示“数字电子钟”;第二行显示“当前时间”;第三行显示日期和星期;第四行显示最近一个闹钟的设定时间。
2、要求:完成该系统的硬件和软件的设计,在Proteus 软件上仿真通过,并提交一篇课程设计说明书。
设计工作量1、汇编或C51 语言程序设计;2、程序调试;3、在Proteus 上进行仿真成功,进行实验板下载调试;4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序分析、仿真分析、调试过程,参考文献、设计总结等。
进度安排起止日期设计内容(或预期目标)备注第一天课题介绍,答疑,收集材料,C51介绍第二天设计方案论证,练习编写C51程序第三天——第六天程序设计第六天——第八天程序调试、仿真第九天——第十天系统测试并编写设计说明书教研室意见年月日系(部)主管领导意见年月日目录一、整体方案设计 (4)1、单片机的选择 (4)2、单片机结构 (4)二、前期准备 (5)三、程序设计 (8)1、键盘约定 (8)2、界面显示 (9)3、全局变量的定义 (9)4、系统时钟 (9)5、闹钟控制时间的设定 (9)四、总结与体会 (10)参考文献 (11)一、整体方案设计1、单片机的选择单片微型计算机主要由微处理器、存储器、I/O接口电路等组成。
毕业论文12864多功能数字钟题目:多功能数字钟摘要此多功能数字钟系统以89C55单片机作为控制核心,其外围电路包括时钟闹钟模块、温度测量模块、交流电电压测量及过欠压报警模块、交流电频率测量模块。
其中使用串行时钟芯片PCF8563,实现时间的显示设置和闹钟功能。
通过温度传感器AD590、 AC-DC转换芯片AD536及模数转换芯片ICL7135实现温度和交流电压的测量。
利用波形转换电路和单片机内部定时器测量交流电的频率。
利用光电开关实现非接触关闭闹钟功能。
本系统很好的完成了题目要求的基本及发挥要求,并进行了进一步的扩展。
关键词:89C55单片机 AD536 ICL7135目录1、引言 (3)2、方案论证与比较 (3)3、系统原理框图 (3)4、主要电路设计与计算..................................................................4 4.1基本功能部分 (4)4.2温度测量部分 (8)4.3交流电特性测量部分..................................................................11 5、系统软件工作流程图 (14)5.1软件说明 (14)5.2系统软件流程图 (14)6、系统性能测试与分析 (15)6.1测试仪器 (15)6.2测试方法与数据 (15)6.3时钟及闹钟功能测试 (15)6.4温度测试 (15)6.5交流电电压测试及过欠压报警 (15)6.6交流电频率测试 (16)7、误差分析 (17)结论 (18)致谢 (19)参考文献 (20)1、引言本题目的是设计一个数字时钟,要求具有24小时时间、闹钟设置并具有闹铃功能。
同时要求有对环境温度及供电电源特性进行测量的扩展功能。
我们提出了以下几种方案:2、方案论证与比较1)方案一这是一种纯硬件电路系统。
各功能采用分离的硬件电路模块实现。
/************************************************************************** 在无字库的12864LCD上显示时、分、秒;没有用时钟芯片MCU:STC89C52晶振:11.0592MHz作者:罗元俊时间:2014.06.25**************************************************************************/ #include <reg52.h>typedef unsigned char uchar;typedef unsigned int uint;#define Port P0 // 数据端口#define Disp_On 0x3f // 开显示#define Disp_Off 0x3e // 关显示#define Col_Add 0x40 // 列地址#define Page_Add 0xb8 // 页地址#define Start_Line 0xc0 // 起始页sbit RS = P2^6;sbit RW = P2^5;sbit EN = P2^7;sbit CS1 = P3^2;sbit CS2 = P3^3;uint t = 0; //全局变量:秒表(用于计数时间的增量)uchar sec,min,hour; // 全局变量:秒、分、时uchar a,b,c,d,e,f; // 秒、分、时的个位和十位uchar code HZ_tab[][32] = {{/*-- 文字: 潜--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0xC2,0x0C,0x80,0x10,0x94,0x54,0x3F,0x54,0x90,0x54,0x3F,0x54,0x94,0x10,0x00,0x04,0x04,0x7E,0x01,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x01,0x00},{/*-- 文字: 龙--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x10,0x11,0x16,0xD0,0x10,0x10,0x00,0x80,0x40,0x20,0x18,0x06,0x41,0x20,0x10,0x3F,0x44,0x42,0x41,0x40,0x40,0x78,0x00},{/*-- 文字: 花--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x04,0x04,0x04,0x84,0x6F,0x04,0x04,0x04,0xE4,0x04,0x8F,0x44,0x24,0x04,0x04,0x00,0x04,0x02,0x01,0xFF,0x00,0x10,0x08,0x04,0x3F,0x41,0x40,0x40,0x40,0x40,0x78,0x00},{/*-- 文字: 园--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0xFE,0x02,0x42,0x4A,0xCA,0x4A,0x4A,0xCA,0x4A,0x4A,0x42,0x02,0xFE,0x00,0x00,0x00,0xFF,0x40,0x50,0x4C,0x43,0x40,0x40,0x4F,0x50,0x50,0x5C,0x40,0xFF,0x00,0x00},{/*-- 文字: 输--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00},{/*-- 文字: 入--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00},{/*-- 文字: 密--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x8C,0x44,0x04,0xE4,0x04,0x95,0xA6,0x44,0x24,0x14,0x84,0x44,0x94,0x0C,0x00,0x02,0x02,0x7A,0x41,0x41,0x43,0x42,0x7E,0x42,0x42,0x42,0x43,0xF8,0x00,0x00,0x00},{/*-- 文字: 码--*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x04,0x84,0xE4,0x5C,0x44,0xC4,0x00,0x02,0xF2,0x82,0x82,0x82,0xFE,0x80,0x80,0x00,0x02,0x01,0x7F,0x10,0x10,0x3F,0x00,0x08,0x08,0x08,0x08,0x48,0x88,0x40,0x3F,0x00}};uchar code SZ_tab[][16] = {{/*-- 文字: 0 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00}, //0 {/*-- 文字: 1 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, //1 {/*-- 文字: 2 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00}, //2 {/*-- 文字: 3 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00}, //3 {/*-- 文字: 4 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00}, //4{/*-- 文字: 5 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00}, //5 {/*-- 文字: 6 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00}, //6 {/*-- 文字: 7 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, //7 {/*-- 文字: 8 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00}, //8 {/*-- 文字: 9 --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}, //9 {/*-- 文字: - --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, //10 {/*-- 文字: : --*//*-- 新宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00} //11 };void delayms(uint xms) //延时子程序{uint x,y;for(x = xms;x > 0;x--)for(y = 2;y > 0;y--);}void DetBusybit(void) //忙位检测子程序{Port = 0xff; //读状态值时,先给数据端口赋高电平RS = 0;RW = 1;EN = 1;while(Port & 0x80); //如果LCD处于忙状态,程序就此停止delayms(2);EN = 0;}void LCD_WrCom_L(uchar com) // 写左半屏指令子程序{DetBusybit();CS1 = 1; CS2 = 0;RS = 0;RW = 0;EN = 1;Port = com;delayms(5);EN = 0;}void LCD_WrCom_R(uchar com) // 写右半屏指令子程序{DetBusybit();CS1 = 0; CS2 = 1;RS = 0;RW = 0;EN = 1;Port = com;delayms(5);EN = 0;}void LCD_WrDat_L(uchar dat) // 写左半屏数据子程序{DetBusybit();CS1 = 1; CS2 = 0;RS = 1;RW = 0;EN = 1;Port = dat;delayms(5);EN = 0;}void LCD_WrDat_R(uchar dat) // 写右半屏数据子程序{DetBusybit();CS1 = 0; CS2 = 1;RS = 1;RW = 0;EN = 1;Port = dat;delayms(5);EN = 0;}void Clear_L(void) // 左半屏清屏{uchar i,j;CS1 = 1; CS2 = 0;LCD_WrCom_L(Page_Add + 0);LCD_WrCom_L(Col_Add + 0);for(j = 0; j < 8; j++)LCD_WrCom_L(Page_Add + j);for(i = 0; i < 64; i++)LCD_WrDat_L(0x00);}void Clear_R(void) // 右半屏清屏{uchar i,j;CS1 = 0; CS2 = 1;LCD_WrCom_R(Page_Add + 0);LCD_WrCom_R(Col_Add + 0);for(j = 0; j < 8; j++)LCD_WrCom_R(Page_Add + j);for(i = 0; i < 64; i++)LCD_WrDat_R(0x00);}void Disp_HZ_L(uchar pag,uchar col,uchar n) // 显示左半屏汉字16*16 {uchar i = 0,j = 0;CS1 = 1; CS2 = 0;for(i = 0; i < 2; i++){LCD_WrCom_L(Page_Add + pag + i);LCD_WrCom_L(Col_Add + col);for(j = 0; j < 16; j++)LCD_WrDat_L(HZ_tab[n][16*i+j]);}}void Disp_SZ_L(uchar pag,uchar col,uchar n) // 显示左半屏数字8*16 {uchar i = 0,j = 0,k = 0;CS1 = 1; CS2 = 0;for(i = 0; i < 2; i++){LCD_WrCom_L(Page_Add + pag + i);LCD_WrCom_L(Col_Add + col);for(j = 0; j < 8; j++){LCD_WrDat_L(SZ_tab[n][8*i+j]);}}}void Disp_HZ_R(uchar pag,uchar col,uchar n) // 显示右半屏汉字16*16 {uchar i = 0,j = 0;CS1 = 0; CS2 = 1;for(i = 0; i < 2; i++){LCD_WrCom_R(Page_Add + pag + i);LCD_WrCom_R(Col_Add + col);for(j = 0; j < 16; j++)LCD_WrDat_R(HZ_tab[n][16*i+j]);}}void Disp_SZ_R(uchar pag,uchar col,uchar n) // 显示右半屏数字8*16 {uchar i = 0,j = 0;CS1 = 0; CS2 = 1;for(i = 0; i < 2; i++){LCD_WrCom_R(Page_Add + pag + i);LCD_WrCom_R(Col_Add + col);for(j = 0; j < 8; j++){LCD_WrDat_R(SZ_tab[n][8*i+j]);}}}void TimerInit(void) //定时器初始化函数{TMOD = 0x02; //设置定时器0为工作模式2TH0 = 0x47; //装初值TL0 = 0x47; //设定时间为0.2msEA = 1;ET0 = 1;TR0 = 1; //启动定时器0}void LCD_Init(void) // LCD初始化子程序{delayms(10);LCD_WrCom_L(Disp_Off); LCD_WrCom_R(Disp_Off);LCD_WrCom_L(Page_Add + 0); LCD_WrCom_R(Page_Add + 0);LCD_WrCom_L(Start_Line + 0); LCD_WrCom_R(Start_Line + 0);LCD_WrCom_L(Col_Add + 0); LCD_WrCom_R(Col_Add + 0);LCD_WrCom_L(Disp_On); LCD_WrCom_R(Disp_On); }void main(void){LCD_Init();TimerInit();Clear_L();Clear_R();while(1){sec = t%60; //秒钟分离min = (t/60)%60; //分钟分离hour = (t/3600)%60; //时钟分离a = sec%10; //秒钟个位分离b = (sec/10)%10; //秒钟十位分离c = min%10; //分钟个位分离d = (min/10)%10; //分钟十位分离e = hour%10; //时钟个位分离f = (hour/10)%10; //时钟十位分?Disp_HZ_L(0,32,0); // 第0页,第16列,第0个字Disp_HZ_L(0,48,1);Disp_HZ_R(0,0,2);Disp_HZ_R(0,16,3);Disp_SZ_L(2,24,2);Disp_SZ_L(2,32,0);Disp_SZ_L(2,40,1);Disp_SZ_L(2,48,4);Disp_SZ_L(2,56,10);Disp_SZ_R(2,0,0);Disp_SZ_R(2,8,6);Disp_SZ_R(2,16,10);Disp_SZ_R(2,24,2);Disp_SZ_R(2,32,7);Disp_SZ_L(4,32,f);Disp_SZ_L(4,40,e);Disp_SZ_L(4,48,11);Disp_SZ_L(4,56,d);Disp_SZ_R(4,0,c);Disp_SZ_R(4,8,11);Disp_SZ_R(4,16,b);Disp_SZ_R(4,24,a);Disp_HZ_L(6,0,4);Disp_HZ_L(6,16,5);Disp_HZ_L(6,32,6);Disp_HZ_L(6,48,7);Disp_SZ_R(6,0,11);}}void timer0(void) interrupt 1{uint i;i++;if(i == 5000) //1s时间到{t++; //秒表计时开始i = 0;}}。
//程序已全部通过硬件测试, 请放心使用。
(没有使用到 DS1302)/************12864 时钟显示函数 *************//****** 实现时间走动、按键控制、蜂鸣器闹铃、温度显示 ******/#include<reg52.h>#include <stdio.h>#define uchar unsigned char#define uint unsigned int/******************** 功能:定义液晶 12864 控制端接口*********************/sbit rs=P2八6;// 注意: rw 控制端始终为低电平,直接在硬件上接低电平sbit en=P2A 7;sbit wd=P2A0; ll 温度传感器信号线/******************** 功能:定义蜂鸣器、按键 接口*********************/sbit beet=P2A2;sbit key1=P1A0;sbit key2=P1A1;sbit key3=P1A2;sbit key4=P"3;ll 北京时间与闹钟时间画面切换 l******************** 功能:定义数据初始值******************************lchar hour=23,minute=59,second=58,count=0;char shi=0,fen=0,miao=0,hm;int years=2012;char month=12,day=30,mm=0,cc=7;uint temp;float f_temp;功能:定义数组字符串/********************/*******************//蜂鸣器定义 //功能选择 //至加 //至减 /******************** *********************/uchar code table1[]={" 幸福牌电子钟"}; uchar code table2[]={"温馨提示:00.0°C "};***************************/ 功能:延时函数void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);} 功能:蜂鸣器响应***********************l void fengmingqi(){ beet=0;delay(1);beet=1;delay(1);}void init_12864(){xieling_shu(1,0x30);//基本指令操作 xieling_shu(1,0x30); //基本指令操作xieling_shu(1,0x0C); //0x0c: 无光标, OXOF: 光标反白显示xieling_shu(1,0x01); // 清屏****************** 功能:液晶 12864 读写数据 ******************/ void xieling_shu(uchar aa,uchar bb) { if(aa==1){rs=0;} if(aa==0){rs=1;} P0=bb;delay(1); en=1; delay(1); en=0; delay(1); ****************** } 功能:液晶 12864 写入地址 ******************/ void xieludizhi(uchar x, uchar y) { switch(x) { case 1: xieling_shu(1,0x80 + y ); return;//return 返回的意思 ****************** case 2: xieling_shu(1,0x90 + y ); return; case 3: xieling_shu(1,0x88 + y ); return; case 4: xieling_shu(1,0x98 + y ); return; } } 功能:液晶 12864 写入字符串 *****************/ void xiezifuchuan(uchar *dd) { while(*dd != '\0') { ****************** xieling_shu(0,*dd++ ); } } 功能:液晶 12864 清屏函数 *********************/ void qingping() { xieling_shu(1,0x01); xieling_shu(1,0x01); xieling_shu(1,0x01); delay(20); //清屏 //清屏 //清屏 ****************** } 功能:液晶 12864 初始化指令操作 ***************** */****************** xieling_shu(1,0x06); } 功能:液晶 12864 初始化字串显示 ******************/ void init_zifu() { xieludizhi(1,0);xiezifuchuan(" xieludizhi(2,0);xiezifuchuan(" xieludizhi(3,0);xiezifuchuan(" 欢迎使用 幸福牌电子钟 订购热线 "); "); "); xieludizhi(4,0);xiezifuchuan("Phone:0777-66914"); qingping();xieludizhi(1,0);xiezifuchuan(table1); delay(1); xieludizhi(4,0);xiezifuchuan(table2); delay(1); xieludizhi(3,5);xiezifuchuan("星期"); 日"); delay(1); delay(1); delay(1); delay(9534); /******************* xieludizhi(2,2);xiezifuchuan('年 月 } 功能:时间、年月日 显示函数 void display() { xieludizhi(3,0); // 显示 时 ********************/ 分秒 /******************* xieling_shu(0,0x30+hour/10); xieling_shu(0,0x30+hour%10); xieling_shu(0,':'); xieling_shu(0,0x30+minute/10); xieling_shu(0,0x30+minute%10); xieling_shu(0,':'); xieling_shu(0,0x30+second/10); xieling_shu(0,0x30+second%10); xieludizhi(2,0); // 显示 年 xieling_shu(0,0x30+years/1000); xieling_shu(0,0x30+years%1000/100); xieling_shu(0,0x30+years%100/10); xieling_shu(0,0x30+years%10); xieludizhi(2,3); // 显示 月 xieling_shu(0,0x30+month/10); xieling_shu(0,0x30+month%10); xieludizhi(2,5); // 显示 日 xieling_shu(0,0x30+day/10); xieling_shu(0,0x30+day%10); } 功能:闹钟(时间、年月日) 显示函数 ********************/ void display1() {xieludizhi(3,0); // 显示 时 分 秒xieling_shu(0,0x30+shi/10);xieling_shu(0,0x30+shi%10);xieling_shu(0,':');xieling_shu(0,0x30+fen/10);xieling_shu(0,0x30+fen%10);xieling_shu(0,':');xieling_shu(0,0x30+miao/10);xieling_shu(0,0x30+miao%10);xieludizhi(2,0); // 显示 年xieling_shu(0,0x30+years/1000);xieling_shu(0,0x30+years%1000/100);xieling_shu(0,0x30+years%100/10);xieling_shu(0,0x30+years%10);xieludizhi(2,3); // 显示 月xieling_shu(0,0x30+month/10);xieling_shu(0,0x30+month%10);xieludizhi(2,5); // 显示 日xieling_shu(0,0x30+day/10);xieling_shu(0,0x30+day%10);void xingqi()switch(cc)case 1: xieludizhi(3,7); xiezifuchuan(一 ");return; case 2: xieludizhi(3,7); xiezifuchuan(二");return; case 3: xieludizhi(3,7); xiezifuchuan(叁");return; case 4: xieludizhi(3,7);xiezifuchuan(四");return; case 5: xieludizhi(3,7);xiezifuchuan(五");return; case 6: xieludizhi(3,7);xiezifuchuan(六"); return; case 7: xieludizhi(3,7);xiezifuchuan('B "); return;void anjian()if(key4==0){delay(1);hm=~hm;while(key4==0);}if(key1==0){delay(1);***************** *********************************** 星期函数 ************************************************ }功能:按键程序 *****************mm++;if(hm!=0){if(mm>=4)mm=0;}if(mm==1){xieludizhi(3,3);xieling_shu(0,0x5f);}if(mm==2){TR0=1;xieludizhi(3,2);xieling_shu(0,0x5f);}if(mm==3){xieludizhi(3,0);xieling_shu(0,0x5f);}if(mm==4){xieludizhi(2,5);xieling_shu(0,0x5f);}if(mm==5){xieludizhi(2,3);xieling_shu(0,0x5f);}if(mm==6){xieludizhi(2,1);xieling_shu(0,0x5f);}if(mm==7){xieludizhi(3,7);xieling_shu(0,0x5f);}if(mm==8){xieludizhi(2,7);xieling_shu(0,0x02);} if(mm>=9){xieludizhi(2,7);xieling_shu(0,0x20);mm=0;} // mm=0; 跳出调整时间while(key1==0);}功能:key2按键力卩减功能*******************/ *****************if(mm==1&&key2==0) //秒加1if(hm==0){TR0=0;delay(1);if(key2==0){second++;if(second>=60){second=0;}}} if(hm!=0){delay(1);if(key2==0){miao++;if(miao>=60){miao=0;}}}while(key2==0);}if(mm==1&&key3==0) //秒减1if(hm==0){TR0=0;delay(1);if(key3==0){second--;if(second<=-1){second=59;}}} if(hm!=0){delay(1);if(key3==0){miao--;if(miao<=-1){miao=59;}}}while(key3==0);}if(mm==2&&key2==0) //分加1{if(hm==0){delay(1);if(key2==0){minute++;if(minute>=60){minute=0;}}} if(hm!=0){delay(1);if(key2==0){fen++;if(fen>=60){fen=0;}}}while(key2==0);}if(mm==2&&key3==0) //分减1{if(hm==0){delay(1);if(key3==0){minute--;if(minute<=-1){minute=59;}}}if(hm!=0){delay(1);if(key3==0){fen--;if(fen<=-1){fen=59;}}}while(key3==0);}if(mm==3&&key2==0) //时加1{ if(hm==0){delay(1);if(key2==0){hour++;i f(hour>=24){hour=0;}}}if(hm!=0){delay(1);if(key2==0){shi++;if(shi>=24){shi=0;}}}while(key2==0);}if(mm==3&&key3==0) //时减1{ if(hm==0){delay(1);if(key3==0){hour--;if (hour<=-1){hour=23;}}}if(hm!=0){delay(1);if(key3==0){shi--;if(shi<=-1){shi=23;}}}while(key3==0);}if(mm==4&&key2==0) // 日加1{delay(1);if(key2==0){ day++; if(day>=31){day=1;} }while(key2==0);}if(mm==4&&key3==0) // 日减1{delay(1);if(key3==0){ day--; if(day<=0){day=31;} }while(key3==0);}if(mm==5&&key2==0) // 月加1{delay(1);if(key2==0){month++;if(month>=13){month=1;}}while(key2==0);}if(mm==5&&key3==0) // 月减1{delay(1);if(key3==0){month--;if(month<=0){month=12;}}while(key3==0);}if(mm==6&&key2==0) //年加1{delay(1);if(key2==0){years++;}// 不设置年限while(key2==0);}if(mm==6&&key3==0) // 年减1{delay(1);if(key3==0){years--;}while(key3==0);}if(mm==7&&key2==0) // 星期加1{ delay(1);if(key2==0){cc++;if(cc>=8){cc=1;}} while(key2==0);}if(mm==7&&key3==0) // 星期减1{delay(1);if(key3==0){cc--;if(cc==0){cc=7;}}while(key3==0);}}****************************************************************** *****************************************************void dsreset(void){uint i;wd=0;i=103;while(i>0)i--;wd=1;i=4;bit tempreadbit(void){uint i;bit dat;wd=0;i++; //i++ 起延时作用wd=1;i++;i++;dat=wd;i=8;while(i>0)i--;return (dat); uchar tempread(void){uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面, 这样刚好一个字节在DAT 里}return(dat);******************************* 功能: 18B20 所有函数 ***************** 18B20 复位,初始化函数 ***************************************** while(i>0)i--; } 18B20读 1 位 函数 ***************************************** }18B20 读 1 个字节 函数************************void tempwritebyte(uchar dat){uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb) // 写 1{wd=0;i++;i++;wd=1;i=8;while(i>0)i--;}else{wd=0; //写 0i=8;while(i>0)i--;wd=1;i++;i++;}}}/******************* 18B20 开始获取温度并转换 函数**************************/void tempchange(void){dsreset();delay(1);tempwritebyte(0xcc); // 写跳过读 ROM 指令tempwritebyte(0x44); // 写温度转换指令}/******************* 18B20 读取寄存器中存储的温度数据**************************/uint get_temp(){uchar a,b;dsreset(); delay(1);***************** }18B20 写一个字节数据 函数 ************************函数tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread(); //读低 8 位b=tempread();//读高 8 位 temp=b; temp<<=8; //两个字节组合为 1 个字temp=temp|a;f_temp=temp*0.0625; //温度在寄存器中为 12 位 分辨率位 0.0625°temp=f_temp*10+0.5; //乘以 10 表示小数点后面只取 1 位,加 0.5 是四舍五入f_temp=f_temp+0.05;return temp; //temp 是整型void comm(char *parr){do while(1){ if(count>5&&count<18){tempchange(); //开始获取温度get_temp(); //读取寄存温度 ***************** }18B20 发送数据 函数 ************************{SBUF = *parr++; //发送数据while(!TI);TI=0; }while(*parr);**********************// 等待发送完成标志为 1 //标志清零 //保持循环直到字符为 '\0' } 」r\?r zfefr *************************** void main(){TMOD=0x01;uchar buff[4]; // 设置 T0 为工作方式 1 EA=1; ET0=1; TR0=1; //开启 T0 中断功能:sprintf(buff,"%f",f_temp);comm(buff);xieludizhi(4,5);xieling_shu(0,0x30+ temp/100);xieling_shu(0,0x30+temp%100/10);xieling_shu(0,0x2e);xieling_shu(0,0x30+temp%100%10);if(hm==0)display() ;}// 如果hm=0 显示北京时间,否则显示闹钟时间else display1();anjian(); // 按键判断xingqi(); // 显示星期if(minute==59&&second==59){fengmingqi();} // 整点报时if(shi==hour&&fen==minute&&miao>=second&&miao<=second+3){fengmingq/************************i();}// 闹钟}}功能:中断函数**************************/void time() interrupt 1{ TH0=-50000/256; TL0=-50000%256;count++; if(count==20) { count=0; second++;if(second==60) { second=0; minute++;if(minute==60) { minute=0; hour++; if(hour==24) { hour=0; day++; cc++; if(cc==8) cc=1;if(day==31) { day=1; month++; if(month==13){ month=1; years++;}}}}}}}。
《单片机技术》课程设计说明书基于12864的模拟电子钟摘要单片机应用技术飞速发展,纵观我们现在生活的各个领域,从导弹的导航装置,到飞机上各种仪表的控制,从计算机的网络通讯与数据传输,到工业自动化过程的实时控制和数据处理,以及我们生活中广泛使用的各种智能IC卡、电子宠物等,单片机都起到了举足轻重的作用。
所以单片机技术也日趋成熟。
单片机是集CPU,RAM,ROM,定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强。
而52系列单片机是各单片机中最为典型和最有代表性的一种。
此次单片机课程设计是通过利用52单片机来完成对电子钟的设计,且由12864液晶显示屏来显示时钟信息,并带有DS18B20输出的实时温度显示。
此次课程设计达到了学习、了解单片机相关指令在各方面的应用,以及初步了解开发软、硬件的知识。
关键词 :单片机;12864液晶屏;DS18B20;实时温度ABSTRACTMCUapplication technologyrapid development throughout all areas of life we are now, themissile fromthe navigation deviceto controlavarietyof instruments on theplane, network communicationsand data transfer from thecomputer to thereal-time control and dataprocessingindustrial automation process,andwe live in avariety of widely used smart IC cards, electronicpets, MCU have played a pivotal role.So microcontroller technology matures. MCU is a setof CPU, RAM,ROM, timing, counting, and multiple interfacesin one microcontroller. Its small size,lowcost, high functionality. The 52 Series single-chip microcontrolleris all themost typical and most representative one.Thecourse is designed bythe useof single-chipmicrocontroller52 to complete the electronic clock design, andthe12864 LCD screento display the clockinformationand real-timetemperature displaywith DS18B20 output.The curriculum designed tomeet thelearning and understanding of MCU-related instruction inallaspects of the application, as wellas a preliminary understandingof the development ofsoftware and hardwareknowledge.Key words MCU;12864 LCD screen; DS18B20; real-time temperature目录第一章绪论........................................ 错误!未定义书签。
#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define LCDdata P0//采用并行模式sbit E = P2^7;sbit RW = P2^6;sbit RS = P2^5;sbit RST = P2^4;sbit key1 = P2^0; //时、分、秒选择键sbit key2 = P2^1; //加一键sbit key3 = P2^2; //减一键void init();//void check_busy();void delayms(uint x);void write_com(uchar com);void write_data(uchar date);//void delay(uchar y);void t_bcd();void disp_time();void t_time();uchar code string[]={"00时00分00秒"}; uchar code tab[] ={"长春工业大学"}; uchar code tab1[]={"人文信息学院"}; uchar code tab2[]={"electronic 沈琦"};uchar time[6];//显示缓冲区uchar count;char sec,min,hour;//--------------主函数-----------------void main(){init();while(1){if(count == 200){count = 0;sec++;if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++;if(hour == 24){hour = 0;}}}t_bcd();disp_time();}t_time();}}//-------------初始化----------------void init(){uchar i;// RST = 0;// delayms(1);// RST = 1;// delayms(40);write_com(0x30);write_com(0x0f);write_com(0x01);write_com(0x81);for(i=0;i<12;i++){write_data(string[i]);delayms(5);}write_com(0x90);for(i=0;i<16;i++){write_data(tab[i]);delayms(5);}write_com(0x8a);for(i=0;i<12;i++){write_data(tab1[i]);delayms(5);}write_com(0x98);for(i=0;i<16;i++){write_data(tab2[i]);delayms(5);}TMOD = 0x01;TH0 = (65536-5000)/256;TL0 = (65536-5000)%256;EA = 1;ET0 = 1;TR0 = 1;write_com(0x0c);}//------------毫秒延时--------------- void delayms(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}/*//--------------判忙程序--------------- void check_busy(){// LCDdata = 0xff;RS = 0;RW = 1;// E = 0;E = 1;LCDdata = 0xff;while(LCDdata&0x80);E = 0;}*///------------写命令----------------- void write_com(uchar com){// check_busy();RS = 0;RW = 0;E = 0;LCDdata = com;// delayms(5);E = 1;delayms(5);E = 0;}//-------------写数据------------------ void write_data(uchar date){// check_busy();RS = 1;RW = 0;E = 0;LCDdata = date;// delayms(5);E = 1;delayms(5);E = 0;}//-----------定时中断0------------- void timer0() interrupt 1{TH0 = (65536-5000)/256;TL0 = (65536-5000)%256;count++;}void t_bcd(){time[0] = sec%10;time[1] = sec/10;time[2] = min%10;time[3] = min/10;time[4] = hour%10;time[5] = hour/10;}//--------------时钟时间显示----------------- void disp_time(){write_com(0x85);write_data(0x30+time[1]);write_data(0x30+time[0]);write_com(0x83);write_data(0x30+time[3]);write_data(0x30+time[2]);write_com(0x81);write_data(0x30+time[5]);write_data(0x30+time[4]);}//------------调整时间程序--------------- void t_time(){static uchar num;if(key1 == 0){delayms(5);while(!key1);TR0 = 0;num++;}//-----------------调时-----------------if(num == 1){write_com(0x81);write_com(0x0f);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);hour++;if(hour == 24){hour = 0;}t_bcd();write_data(0x30+time[5]);write_data(0x30+time[4]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);hour--;if(hour == -1){hour = 23;}t_bcd();write_data(0x30+time[5]);write_data(0x30+time[4]);}}}//-----------------调分----------------------if(num == 2){write_com(0x83);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);min++;if(min == 60){min = 0;}t_bcd();write_data(0x30+time[3]);write_data(0x30+time[2]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);min--;if(min == -1){min = 59;}t_bcd();write_data(0x30+time[3]);write_data(0x30+time[2]);}}}//---------------调秒------------------if(num == 3){write_com(0x85);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);sec++;if(sec == 60){sec = 0;}t_bcd();write_data(0x30+time[1]);write_data(0x30+time[0]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);sec--;if(sec == -1){sec = 59;}t_bcd();write_data(0x30+time[1]);write_data(0x30+time[0]);}}}//---------------退出调整时间----------------- if(num == 4){num = 0;write_com(0x0c);TR0 = 1;}}#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define LCDdata P0//采用并行模式sbit RS = P1^0;sbit RW = P1^1;sbit E = P1^2;//sbit RST = P2^4;sbit key1 = P3^0; //时、分、秒选择键sbit key2 = P3^1; //加一键sbit key3 = P3^2; //减一键void init();//void check_busy();void delayms(uint x);void write_com(uchar com);void write_data(uchar date);//void delay(uchar y);void t_bcd();void disp_time();void t_time();uchar code string[]={"00时00分00秒"}; uchar code tab[] ={"农工商学院"}; uchar code tab1[]={"机电系应电"}; uchar code tab2[]={"electronic 星星"};uchar time[6];//显示缓冲区uchar count;char sec,min,hour;//--------------主函数-----------------void main(){init();while(1){if(count == 200){count = 0;sec++;if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++;if(hour == 24){hour = 0;}}}t_bcd();disp_time();}t_time();}}//-------------初始化---------------- void init(){uchar i;// RST = 0;// delayms(1);// RST = 1;// delayms(40);write_com(0x30);write_com(0x0f);write_com(0x01);write_com(0x81);for(i=0;i<12;i++){write_data(string[i]);delayms(5);}write_com(0x92);for(i=0;i<12;i++){write_data(tab[i]);delayms(5);}write_com(0x8a);for(i=0;i<12;i++){write_data(tab1[i]);delayms(5);}write_com(0x98);for(i=0;i<16;i++){write_data(tab2[i]);delayms(5);}TMOD = 0x01;TH0 = (65536-5000)/256;TL0 = (65536-5000)%256;EA = 1;ET0 = 1;TR0 = 1;write_com(0x0c);}//------------毫秒延时--------------- void delayms(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}/*//--------------判忙程序--------------- void check_busy(){// LCDdata = 0xff;RS = 0;RW = 1;// E = 0;E = 1;LCDdata = 0xff;while(LCDdata&0x80);E = 0;}*///------------写命令----------------- void write_com(uchar com){// check_busy();RS = 0;RW = 0;E = 0;LCDdata = com;delayms(5);E = 1;delayms(5);E = 0;}//-------------写数据------------------void write_data(uchar date){// check_busy();RS = 1;RW = 0;E = 0;LCDdata = date;delayms(5);E = 1;delayms(5);E = 0;}//-----------定时中断0-------------void timer0() interrupt 1{TH0 = (65536-5000)/256;TL0 = (65536-5000)%256;count++;}void t_bcd(){time[0] = sec%10;time[1] = sec/10;time[2] = min%10;time[3] = min/10;time[4] = hour%10;time[5] = hour/10;}//--------------时钟时间显示----------------- void disp_time(){write_com(0x85);write_data(0x30+time[1]);write_data(0x30+time[0]);write_com(0x83);write_data(0x30+time[3]);write_data(0x30+time[2]);write_com(0x81);write_data(0x30+time[5]);write_data(0x30+time[4]);}//------------调整时间程序---------------void t_time(){static uchar num;if(key1 == 0){delayms(5);while(!key1);TR0 = 0;num++;}//-----------------调时-----------------if(num == 1){write_com(0x81);write_com(0x0f);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);hour++;if(hour == 24){hour = 0;}t_bcd();write_data(0x30+time[5]);write_data(0x30+time[4]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);hour--;if(hour == -1){hour = 23;}t_bcd();write_data(0x30+time[5]);write_data(0x30+time[4]);}}}//-----------------调分----------------------if(num == 2){write_com(0x83);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);min++;if(min == 60){min = 0;}t_bcd();write_data(0x30+time[3]);write_data(0x30+time[2]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);min--;if(min == -1){min = 59;}t_bcd();write_data(0x30+time[3]);write_data(0x30+time[2]);}}}//---------------调秒------------------if(num == 3){write_com(0x85);if(key2 == 0){delayms(5);if(key2 == 0){while(!key2);sec++;if(sec == 60){sec = 0;}t_bcd();write_data(0x30+time[1]);write_data(0x30+time[0]);}}if(key3 == 0){delayms(5);if(key3 == 0){while(!key3);sec--;if(sec == -1){sec = 59;}t_bcd();write_data(0x30+time[1]);write_data(0x30+time[0]);}}}//---------------退出调整时间----------------- if(num == 4){num = 0;write_com(0x0c);TR0 = 1;}}。