12864显示动态时钟
- 格式:doc
- 大小:599.00 KB
- 文档页数:7
12864液晶电子钟具有按键可调闹钟温度显示理解才是最主要程序已全部通过硬件测试,请放心使用。
(没有使用到DS1302)/某某某某某某某某某某某某12864时钟显示函数某某某某某某某某某某某某某//某某某某某某实现时间走动、按键控制、蜂鸣器闹铃、温度显示某某某某某某/#include<reg52.h>#include<tdio.h>#defineucharunignedchar#defineuintunignedint/某某某某某某某某某某某某某某某某某某某某功能:定义液晶12864控制端接口某某某某某某某某某某某某某某某某某某某某某/bitr=P2^6;//注意:rw控制端始终为低电平,直接在硬件上接低电平biten=P2^7;bitwd=P2^0;//温度传感器信号线/某某某某某某某某某某某某某某某某某某某某功能:定义蜂鸣器、按键接口某某某某某某某某某某某某某某某某某某某某某/bitbeet=P2^2;//蜂鸣器定义bitkey1=P1^0;//功能选择bitkey2=P1^1;//至加bitkey3=P1^2;//至减bitkey4=P1^3;//北京时间与闹钟时间画面切换/某某某某某某某某某某某某某某某某某某某某功能:定义数据初始值某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/charhour=23,minute=59,econd=58,count=0;charhi=0,fen=0,miao=0,hm;intyear=2022;charmonth=12,day=30,mm=0,cc=7;uinttemp;floatf_temp;/某某某某某某某某某某某某某某某某某某某某功能:定义数组字符串某某某某某某某某某某某某某某某某某某某某某/ucharcodetable1[]={"幸福牌电子钟"};ucharcodetable2[]={"温馨提示:00.0℃"};/某某某某某某某某某某某某某某某某某某某某功能:延时函数某某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddelay(uintz){uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}/某某某某某某某某某某某某某某某某某某某功能:蜂鸣器响应某某某某某某某某某某某某某某某某某某某某某某某/voidfengmingqi(){beet=0;delay(1);beet=1;delay(1);}理解才是最主要/某某某某某某某某某某某某某某某某某某某某功能:液晶12864读写数据某某某某某某某某某某某某某某某某某某/void某ieling_hu(ucharaa,ucharbb){if(aa==1){r=0;}if(aa==0){r=1;}P0=bb;delay(1);en=1;delay(1);en=0;delay(1);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入地址某某某某某某某某某某某某某某某某某某/void某ieludizhi(uchar某,uchary){witch(某){cae1:某ieling_hu(1,0某80+y);return;//return返回的意思cae2:某ieling_hu(1,0某90+y);return;cae3:某ieling_hu(1,0某88+y);return;cae4:某ieling_hu(1,0某98+y);return;}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864写入字符串某某某某某某某某某某某某某某某某某/void某iezifuchuan(uchar某dd){while(某dd!='\0'){某ieling_hu(0,某dd++);}}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864清屏函数某某某某某某某某某某某某某某某某某某某某某/voidqingping(){某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏某ieling_hu(1,0某01);//清屏delay(20);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化指令操作某某某某某某某某某某某某某某某某某某/voidinit_12864(){某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某30);//基本指令操作某ieling_hu(1,0某0C);//0某0c:无光标,O某OF:光标反白显示某ieling_hu(1,0某01);//清屏理解才是最主要某ieling_hu(1,0某06);}/某某某某某某某某某某某某某某某某某某某某功能:液晶12864初始化字串显示某某某某某某某某某某某某某某某某某某/voidinit_zifu(){某ieludizhi(1,0);某iezifuchuan("欢迎使用");delay(1);某ieludizhi(2,0);某iezifuchuan("幸福牌电子钟");delay(1);某ieludizhi(3,0);某iezifuchuan("订购热线");delay(1);某ieludizhi(4,0);某iezifuchuan("Phone:0777-66914");delay(9534);qingping();某ieludizhi(1,0);某iezifuchuan(table1);delay(1);某ieludizhi(4,0);某iezifuchuan(table2);delay(1);某ieludizhi(3,5);某iezifuchuan("星期");某ieludizhi(2,2);某iezifuchuan("年月日");}/某某某某某某某某某某某某某某某某某某某功能:时间、年月日显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay(){某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hour/10);某ieling_hu(0,0某30+hour%10);某ieling_hu(0,':');某ieling_hu(0,0某30+minute/10);某ieling_hu(0,0某30+minute%10);某ieling_hu(0,':');某ieling_hu(0,0某30+econd/10);某ieling_hu(0,0某30+econd%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:闹钟(时间、年月日)显示函数某某某某某某某某某某某某某某某某某某某某/voiddiplay1(){理解才是最主要某ieludizhi(3,0);//显示时分秒某ieling_hu(0,0某30+hi/10);某ieling_hu(0,0某30+hi%10);某ieling_hu(0,':');某ieling_hu(0,0某30+fen/10);某ieling_hu(0,0某30+fen%10);某ieling_hu(0,':');某ieling_hu(0,0某30+miao/10);某ieling_hu(0,0某30+miao%10);某ieludizhi(2,0);//显示年某ieling_hu(0,0某30+year/1000);某ieling_hu(0,0某30+year%1000/100);某ieling_hu(0,0某30+year%100/10);某ieling_hu(0,0某30+year%10);某ieludizhi(2,3);//显示月某ieling_hu(0,0某30+month/10);某ieling_hu(0,0某30+month%10);某ieludizhi(2,5);//显示日某ieling_hu(0,0某30+day/10);某ieling_hu(0,0某30+day%10);}/某某某某某某某某某某某某某某某某某某某功能:星期函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ void某ingqi(){witch(cc){cae1:某ieludizhi(3,7);某iezifuchuan("一");return;cae2:某ieludizhi(3,7);某iezifuchuan("二");return;cae3:某ieludizhi(3,7);某iezifuchuan("叁");return;cae4:某ieludizhi(3,7);某iezifuchuan("四");return;cae5:某ieludizhi(3,7);某iezifuchuan("五");return;cae6:某ieludizhi(3,7);某iezifuchuan("六");return;cae7:某ieludizhi(3,7);某iezifuchuan("日");return;}}/某某某某某某某某某某某某某某某某某某某功能:按键程序某某某某某某某某某某某某某某某某某某某/voidanjian(){if(key4==0){delay(1);hm=~hm;while(key4==0);}/某某某某某某某某某某某某某某某某某某某功能:key1按键选择功能某某某某某某某某某某某某某某某某某某某/if(key1==0){delay(1);mm++;if(hm!=0){if(mm>=4)mm=0;}理解才是最主要if(mm==1){某ieludizhi(3,3);某ieling_hu(0,0某5f);}if(mm==2){TR0=1;某ieludizhi(3,2);某ieling_hu(0,0某5f);}if(mm==3){某ieludizhi(3,0);某ieling_hu(0,0某5f);}if(mm==4){某ieludizhi(2,5);某ieling_hu(0,0某5f);}if(mm==5){某ieludizhi(2,3);某ieling_hu(0,0某5f);}if(mm==6){某ieludizhi(2,1);某ieling_hu(0,0某5f);}if(mm==7){某ieludizhi(3,7);某ieling_hu(0,0某5f);}if(mm==8){某ieludizhi(2,7);某ieling_hu(0,0某02);}if(mm>=9){某ieludizhi(2,7);某ieling_hu(0,0某20);mm=0;}//mm=0;跳出调整时间while(key1==0);}/某某某某某某某某某某某某某某某某某某某功能:key2按键加减功能某某某某某某某某某某某某某某某某某某某/if(mm==1&&key2==0)//秒加1{if(hm==0){TR0=0;delay(1);if(key2==0){econd++;if(econd>=60){e cond=0;}}}if(hm!=0){delay(1);if(key2==0){miao++;if(miao>=60){miao=0;}}} while(key2==0);}if(mm==1&&key3==0)//秒减1{if(hm==0){TR0=0;delay(1);if(key3==0){econd--;if(econd<=-1){econd=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){minut e=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++;if(hour>=24){hour=0;}}} if(hm!=0){delay(1);if(key2==0){hi++;if(hi>=24){hi=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){hi--;if(hi<=-1){hi=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){year++;}//不设置年限while(key2==0);}if(mm==6&&key3==0)//年减1{delay(1);if(key3==0){year--;}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);}}/某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某功能:18B20所有函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//某某某某某某某某某某某某某某某某某某某18B20复位,初始化函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voiddreet(void){uinti;wd=0;i=103;while(i>0)i--;wd=1;i=4;while(i>0)i--;}/某某某某某某某某某某某某某某某某某某某18B20读1位函数某某某某某某某某某某某某某某某某某某某某某某某某某某/bittempreadbit(void){uinti;bitdat;wd=0;i++;//i++起延时作用wd=1;i++;i++;dat=wd;i=8;while(i>0)i--;return(dat);}/某某某某某某某某某某某某某某某某某某某18B20读1个字节函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uchartempread(void){uchari,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);理解才是最主要}/某某某某某某某某某某某某某某某某某某某18B20写一个字节数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempwritebyte(uchardat){uinti;ucharj;bittetb;for(j=1;j<=8;j++){tetb=dat&0某01;dat=dat>>1;if(tetb)//写1{wd=0;i++;i++;wd=1;i=8;while(i>0)i--;}ele{wd=0;//写0i=8;while(i>0)i--;wd=1;i++;i++;}}}/某某某某某某某某某某某某某某某某某某某18B20开始获取温度并转换函数某某某某某某某某某某某某某某某某某某某某某某某某某某/voidtempchange(void){dreet();delay(1);tempwritebyte(0某cc);//写跳过读ROM指令tempwritebyte(0某44);//写温度转换指令}/某某某某某某某某某某某某某某某某某某某18B20读取寄存器中存储的温度数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/uintget_temp(){uchara,b;dreet();delay(1);理解才是最主要tempwritebyte(0某cc);tempwritebyte(0某be);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;returntemp;//temp是整型}/某某某某某某某某某某某某某某某某某某某18B20发送数据函数某某某某某某某某某某某某某某某某某某某某某某某某某某/{do{SBUF=某parr++;//发送数据while(!TI);//等待发送完成标志为1TI=0;//标志清零}while(某parr);//保持循环直到字符为'\0'}/某某某某某某某某某某某某某某某某某某某某某某某某功能:主函数某某某某某某某某某某某某某某某某某某某某某某某某某某某某/ voidmain(){ucharbuff[4];TMOD=0某01;//设置T0为工作方式1EA=1;ET0=1;TR0=1;//开启T0中断TH0=-50000/256;TL0=-50000%256;init_12864();init_zifu();hm=0;while(1){if(count>5&&count<18){tempchange();//开始获取温度get_temp();//读取寄存温度printf(buff,"%f",f_temp);某ieludizhi(4,5);某ieling_hu(0,0某30+temp/100);某ieling_hu(0,0某30+temp%100/10);理解才是最主要某ieling_hu(0,0某2e);某ieling_hu(0,0某30+temp%100%10);}if(hm==0)diplay();//如果hm=0显示北京时间,否则显示闹钟时间elediplay1();anjian();//按键判断某ingqi();//显示星期if(minute==59&&econd==59){fengmingqi();}//整点报时if(hi==hour&&fen==minute&&miao>=econd&&miao<=econd+3){fengmi ngqi();}//闹钟}}/某某某某某某某某某某某某某某某某某某某某某某某某功能:中断函数某某某某某某某某某某某某某某某某某某某某某某某某某某/ {TH0=-50000/256;TL0=-50000%256;count++;if(count==20){count=0;econd++;if(econd==60){econd=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;year++; }}} } } } }。
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]);//时间之间的冒号。
/************12864时钟显示函数*************//******实现时间走动、按键控制、蜂鸣器闹铃******/#include<reg52.h>#define uchar unsigned char //宏定义#define uint unsigned int //宏定义sbit rs=P0^7;sbit rw=P0^6;sbit en=P0^5;sbit beet=P0^4; //蜂鸣器定义sbit key1=P3^5; //功能选择sbit key2=P3^4; //至加sbit key3=P3^3; //至减char hour=23;char minute=59;char second=46;int years=2012;char month=12;char day=30;uchar count=0;char mm;char cc;uchar code table1[]={"创新工作室"};uchar code table2[]={" 应用电子"};/*************************延时函数****************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*********地址初始化*************/void xieling_shu(uchar aa,uchar bb){if(aa==1){rs=0;}if(aa==0){rs=1;}rw=0;P2=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初始化显示函数******************/ void init_12864(){ mm=0;cc=7; //选择星期初始化xieling_shu(1,0x30); //基本指令操作xieling_shu(1,0x30); //基本指令操作xieling_shu(1,0x0C); //0x0c: 无光标,OXOF: 光标反白显示xieling_shu(1,0x01); //清屏xieling_shu(1,0x06);}/******************* 液晶12864初始化字串显示******************/ void init_zifu(){//qingping();xieludizhi(1,0);xiezifuchuan(table1); //delay(1);xieludizhi(4,0);xiezifuchuan(table2); //delay(1);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(3,5);xiezifuchuan("星期");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);xiezifuchuan("年");xieling_shu(0,0x30+month/10);xieling_shu(0,0x30+month%10);xiezifuchuan("月");xieling_shu(0,0x30+day/10);xieling_shu(0,0x30+day%10);xiezifuchuan("日");}/***************星期函数***************/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("日"); return;}}/***************按键程序***************/void anjian(){if(key1==0) //key1按键选择功能{ mm++;delay(1);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,5);xieling_shu(0,0x5f);}if(mm==8){xieludizhi(2,7);xieling_shu(0,0x02);}if(mm==9){xieludizhi(2,7);xieling_shu(1,0x01);mm=0;}} //key2按键控制if(mm==1&&key2==0) //秒加1{TR0=0;delay(1);if(key2==0){second++;if(second==60){second=0;}}}if(mm==1&&key3==0) //秒减1{TR0=0;delay(1);if(key3==0){second--;if(second==-1){second=59;}}}if(mm==2&&key2==0) //分加1 { delay(1);if(key2==0){minute++;if(minute==60){minute=0;}}}if(mm==2&&key3==0) //分减1 { delay(1);if(key3==0){minute--;if(minute==-1){minute=59;}}}if(mm==3&&key2==0) //时加1 { delay(1);if(key2==0){hour++;if(hour==24){hour=0;}}}if(mm==3&&key3==0) //时减1 { delay(1);if(key3==0){hour--;if(hour==-1){hour=23;}}}if(mm==4&&key2==0) //日加1 { delay(1);if(key2==0){day++;if(day==31){day=1;}}}if(mm==4&&key3==0) //日减1 { delay(1);if(key3==0){day--;if(day==0){day=30;}}}if(mm==5&&key2==0) //月加1 { delay(1);if(key2==0){month++;if(month==13){month=1;}}}if(mm==5&&key3==0) //月减1 { delay(1);if(key3==0){month--;if(month==0){month=12;}}}if(mm==6&&key2==0) //年加1 { delay(1);if(key2==0){years++;}}if(mm==6&&key3==0) //年减1 { delay(1);if(key3==0){years--;}}if(mm==7&&key2==0) //星期加1 { delay(1);if(key2==0){cc++;if(cc==8){cc=1;}}}if(mm==7&&key3==0) //星期减1 { delay(1);if(key3==0){cc--;if(cc==0){cc=7;}}}}/***************************定时器函数************************/void init_t0_t1() //定时器t0,t1初始化函数{TMOD=0x11;EA=1;ET0=1;TR0=1; //开启中断TH0=(65536-50000)/256;TL0=(65536-50000)%256;}/**************主函数**************/void main(){init_12864();init_t0_t1();while(1){init_zifu();anjian();xingqi();}}/***************中断函数***************/void time() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(hour==0&minute==0&second==0||hour==0&minute==1&second==0||hour==0&minute==1&s econd==5)//采用与或逻辑设定闹铃{beet=0;delay(5);beet=1;}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++;}}。
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}void Write_DS1302(uchar add,uchar dat)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
#include <reg52.h>#include <intrins.h>#include "delay.h"sbit rs = P2^4; //寄存器选择输入sbit rw = P2^5; //液晶读/写控制sbit en = P2^6; //液晶使能控制sbit psb = P2^1; //串/并方式控制uchar table[]="电子时钟";uchar table[]="日期:2014-7-16";uchar table[]="时间:23:23:53";uchar table[]="闹钟:00:00:00";void write_12864com(uchar com); //定义写指令到12864 void write_12864dat(uchar dat); //定义写数据到12864 void init(void); //函数初始化定义void display1(void); //声明一个显示函数void display2(void);void display3(void);void main() //主函数{init();while(1){//display1();//display2();display3();while(1);}}void write_12864com(uchar com) //写指令到12864{rw=0; //低电平写rs=0; //写指令delay_50us(1);P0=com;en=1; //使能信号高电平delay_50us(10);en=0; //使能信号低电平delay_50us(2);}void write_12864dat(uchar dat) //写数据到12864{rw=0; //低电平写rs=1; //写数据delay_50us(1);P0=dat;en=1; //使能信号高电平delay_50us(10);en=0; //使能信号低电平delay_50us(2);}void init(void) //函数初始化{delay_50ms(2); //延时40mswrite_12864com(0x30); //基本指令设置delay_50us(4); //延时100uswrite_12864com(0x30); //功能设置delay_50us(4); //延时100uswrite_12864com(0x0f); //控制D=1整体显示开C=1游标开B=1游标位置反白允许delay_50us(4); //延时100uswrite_12864com(0x01); //屏幕清零delay_50us(240);write_12864com(0x06);delay_50us(10);}void display1(void){uchar i;uchar a;a=0x00;write_12864com(0x80); //设置地址delay_50us(1);for(i=0;i<16;i++){write_12864dat(a);delay_50us(1);a++;}}void display2(void){uchar i;uchar a,b;a=0xBA;b=0xC0;write_12864com(0x80);for(i=0;i<8;i++){write_12864dat(a);write_12864dat(b);delay_50us(1);b++;}}void display3(void){uchar i;write_12864com(0x80);for(i=0;i<16;i++){write_12864dat(table[i]);delay_50us(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;}}。
FPGA实现12864液晶的静\动态显示摘要本文使用FPGA技术实现,通过控制液晶屏的地址,将汉字、字符或图形输入到液晶屏上,通过连续几屏显示实现动态效果。
关键词FPGA;12864lcd;静态显示;动态显示1 芯片和液晶屏介绍本实验所用芯片为ALTERA公司开发的EP1C6Q240C8芯片,cyclone系列,具有240个引脚,工作时最多可同时处理10路控制信号,工作电压为1.4V~3.6V。
液晶屏为12864,显示类型STN ,点阵格式128 x 64 ,点尺寸0.48 x 0.48mm 。
软件编程环境:Altera的Quartus II。
2 焊接板子,原理图如下左侧为EP1C6Q240C8芯片:共有240个引脚,相当于把4块芯片联系在一起,备选的引脚比较多。
右侧为液晶屏引脚,本液晶屏内置汉字库(通过查汉字编码库,得到代码)。
3 静态显示的设计3.1 给data_buffer赋内容constant data_buf0:data_buffer:=(x”a3”,x”c6”,x”a3”,x”d0”,//显示:fpgax”a3”,x”c7”,x”a3”,x”c1”,”x”20”,x”20”,x”20”,x”20”,x”20”,x”20”,x”20”,x”20”);// x”20”代表空格constant data_buf1:data_buffer:=(x”cd”,x”f5”,x”cf”,x”d4”,//显示:王显03x”a3”,x”b0”,x”a3”,x”b3”,x”20”,x”20”,x”20”,x”20” ,x”20”,x”20”,x”20”,x”20”);constant data_buf2与constant data_buf3所赋值均为x”20”,由图片可知,后两行并未输出内容。
x”20”代表空格,即此处不输入内容。
也可根据需要,通过查汉字编码表输入内容。
3.2 分频部分process(clk) //使用晶振为50MHZvariable cnt:integer range 0 to 499;//100k分频我们静态显示的频率是100kbeginif clk=‘1’ and clk’event thenif cnttemp=499 then cnttemp:=0;elseif cnttemprwcnt_1:=cnt_1+1;//此部分也是对液晶初始化。
/*------------------------------------------------------------------------------PC2 PC3 PC4 PC5 PC6 PC7 PA0 PA1 PA2 PA3 PA4 PA5 PA6 PA7RS R/W E PSB NC RST DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7RS高电平写数据,低电平写指令代码.R/W高电平为读,低电平为写E为使能信号,PSB高电平为并行模式,低电平为串行模式,RST低电平有效显示地址:80H,81H,......86H,87H.第一行显示地址90H,91H,......96H,97H.第二行显示地址88H,89H,......8EH,8FH.第二行显示地址98H,99H,......9EH,9FH.第三行显示地址写指令01H:显示清屏,写指令02H: 位址归位,写指令0CH:开显示(无游标,不反白)写指令30H:基本指令集,写指令80H:设置DDRAM,写指令10H:显示HCGROM------------------------------------------------------------------------------*/#include <iom16v.h>#include <macros.h>#define RS_H DDRC |= (1<<2);PORTC |= (1<<2); //RS设为高电平#define RS_L DDRC |= (1<<2);PORTC &= ~(1<<2); //RS设为低电平#define RW_H DDRC |= (1<<3);PORTC |= (1<<3); //RW设为高电平#define RW_L DDRC |= (1<<3);PORTC &= ~(1<<3); //RW设为低电平#define E_H DDRC |= (1<<4);PORTC |= (1<<4); //E设为高电平#define E_L DDRC |= (1<<4);PORTC &= ~(1<<4); //E设为低电平#define RST_H DDRC |= (1<<7);PORTC |= (1<<7); //RST为高电平unsigned char MainMenu0[] = {"第二课堂胜风电子"};unsigned char MainMenu1[] = {"数据为:"};unsigned char Shuzi[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','+'};/***********************函数功能:LCD延时子程序入口参数:t********************/ void delay(unsigned int t){ unsigned int i,j;for(i=0;i<t;i++)for(j=0;j<10;j++);}/***********************函数功能:端口初始化***********************************/ void PORT_init(){ PORTA = 0xFF;DDRA = 0xFF;PORTC = 0xCE;DDRC = 0xCE;}/**********************函数功能:LCD测试忙程序*********************************//**********************RS=L,RW=H,EN=高脉冲,读取忙碌标志DB7(BF)*****************/unsigned char check_busy(){ unsigned char BF; //忙标志BFDDRA = 0X00; //端口A设为输入方式PORTA = 0XFF;delay(1);RS_L; //RS=0(命令)delay(1);RW_H;delay(1);E_H; //EN=1,使能delay(1);BF = PINA; //读取A口数据delay(1);E_L; //EN=0delay(1);DDRA = 0XFF; //端口A设为输出方式BF &= 0x80; //读取lcd_data第八位return (BF); //读取结果返回}/***********************函数功能:写指令数据到lcd子程序入口参数:cmd**********/ /***********************RS=L,RW=L,EN=高脉冲,DB0-DB7=指令码******************/void lcdwc(unsigned char cmd){ while(check_busy()); //判断LCD是否为忙状态RS_L; //RS=0(指令),RW=0(写)RW_L;PORTA = cmd; //向LCD发送指令E_H; //EN=1,使能delay(5);E_L; //EN=0}/***********************函数功能:写入显示数据到lcd子程序入口参数:data*******/ /***********************RS=H,RW=L,EN=高脉冲,DB0-DB7=数据********************/void lcdwd(unsigned char Data){ while(check_busy()); //判断LCD是否为忙状态RS_H; //RS=1(数据),RW=0(写)RW_L;PORTA = Data; //向LCD写数据E_H; //EN=1,使能delay(5);E_L; //EN=0}/***********************函数功能:lcd初始化子程序******************************/ void lcd_init(){ delay(5);lcdwc(0x30); //功能设置8位数据,基本指令delay(5);lcdwc(0x0C); //显示状态ON,游标OFF,反白OFFdelay(5);lcdwc(0x01); //清除显示,并且设定地址指针为00Hdelay(5);lcdwc(0x02); //地址归位delay(5);lcdwc(0x80); //设置DDRAM地址}/**********************函数功能:LCD显示子程序*********************************//**********************入口参数:y是所选择的行号,p为写入的字符串**************/ void Char_Set_XY(unsigned char y, unsigned char *p){if(y == 0){lcdwc((0x80));}if(y == 1){lcdwc((0x90));}if(y == 2){lcdwc((0x88));}if(y == 3){lcdwc((0x98));}while(*p != 0) //没写完就继续写{lcdwd(*p++);}}/**********************函数功能:LCD浮点数显示*********************************//**********************入口参数:M为显示的数据,add为从哪里开始显示数据********/ void display_f(float M,unsigned char add){ unsigned char ledbuf[7]={0,0,0,0,0,0,0};unsigned char i,j,k;unsigned long m;if(M>0) //正实数处理{ ledbuf[0] = 12;m = M;if(M<10000) {m = 10*M;}if(M<1000) {m = 100*M;}if(M<100) {m = 1000*M;}if(M<10) {m = 10000*M;}}if(M<0) //负实数处理{ ledbuf[0] = 11;m = -1*M;if(M>-10000) {m = -10*M;}if(M>-1000) {m = -100*M;}if(M>-100) {m = -1000*M;}if(M>-10) {m = -10000*M;}}ledbuf[1]=m/10000; //万位ledbuf[2]=m%10000/1000; //千位ledbuf[3]=m%1000/100; //百位ledbuf[4]=m%1000%100/10; //十位ledbuf[5]=m%1000%100%10; //个位ledbuf[6]=10; //小数点if(M>=0) //+号处理{ if(M<10000) { ledbuf[6] = ledbuf[5];ledbuf[5] = 10;}if(M<1000) { ledbuf[5] = ledbuf[4];ledbuf[4] = 10;}if(M<100) { ledbuf[4] = ledbuf[3];ledbuf[3] = 10;}if(M<10) { ledbuf[3] = ledbuf[2];ledbuf[2] = 10;}}if(M<0) //-号处理{ if(M>-10000) { ledbuf[6] = ledbuf[5];ledbuf[5] = 10; }if(M>-1000) { ledbuf[5] = ledbuf[4];ledbuf[4] = 10; }if(M>-100) { ledbuf[4] = ledbuf[3];ledbuf[3] = 10; }if(M>-10) { ledbuf[3] = ledbuf[2];ledbuf[2] = 10; }}lcdwc(add);for(k=0;k<7;k++){ i = ledbuf[k];j = Shuzi[i];lcdwd(j);}}/***********************函数功能:主函数***************************************/ void main(void){ float i = 168.88;PORT_init(); //端口初始化lcd_init(); //初始化LCD屏RST_H;Char_Set_XY(0,MainMenu0); //第一行显示Char_Set_XY(1,MainMenu1); ////第二行显示while(1){ //delay(1000);display_f(i,0x94);delay(100);//i += 0.02;//delay(1000);}}。
128*64代码进化版显示时,分,秒显示结果:芯片晶振11.0592#include ;#define uchar unsigned char #define uint unsigned int#define dataport P0//数据口sbit CS1=P2^4;//左显引脚sbit CS2=P2^3;//右显引脚sbit RST=P2^2;//复位引脚sbit rs=P2^7;//数据或指令寄存器引脚sbit rw=P2^6;//读或写操作引脚sbit en=P2^5;//读写时能引脚void delay(unsigned long v); //延时void wcode(uchar c,uchar csl,uchar csr); //写指令void wdata(uchar c,uchar csl,uchar csr); //写数据void set_startline(uchar i);//设置起始行void set_xy(uchar x,uchar y);//设置X,Y方向void dison_off(uchar k);//显示器开或关void reset();//复位void lcd_init();//显示器初始化void lw(uchar x,uchar y,uchar dd);//将数据写入左右半屏void display_hz(uchar xx,uchar yy,uchar n,uchar fb); //显示汉字函数uchar code hz[]; //汉字字摸uchar code asc[];//数字字摸uchar hour1,hour0;uchar minute1,minute0;uchar sec1,sec0;uchar hour=0,minute=0,sec=0;uchar osc=0;void Timer0(void)//设定定时器0 50ms{TMOD = 0x01;TH0 = 0x3C;TL0 = 0x0B0;EA = 1;ET0 = 1;TR0 = 1;}void time0init()interrupt 1//定时器中断执行,时,分,秒计算{TR0=0;osc++;if(osc==20){sec++;osc=0;}if(sec==60){minute++; sec=0;}if(minute==60){hour++;minute=0;}if(hour==24){hour=0;}hour1=hour/10;hour0=hour%10;minute1=minute/10;minute0=minute%10;sec1=sec/10;sec0=sec%10;TH0=0x3c;TL0=0x0B0;EA=1;ET0=1;TF0=0;TR0=1;}#include "12864hh.h"void main(void){lcd_init();delay(1000);Timer0();while(1){display_hz(2,0,0,0); display_hz(4,0,1,0); display_hz(6,0,2,0); display_hz(8,0,3,0); display_hz(10,0,4,0); display_hz(0,4,5,0); display_hz(6,4,6,0); display_hz(12,4,7,0); display_asc(2,4,hour1,0); display_asc(3,4,hour0,0); display_asc(8,4,minute1,0); display_asc(9,4,minute0,0); display_asc(14,4,sec1,0); display_asc(15,4,sec0,0); }delay(60000);}//-------------------------中文字字模------------------------------uchar code hz[]={0x20,0x04,0x20,0x04,0x22,0x42,0x22,0x82,0xFE,0x7F ,0x21,0x01,0x21,0x01,0x20,0x10,0x20,0x10,0xFF,0x08,0x20,0x07,0x22,0x1A,0xAC,0x21 ,0x20,0x40,0x20,0xF0,0x00,0x00,/*"我",0*/0x00,0x40,0x40,0x20,0xB2,0xA0,0x96,0x90,0x9A,0x4C ,0x92,0x47,0xF6,0x2A,0x9A,0x2A,0x93,0x12,0x91,0x1A,0x99,0x26,0x97,0x22,0x91,0x40 ,0x90,0xC0,0x30,0x40,0x00,0x00,/*"爱",1*/0x00,0x08,0x00,0x08,0xF8,0x0B,0x28,0x09,0x29,0x09 ,0x2E,0x09,0x2A,0x09,0xF8,0xFF,0x28,0x09,0x2C,0x09,0x2B,0x09,0x2A,0x09,0xF8,0x0B ,0x00,0x08,0x00,0x08,0x00,0x00,/*"单",2*/0x00,0x80,0x00,0x40,0x00,0x30,0xFE,0x0F,0x10,0x01 ,0x10,0x01,0x10,0x01,0x10,0x01,0x10,0x01,0x1F,0x01,0x10,0x01,0x10,0xFF,0x10,0x00 ,0x18,0x00,0x10,0x00,0x00,0x00,/*"片",3*/0x08,0x04,0x08,0x03,0xC8,0x00,0xFF,0xFF,0x48,0x00 ,0x88,0x41,0x08,0x30,0x00,0x0C,0xFE,0x03,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x3F ,0x00,0x40,0x00,0x78,0x00,0x00, /*机",4*/0x00,0x00,0xFC,0x07,0x44,0x04,0x44,0x04,0x44,0x04 ,0xFC,0x07,0x10,0x00,0x90,0x00,0x10,0x03,0x10,0x40,0x10,0x80,0xFF,0x7F,0x10,0x00 ,0x10,0x00,0x10,0x00,0x00,0x00,/*"时",0*/0x80,0x00,0x40,0x80,0x20,0x40,0x98,0x20,0x87,0x10 ,0x82,0x0F,0x80,0x00,0x80,0x00,0x83,0x20,0x84,0x40,0x98,0x3F,0x30,0x00,0x60,0x00 ,0xC0,0x00,0x40,0x00,0x00,0x00,/*"分",1*/0x12,0x04,0x12,0x03,0xD2,0x00,0xFE,0xFF,0x91,0x00 ,0x11,0x83,0xC0,0x80,0x38,0x40,0x10,0x40,0x00,0x20,0xFF,0x23,0x00,0x10,0x08,0x08 ,0x10,0x04,0x60,0x03,0x00,0x00};/*"秒",2*///------------------------------数字字摸----------------------------------uchar code asc[]={0x00,0x00,0xE0,0x0F,0x10,0x10,0x08,0x20,0x08,0x20 ,0x10,0x10,0xE0,0x0F,0x00,0x00,/*"0",0* /0x00,0x00,0x10,0x20,0x10,0x20,0xF8,0x3F,0x00,0x20 ,0x00,0x20,0x00,0x00,0x00,0x00,/*"1",1* /0x00,0x00,0x70,0x30,0x08,0x28,0x08,0x24,0x08,0x22 ,0x88,0x21,0x70,0x30,0x00,0x00,/*"2",2* /0x00,0x00,0x30,0x18,0x08,0x20,0x88,0x20,0x88,0x20 ,0x48,0x11,0x30,0x0E,0x00,0x00,/*"3",3* /0x00,0x00,0x00,0x07,0xC0,0x04,0x20,0x24,0x10,0x24 ,0xF8,0x3F,0x00,0x24,0x00,0x00,/*"4",4* /0x00,0x00,0xF8,0x19,0x08,0x21,0x88,0x20,0x88,0x20 ,0x08,0x11,0x08,0x0E,0x00,0x00,/*"5",5* /0x00,0x00,0xE0,0x0F,0x10,0x11,0x88,0x20,0x88,0x20 ,0x18,0x11,0x00,0x0E,0x00,0x00,/*"6",6* /0x00,0x00,0x38,0x00,0x08,0x00,0x08,0x3F,0xC8,0x00 ,0x38,0x00,0x08,0x00,0x00,0x00,/*"7",7* /0x00,0x00,0x70,0x1C,0x88,0x22,0x08,0x21,0x08,0x21 ,0x88,0x22,0x70,0x1C,0x00,0x00,/*"8",8*0x00,0x00,0xE0,0x00,0x10,0x31,0x08,0x22,0x08,0x22 ,0x10,0x11,0xE0,0x0F,0x00,0x00,/*"9",9* /0x00,0x00,0xE0,0x0F,0x10,0x10,0x08,0x20,0x08,0x20 ,0x10,0x10,0xE0,0x0F,0x00,0x00};/*"0",1 0*///------------------------------库函数---------------------------void delay(unsigned long v) //延时子函数{while(v--);}void lcd_busy() //繁忙标志{rs=0;rw=1;dataport=0xff;while(1)en=1;if(dataport;=64){set_xy(x-64,y);wdata(dd,0,1);}else{set_xy(x,y);wdata(dd,1,0);}}void set_startline(uchar i)//设定起始行{i=0xc0+i;wcode(i,1,1);}void set_xy(uchar x,uchar y) //定位x,y位置{x=x+0x40;y=y+0xb8;wcode(x,1,1);wcode(y,1,1);}void dison_off(uchar k) //开,关显示{k=k+0x3e;wcode(k,1,1);}void reset(){RST=0;delay(40);RST=1;delay(40);}void lcd_init(void)//芯片初始化{uchar x,y;reset();set_startline(0);dison_off(0);for(y=0;y<8;y++){for(x=0;x<128;x++)lw(x,y,0);}dison_off(1);}void display_hz(uchar xx, uchar yy, uchar n, uchar fb)//显示汉字逐列式{uchar i,dx;for(i=0;i<16;i++){dx=hz[2*i+n*32];if(fb)dx=255-dx;lw(xx*8+i,yy,dx);dx=hz[(2*i+1)+n*32];if(fb)dx=255-dx;lw(xx*8+i,yy+1,dx);}}void display_asc(uchar xx,uchar yy,uchar n,uchar fb)//显示数字逐列式{uchar i,dx;for(i=0;i<8;i++){dx=asc[2*i+n*16];if(fb)dx=255-dx;lw(xx*8+i,yy,dx);dx=asc[2*i+1+n*16];if(fb)dx=255-dx;lw(xx*8+i,yy+1,dx);}}。
12864液晶电子时钟+温度显示上午花了一上午时间,用12864 液晶写了一个电子时钟加温度传感器程序,先说一下程序的功能,可以实现显示年月日时间和温度,年月日和时间是可通过按键调节的,调节相应的选项时,该选项会闪烁,并停止走时,当调节完毕后时钟恢复走时。
现在将程序和思路写下来,以便日后查看和与大家探讨改进,欢迎高手提出宝贵意见。
我使用的是HJ12864M-1 带字库液晶,所以在显示上稍微方便一点。
下面先来说一下我的编程思路。
时间更新用的是单片机自带的定时器,液晶要显示数字必需将它转换成ASCii 码的形式,数字0-9 的ASCii 码与数字之间有一个定量的关系,当数字加上0x30 之后便得到该数字的ASCii 码,这样以来液晶更新数据就变得简单了。
调节时间时对应选项闪烁,是通过不断的交替写入数据和空格实现的。
温度显示用的是DS18B20,,将测得的当前温度不断更新显示在液晶上。
调节时间用的是三个独立按键。
由于这个程序我使用模块化来写的,就只能将每个模块分别给出来,大家只要组装一下便可以使用。
如果需要完整程序的可以给我留言我发给你们。
下面是12864 液晶的初始化,读写命令,及读忙操作#include “lcd12864.h”#include reg52.hsbit RS=P2 ; //控制端口位定义sbitRW=P2;s b it EN=P2;vo id init_12864(){delay(40);write_com(0x30);//8 位数据格式,基本指令显示delay(10); //延时时间write_com(0x30);//8 位数据格式,基本指令显示delay(37);write_com(0x0C);//开显示、关闭光标delay(10);write_com(0x01);//清屏指令delay(10); //延时write_com(0x06);//设置显示点:指针自加1}tips:感谢大家的阅读,本文由我司收集整编。
;**********此程序用于12864(lgm12641bs1r)液晶显示汉字(没有字库)********* ;****************2011.3.30**************lcm equ p1cs1 bit p2.4 ;cs1片选左屏cs2 bit p2.3 ;cs2片选右屏di bit p2.2rw bit p2.1e bit p2.0rst bit p2.7x equ 30hy equ 31hdd equ 32hxx equ 33hyy equ 34hhz equ 35horg 0000hljmp mainorg 0030hmain: ;lcall lcd_init;mov r5,#0ffh;lcall delaymov xx,#00hmov yy,#00h;mov hz,hz1mov dptr,#tab1lcall disp_hz;lcall delaymov xx,#0hmov yy,#02hmov dptr,#tab2lcall disp_hzmov xx,#1hmov yy,#00hmov dptr,#tab1lcall disp_hzljmp $;************设定起始行子程序********************set_startline:;此处由a值进入add a,#0c0hsetb cs1setb cs2lCALL w_coderet;******************写指令到lcm中******************w_code: ;调用此子程序之前须设定片选,数据由a进入lcall lcd_busyclr di ;低电平选中指令输入端clr rw;lcall lcd_busymov lcm,asetb eclr eret;******************写数据到lcm中******************w_data: ;调用此子程序之前须设定片选,数据由a进入lcall lcd_busysetb di;高电平选中数据输入端clr rwmov lcm,asetb eclr eret;**************设定x,y坐标,数据并由x,y传入*****set_xy:mov a,xadd a,#40hsetb cs1setb cs2lcall w_codemov a,yadd a,#0b8hsetb cs1setb cs2lcall w_coderet;***********开关屏数据由a传入,0为关,1为开*************** dison_off:add a,#3ehsetb cs1setb cs2lcall w_coderet;************复位程序************************************** reset: clr rstmov r5,#20 ;延时20mslcall delaysetb rstmov r5,#20lcall delayret;************初始化lcd**********************************lcd_init:lcall resetmov a,#00hlcall dison_off ;关显示mov y,#00hxx2: mov x,#0mov dd,#00hxx1: lcall lwinc xmov a,xcjne a,#128,xx1inc ymov a,ycjne a,#8,xx2;djnz x,xx1;djnz y,xx2mov a,#01hlcall dison_off ;开显示mov a,#00h ; 起始行为0lcall set_startlineret;************写数据到lcm指定位置**********************;************此子程序由x,y,dd导入数据***************lw: mov a,xcjne a,#64,x1x1: jc x2;mov a,xclr csubb a,#64mov x,alcall set_xyclr cs1setb cs2mov a,ddlcall w_dataljmp fanhuix2: lcall set_xysetb cs1clr cs2mov a,ddlcall w_datafanhui: ret;***************显示一个汉字子程序*****************;**********此程序由xx(表示该行第xx个字),yy(表示第yy行),hz(要写入的汉字)导入数据**********disp_hz:;mov dptr,#tab1mov r7,#0 ;ixx0:mov a,r7mov b,#2mul abinc amov 7fh,adec amovc a,@a+dptrmov dd,amov a,xxmov b,#16mul abadd a,r7mov x,amov y,yylcall lwmov a,7fhmovc a,@a+dptrmov dd,ainc ylcall lwinc r7cjne r7,#16,xx0retdelay: ;1msd3: mov r3,#090hd1: mov r4,#2hd2: djnz r4,d2djnz r3,d1djnz r5,d3retlcd_busy: ;判忙clr disetb rwrettab3: DB 80h,80h,40h,20h,50h,48h,44h,0C3h,44h,48h,50h,20h,40h,80h,80h,00h DB 40h,40h,42h,4Ah,72h,42h,42h,7Fh,42h,42h,62h,5Ah,42h,40h,40h,00htab1:db 40h,40h,40h,40h,20h,42h,20h,42h,50h,4Ah,48h,72h,44h,42h,0C3h,7Fh,db 44h,42h,48h,62h,50h,5Ah,50h,42h,20h,42h,60h,40h,20h,40h,00h,00htab2:DB 00h,80h,60h,0F8h,07h,00h,0FCh,44h,44h,44h,44h,44h,44h,0FCh,00h,00hDB 01h,00h,00h,0FFh,00h,40h,4Fh,44h,44h,44h,44h,44h,44h,4Fh,40h,00h end。
#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();}}。
fpga设计电子时钟(12864显示)设计心得:1,进行分块设计,类似调用函数,脉冲使能2,充分了解fpga的并行特性(c程序的串行特性,不能并行处理,线性:只有完成了当前任务,才能进行下一个任务)设计问题:1,似乎读有问题,在char_LR=1时,写的数据为汉字(程序中时间没有更改,主要为了调试看波形)实际板子验证时,将LCD_clk模块中的分频调为50到100kHz左右整体架构功能模块液晶初始化时序parameter Idle =8'b0000_0001,Basic_com =8'b0000_0010, //basic instruction:0x30Disp_set =8'b0000_0100, //set show curse blingDDRAM_clear =8'b0000_1000, //colunm address XWait_clear =8'b0001_0000,Point_set =8'b0010_0000,Show_on =8'b0100_0000,Stop=8'b1000_0000;写字符的时序由于字符属于半宽字形,且DDRAM形式下,每行只有8个地址,而字符可以写16个,因此用下面三个来表示写的地址:i nput [1:0] Y, //row 0-3i nput [2:0] X, //clunm 0-7i nput LR, //0/1因此当LR=0时,直接写地址,然后写一个字符编码即可LR=1时,先写地址,读出高位数据,然后写入两个字节(读出的数据,要写的数据)parameter Idle =8'b0000_0001,DDRAM =8'b0000_0010, //drawing modeW_addr =8'b0000_0100, //row address YDummy =8'b0000_1000, // not really readingR_data =8'b0001_0000, //reading high byte dataW0_data =8'b0010_0000,W1_data =8'b0100_0000,Stop =8'b1000_0000;# t1: 0 t2: 2305, T: 10,n_init: 38 # t1: 2305 t2: 2665, T: 10,n_char: 6 # t1: 2665 t2: 3265, T: 10,n_char: 10完成了上述工作,就可以设计一个简单的电子时钟,其要求如下:在屏幕上显示时间00:00:00要动态走(主要就是控制脉冲信号的产生)设计思路:100:00:0023LCD更新数据显示00:00:0100:01:591代码/*sign.v//creat the control signclock h:m:s*/module sign(//module LED(input lcd_clk, //100kHzinput sys_rst,output reg lcd_char_en,output reg lcd_init_en,output reg [7:0]char_data,output reg [2:0]char_X,output reg [1:0]char_Y,output reg char_LR);parameter T_w_char = 5,T_lcd_init = 40;reg [47:0] time_out;/* 1s */reg [16:0] cnt_s;reg [5:0] cnt0_clk;reg [3:0] cnt1_clk;reg [2:0] cnt_char;reg [5:0] sec,min;reg [4:0] hour;reg flag_s,flag_init;always @ (posedge lcd_clk or negedge sys_rst) begin //100kHz if(!sys_rst)begincnt_s <=0;cnt0_clk<=0;cnt1_clk<=0;cnt_char<=0;sec <=0;min <=0;hour <=0;flag_s <=0;flag_init <=1'b1;char_Y <= 2'b10;endelsebeginif(cnt_s == (40-1))begincnt_s <=0;flag_s<=1'b1;data_deal; //taskendelsecnt_s <=cnt_s+1'b1;if(flag_init)begincnt0_clk <= cnt0_clk +1'b1;case(cnt0_clk)1 : begin lcd_init_en <=1'b0; end2 : begin lcd_init_en <=1'b1; end3 : begin lcd_init_en <=1'b1; end4 : begin lcd_init_en <=1'b0; endT_lcd_init: beginflag_init <=0;cnt0_clk <=0;enddefault: lcd_init_en <=0;endcaseendelseif(flag_s)begincnt1_clk <= cnt1_clk +1'b1;case(cnt1_clk)1 : begin lcd_char_en <=1'b0; e nd2 : begin lcd_char_en <=1'b1; e nd3 : begin lcd_char_en <=1'b1; e nd4 : begin lcd_char_en <=1'b0; e ndT_w_char: beginif(cnt_char == 3'b111)begin cnt_char<=0; flag_s <=0; endelsecnt_char <=cnt_char+1'b1;cnt1_clk <=0;enddefault: lcd_char_en <=0;endcasecase(cnt_char)//2 3 4 50 : begin char_X <=3'b000; char_LR <=0; char_data <=time_out[47:40]; end //x0:00:001 : begin char_X <=3'b001; char_LR <=0; char_data <=time_out[39:32]; end //0x:00:002 : begin char_X <=3'b010; char_LR <=0; char_data <=8'h3a; end //: ascii 0583 : begin char_X <=3'b011; char_LR <=0; char_data <=time_out[31:24]; end //00:x0:004 : begin char_X <=3'b100; char_LR <=0; char_data <=time_out[23:16]; end //00:0x:005 : begin char_X <=3'b101; char_LR <=0; char_data <=8'h3a; end //: ascii 0586 : begin char_X <=3'b110; char_LR <=0; char_data <=time_out[15: 8]; end//00:00:x07 : begin char_X <=3'b111; char_LR <=0; char_data <=time_out[7 : 0]; endendcaseendendendtask data_deal;beginif(sec == 59)if(min ==59)if(hour == 23)begin hour<=0;min <=0;sec <=0; endelsebegin hour<=hour + 1'b1; min <=0; sec<=0; endelsebegin min <= min+1'b1; sec <=0; endelsesec <= sec +1'b1;time_out[47:40] <= 8'h30+(hour/10);time_out[39:32] <= 8'h30+(hour%10);time_out[31:24] <= 8'h30+(min /10);time_out[23:16] <= 8'h30+(min %10);time_out[15: 8] <= 8'h30+(sec /10);time_out[ 7: 0] <= 8'h30+(sec %10);endendtaskendmodule2代码module LCD_init(//module LED(input lcd_clk,input sys_clk,input lcd_en, //1 is activedoutput reg LCD_RS,output reg LCD_RW,output reg LCD_EN,inout [7:0] LCD_DATA,output reg ACK);reg flag;reg [7:0] lcd_data;reg [7:0] State;reg link_rs;reg link_data;parameter Idle =8'b0000_0001,Basic_com =8'b0000_0010, //basic instruction:0x30Disp_set =8'b0000_0100, //set show curse blingDDRAM_clear =8'b0000_1000, //colunm address XWait_clear =8'b0001_0000,Point_set =8'b0010_0000,Show_on =8'b0100_0000,Stop =8'b1000_0000;reg [9:0] cnt; //16*2*32=2^10 byte(8bits)/* LCD_RW LCD_DATA*/assign LCD_DATA = link_data ? lcd_data: 8'hzz;/* LCD_RW LCD_EN */always @ (posedge sys_clk) beginif(flag)beginLCD_RW =0;LCD_EN = lcd_clk;endelsebeginLCD_RW =1'bz;LCD_EN =1'bz;endend/* LCD_RS */always @ (posedge lcd_clk) beginif(link_rs)LCD_RS <=1'b0;elseLCD_RS <=1'bz;end/*-Main state transter-*/always @ (posedge lcd_clk) begincase (State)Idle : beginif(lcd_en)begin link_rs=1; State <= Basic_com; endelseState <= Idle;ACK =0;flag <=1'b0;lcd_data <= 8'hzz;cnt <= 0;endBasic_com : beginflag <=1'b1;link_data =1'b1;cnt <= cnt +1'b1;if(cnt == 1)State <= Disp_set;elseState <= Basic_com;lcd_data <= 8'h30;endDisp_set : beginState <= DDRAM_clear;lcd_data <= 8'h0c; //show curse blink is offendDDRAM_clear : beginState <= Wait_clear;lcd_data <= 8'h01;endWait_clear : begincnt <=cnt +1'b1;link_data = 1'b0;flag <=0;lcd_data <= 8'hzz;if(cnt == 30)State <= Point_set;elseState <= Wait_clear;endPoint_set : beginflag <=1'b1;link_data =1'b1;State <= Show_on;lcd_data <= 8'h06; //point +1 automatically,screen move off endShow_on : beginState <= Stop;lcd_data <= 8'h0c;endStop : beginState <= Idle;flag <=1'b0;link_data =1'b0;ACK <=1'b1;lcd_data <= 8'hzz;cnt <= 0;link_rs =0;enddefault: begin ACK =0;State <= Idle;end endcaseendendmodule3代码//module LCD_top(module LED(input sys_clk,input sys_rst,output LCD_RS,output LCD_RW,output LCD_EN,inout [7:0] LCD_DATA,output BUSY);wire [7:0] char_data;wire [2:0] char_X;wire [1:0] char_Y;sign singb(.lcd_clk (lcd_clk), //100kHz.sys_rst (sys_rst),.lcd_char_en(lcd_char_en),.lcd_init_en(lcd_init_en),.char_data (char_data),.char_X (char_X),.char_Y (char_Y),.char_LR (char_LR));LCD_init lcd_init(.lcd_clk (lcd_clk),.sys_clk (sys_clk),.lcd_en (lcd_init_en), //1 is actived .LCD_RS (LCD_RS),.LCD_RW (LCD_RW),.LCD_EN (LCD_EN),.LCD_DATA (LCD_DATA),.ACK (init_ack));LCD_charac a(.lcd_clk (lcd_clk),.sys_clk (sys_clk),.lcd_en (lcd_char_en), //1 is actived .Y (char_Y), //row 0-3.X (char_X), //clunm 0-7.LR (char_LR), //0/1.data_disp (char_data),.LCD_RS (LCD_RS),.LCD_RW (LCD_RW),.LCD_EN (LCD_EN),.LCD_DATA (LCD_DATA),.ACK (init_ack));LCD_clk clk1(.sys_clk (sys_clk),.lcd_clk (lcd_clk));endmodule4代码module LCD_clk(//module LED(input sys_clk,output reg lcd_clk);/*-creat the 25kHz clock-*/reg [11:0] lcd_cnt;always @ (posedge sys_clk) beginif(lcd_cnt == 2) //100kHzbeginlcd_cnt =0;lcd_clk <= ~ lcd_clk;endelselcd_cnt = lcd_cnt +1'b1;endinitial begin lcd_clk =0; lcd_cnt =0; endendmodule5代码/* to display character */module LCD_charac(//module LED(input lcd_clk,input sys_clk,input lcd_en, //1 is activedinput [1:0] Y, //row 0-3input [2:0] X, //clunm 0-7input LR, //0/1input [7:0] data_disp,output reg LCD_RS,output reg LCD_RW,output reg LCD_EN,inout [7:0] LCD_DATA,output reg ACK);reg [7:0] lcd_data;reg [7:0] R_buff;reg [7:0] State;parameter Idle =8'b0000_0001,DDRAM =8'b0000_0010, //drawing modeW_addr =8'b0000_0100, //row address YDummy =8'b0000_1000, // not really readingR_data =8'b0001_0000, //reading high byte dataW0_data =8'b0010_0000,W1_data =8'b0100_0000,Stop =8'b1000_0000;reg flag,cnt;reg link_data;reg flag0;/* LCD_DATA */assign LCD_DATA = link_data ? lcd_data :8'hzz;/* LCD_EN */always @ (posedge sys_clk) beginif(flag == 1'b1)LCD_EN <= lcd_clk;elseLCD_EN <=1'bz;end/* LCD_RW */always @ (posedge lcd_clk) beginif(flag0)if(State == Dummy || State == R_data)LCD_RW <=1'b1;elseLCD_RW <=1'b0;elseLCD_RW <=1'bz;end/* LCD_RS */always @ (posedge lcd_clk) beginif(flag0)if(State == W0_data || State == W1_data || State == Dummy || State == R_data) LCD_RS <=1'b1;elseLCD_RS <=1'b0;elseLCD_RS <=1'bz;end/*-Main state transter-*/always @ (posedge lcd_clk) begincase (State)Idle : beginif(lcd_en)begin State <= DDRAM; link_data =1; flag0=1'b1; endelsebegin State <= Idle; flag0= 1'b0;endflag <= 1'b0;lcd_data <= 8'hzz;ACK <=0;endDDRAM : begin //here flag is changed,not Idle, cause sys_clk flag <= 1'b1;State <= W_addr;link_data =1;lcd_data <= 8'h30;endW_addr : beginif(!cnt)beginif(LR)State <= Dummy;elseState <= W0_data;cnt =1'b1;endelseState <= W0_data;case (Y)2'b00: lcd_data <= 8'h80 + X;2'b01: lcd_data <= 8'h90 + X;2'b10: lcd_data <= 8'h88 + X;2'b11: lcd_data <= 8'h98 + X;endcaselink_data =1'b1;endDummy : beginState <= R_data;R_buff <= LCD_DATA;link_data =0;endR_data : beginState <=W_addr;R_buff <= LCD_DATA;endW0_data : beginif( !LR)beginlcd_data <= data_disp;State <= Stop;endelsebeginlcd_data <= R_buff;State <= W1_data;endendW1_data : beginlcd_data <= data_disp;State <=Stop;flag0=0;endStop : beginState <= Idle;flag <= 1'b0;lcd_data <= 8'hzz;cnt <= 0;ACK <= 1;enddefault: begin ACK =0;State <= Idle; link_data=0 ;end endcaseendendmodule。
/////////////////////////////////////////////////////程序编写人:小艾//程序编写时间:2012-5-16//程序实现的功能:12864的显示,汇编//////////////////////////////////////////////////////// AIXING EQU 41HAIXING1 EQU 42HSECOND EQU 43HMINUTE EQU 44HHOUR EQU 45HMINUTE1 EQU 46HHOUR1 EQU 47HMINUTE2 EQU 48HHOUR2 EQU 49HMINUTE3 EQU 4AHHOUR3 EQU 4BHMINUTE4 EQU 4CHHOUR4 EQU 4DHCSA EQU P3.2CSB EQU P3.3RS EQU P3.6RW EQU P3.5E EQU P3.4OUTPUT EQU P2COM EQU 2CHDAT EQU 2DHCODES EQU 2Ehcolumn EQU 24Hpagef EQU 25hcpage EQU 26Hccolumn E QU 27Hcolumn2 EQU 28Hpagef2 EQU 29hcpage2 EQU 2aHccolumn2 EQU 2bHCOUNT EQU 60HCOUNT1 EQU 61H//COUNT2 EQU 62H//COUNT3 EQU 63HCOUNT4 EQU 64HCOUNT5 EQU 65Hcolumn1 EQU 30H pagef1 EQU 31h cpage1 EQU 32H ccolumn1 EQU 33H column3 EQU 34H pagef3 EQU 35h cpage3 EQU 36H ccolumn3 EQU 37HSHUJI1 EQU 50H SHUJI2 EQU 51H SHUJI3 EQU 52H SHUJI4 EQU 53H SHUJI5 EQU 54H SHUJI6 EQU 55H SHUJI7 EQU 56H SHUJI8 EQU 57H SHUJI9 EQU 58H SHUJI10 EQU 59H SHUJI11 EQU 5AH SHUJI12 EQU 5BH SHUJI13 EQU 5CH SHUJI14 EQU 5DH SHUJI15 EQU 5EH SHUJI16 EQU 38H SHUJI17 EQU 39H SHUJI18 EQU 3AH SHUJI19 EQU 3BH SHUJI20 EQU 3CH SHUJI21 EQU 3DH SHUJI22 EQU 3EHKEY1 BIT P1.1 KEY2 BIT P1.2 KEY3 BIT P1.3 KEY4 BIT P1.4 KEY5 BIT P1.5 KEY6 BIT P1.6 BT0 BIT 20H.0 BT1 BIT 20H.1 BT2 BIT 20H.2 BT3 BIT 20H.3 BT4 BIT 20H.4 BT5 BIT 20H.5BT6 BIT 20H.6BT7 BIT 20H.7BT8 BIT 21H.0BT9 BIT 21H.1BT10 BIT 21H.2BT11 BIT 21H.3BT12 BIT 21H.4BT13 BIT 21H.5/////////////////////////////////////////////////ORG 0000HLJMP STARTORG 000BHLJMP INTP0ORG 0030H;*********************************************主程序开始START: MOV TMOD,#01HMOV TH0,#(65536-50000) / 256MOV TL0,#(65536-50000) MOD 256SETB EASETB ET0SETB TR0LCALL CLEARLCALL INT ;调用初始化子程序/////////////////////////////////////////////////////MAIN: LCALL KEYSCAN1JB BT7,MAIN1MAIN4: LCALL CLEAR ;调用清屏子程序LCALL DISPLAY1LCALL KKKLCALL DISPLAYLCALL DISPLAY5LCALL DISPLAY6MAIN2: LCALL KKKLCALL DISPLAYLCALL KEYSCAN1JB BT7,MAIN1LJMP MAIN2MAIN1: LCALL CLEAR ;调用清屏子程序MAIN3: LCALL DISPLAY2LCALL DISPLAY3LCALL KEYSCAN1JB BT7,MAIN3LJMP MAIN4////////////////////////////////////////////////////////DISPLAY3:LCALL CHULI1MOV A,COUNT4CJNE A,#0,DISPLAY4RET//////////////////////////////////////////////////// DISPLAY4:CLR COUNT1CLR ALCALL CHULI1MOV A,COUNT4CJNE A,#1,PLAY1LCALL CLEARQQ1: LCALL KKKLCALL KEYSCANLCALL KEYCHULI1LCALL KEYCHULI11LCALL KEYCHULI2LCALL KEYCHULI21LCALL DISPLAYMOV COM,#00HLCALL PRR0LCALL PRM0LCALL CHULI1MOV A,COUNT4CJNE A,#1,PLAY1AJMP QQ1PLAY1: CLR AMOV COUNT1,#0MOV A,COUNT4CJNE A,#2,PLAY2LCALL CLEARQQ2: CLR ALCALL CHULI2MOV A,COUNT5CJNE A,#0,CHULCALL KEYSCANLCALL KEYCHU1LCALL KEYCHU11LCALL KEYCHU5LCALL KEYCHU51LCALL DISPLAY5MOV COM,#00HLCALL PRR0LCALL PRM0LCALL CHULI1CLR AMOV A,COUNT4CJNE A,#2,PLAY2LJMP QQ2 CHU: CLR AMOV A,COUNT5CJNE A,#1,PLAY3LCALL KEYSCANLCALL KEYCHU2LCALL KEYCHU21LCALL KEYCHU6LCALL KEYCHU61LCALL DISPLAY5MOV COM,#00HLCALL PRR0LCALL PRM0LCALL CHULI1CLR AMOV A,COUNT4CJNE A,#2,PLAY2LJMP QQ2///////////////////////////////////////////////// PLAY2: MOV COUNT5,#0CLR AMOV A,COUNT4CJNE A,#3,PLAY3LCALL CLEARQQ3: CLR ALCALL CHULI2MOV A,COUNT5CJNE A,#0,CHU1LCALL KEYSCANLCALL KEYCHU3LCALL KEYCHU31LCALL KEYCHU7LCALL KEYCHU71LCALL DISPLAY6CLR ALCALL CHULI1MOV A,COUNT4CJNE A,#3,PLAY2LJMP QQ3CHU1: CLR AMOV A,COUNT5CJNE A,#1,PLAY3LCALL KEYSCANLCALL KEYCHU4LCALL KEYCHU41LCALL KEYCHU8LCALL KEYCHU81LCALL DISPLAY6LCALL CHULI1CLR AMOV A,COUNT4CJNE A,#3,PLAY3LJMP QQ3PLAY3: LCALL CLEARMOV COUNT4,#0MOV COUNT5,#0RET////////////////显示“菜”/////////////////////////////////// DISPLAY2:MOV CODES,#0MOV column1,#16MOV pagef1,#0MOV CODES,#14CALL writeleft1///////////////////显示“单”////////////////////////////// MOV CODES,#0MOV column3,#00MOV pagef3,#0MOV CODES,#15CALL writeright1/////////////////显示“时”//////////////////////////////MOV CODES,#0MOV column1,#16MOV pagef1,#2MOV CODES,#16CALL writeleft1/////////////////显示“钟”/////////////////////////////// MOV CODES,#0MOV column1,#32MOV pagef1,#2MOV CODES,#17CALL writeleft1/////////////////显示“设”//////////////////////////////MOV column1,#48MOV pagef1,#2MOV CODES,#22CALL writeleft1/////////////////显示“定”/////////////////////////////// MOV CODES,#0MOV column3,#00MOV pagef3,#2MOV CODES,#23CALL writeright1/////////////////显示“开”////////////////////////////// MOV CODES,#0MOV column1,#16MOV pagef1,#4MOV CODES,#18CALL writeleft1/////////////////显示“关”/////////////////////////////// MOV CODES,#0MOV column1,#32MOV pagef1,#4MOV CODES,#19CALL writeleft1/////////////////显示“设”////////////////////////////// MOV CODES,#0MOV column1,#48MOV pagef1,#4MOV CODES,#22CALL writeleft1/////////////////显示“定”/////////////////////////////// MOV CODES,#0MOV column3,#00MOV pagef3,#4MOV CODES,#23CALL writeright1/////////////////显示“调”////////////////////////////// MOV CODES,#0MOV column1,#16MOV pagef1,#6MOV CODES,#20CALL writeleft1/////////////////显示“光”/////////////////////////////// MOV CODES,#0MOV pagef1,#6MOV CODES,#21CALL writeleft1/////////////////显示“设”//////////////////////////////MOV CODES,#0MOV column1,#48MOV pagef1,#6MOV CODES,#22CALL writeleft1/////////////////显示“定”///////////////////////////////MOV CODES,#0MOV column3,#00MOV pagef3,#6MOV CODES,#23CALL writeright1LJMP BB///////////////////显示“星”///////////////////////////// DISPLAY1:MOV CODES,#0MOV column1,#00MOV pagef1,#0MOV CODES,#0lcall writeleft1//////////////////显示“梦”////////////////////////////////// MOV CODES,#0MOV column1,#16MOV pagef1,#0MOV CODES,#1CALL writeleft1//////////////////显示“奕”/////////////////////////////MOV CODES,#0MOV column1,#32MOV pagef1,#0MOV CODES,#2CALL writeleft1////////////////显示“缘”/////////////////////////////MOV CODES,#0MOV column1,#48MOV pagef1,#0MOV CODES,#3CALL writeleft1LJMP BB/////////////////显示“time”////////////////////////////KKK: MOV CODES,#0MOV column,#00MOV pagef,#2MOV CODES,#13CALL writeleftMOV CODES,#0MOV column,#8MOV pagef,#2MOV CODES,#14CALL writeleftMOV CODES,#0MOV column,#16MOV pagef,#2MOV CODES,#15CALL writeleftMOV CODES,#0MOV column,#24MOV pagef,#2MOV CODES,#16CALL writeleftMOV CODES,#0MOV column,#32MOV pagef,#2 ;显示:MOV CODES,#11CALL writeleftRET///////////////“L1开”///////////////////////////////////// DISPLAY5: MOV C ODES,#0MOV column1,#00MOV pagef1,#4MOV CODES,#11CALL writeleft1MOV CODES,#0MOV column,#8MOV pagef,#4MOV CODES,#1CALL writeleftMOV CODES,#0MOV column,#16MOV pagef,#4 ;显示:MOV CODES,#11CALL writeleftMOV CODES,#0MOV SHUJI7,#0CLR AMOV A,MINUTE1MOV B,#10DIV ABMOV A,BMOV SHUJI7,AMOV column,#56MOV pagef,#4MOV CODES,SHUJI7 ;分低位CALL writeleftMOV CODES,#0MOV SHUJI8,#0MOV CODES,#0CLR AMOV A,MINUTE1MOV B,#10DIV ABMOV SHUJI8,AMOV column,#48MOV pagef,#4MOV CODES,SHUJI8 ;分高位CALL writeleftMOV CODES,#0MOV column,#40MOV pagef,#4 ;显示:MOV CODES,#11CALL writeleftMOV CODES,#0MOV SHUJI9,#0CLR AMOV A,HOUR1MOV B,#10DIV ABMOV A,BMOV SHUJI9,Amov column,#32mov pagef,#4MOV CODES,SHUJI9 ;时低位lcall writeleftMOV CODES,#0MOV SHUJI10,#0MOV CODES,#0CLR AMOV A,HOUR1MOV B,#10DIV ABMOV SHUJI10,AMOV column,#24MOV pagef,#4MOV CODES,SHUJI10 ;时高位CALL writeleft///////////////L1关/////////////////////////MOV CODES,#0MOV column3,#48MOV pagef3,#4MOV CODES,#10CALL writeright1MOV CODES,#0MOV SHUJI11,#0CLR AMOV A,MINUTE2MOV B,#10DIV ABMOV A,BMOV SHUJI11,AMOV column2,#40MOV pagef2,#4MOV CODES,SHUJI11 ;分低位CALL writerightMOV CODES,#0MOV SHUJI12,#0MOV CODES,#0CLR AMOV A,MINUTE2MOV B,#10DIV ABMOV SHUJI12,AMOV column2,#32MOV pagef2,#4MOV CODES,SHUJI12 ;分高位CALL writerightMOV CODES,#0MOV column2,#24MOV pagef2,#4 ;显示:MOV CODES,#11CALL writerightMOV CODES,#0MOV SHUJI13,#0CLR AMOV A,HOUR2MOV B,#10DIV ABMOV A,BMOV SHUJI13,Amov column2,#16mov pagef2,#4MOV CODES,SHUJI13 ;时低位CALL writerightMOV CODES,#0MOV SHUJI14,#0MOV CODES,#0CLR AMOV A,HOUR2MOV B,#10DIV ABMOV SHUJI14,AMOV column2,#8MOV pagef2,#4MOV CODES,SHUJI14 ;时高位CALL writerightMOV CODES,#0MOV column2,#00MOV pagef2,#4MOV CODES,#12 ;时高位CALL writerightLJMP BB///////////////“L2开”/////////////////////////////////////DISPLAY6: MOV CODES,#0MOV column1,#00MOV pagef1,#6MOV CODES,#11CALL writeleft1MOV CODES,#0MOV column,#8MOV pagef,#6MOV CODES,#2CALL writeleftMOV CODES,#0MOV column,#16MOV pagef,#6 ;显示:MOV CODES,#11CALL writeleftMOV CODES,#0MOV SHUJI15,#0CLR AMOV A,MINUTE3MOV B,#10DIV ABMOV A,BMOV SHUJI15,AMOV column,#56MOV pagef,#6MOV CODES,SHUJI15 ;分低位CALL writeleftMOV SHUJI16,#0MOV CODES,#0CLR AMOV A,MINUTE3MOV B,#10DIV ABMOV SHUJI16,AMOV column,#48MOV pagef,#6MOV CODES,SHUJI16 ;分高位CALL writeleftMOV CODES,#0MOV column,#40MOV pagef,#6 ;显示:MOV CODES,#11CALL writeleftMOV CODES,#0MOV SHUJI17,#0CLR AMOV A,HOUR3MOV B,#10DIV ABMOV A,BMOV SHUJI17,Amov column,#32mov pagef,#6MOV CODES,SHUJI17 ;时低位lcall writeleftMOV SHUJI8,#0MOV CODES,#0CLR AMOV A,HOUR3MOV B,#10DIV ABMOV SHUJI18,AMOV column,#24MOV pagef,#6MOV CODES,SHUJI18 ;时高位CALL writeleft///////////////L2关/////////////////////////MOV CODES,#0MOV column3,#48MOV pagef3,#6MOV CODES,#9CALL writeright1MOV CODES,#0MOV SHUJI19,#0CLR AMOV A,MINUTE4MOV B,#10DIV ABMOV A,BMOV SHUJI19,AMOV column2,#40MOV pagef2,#6MOV CODES,SHUJI19 ;分低位CALL writerightMOV SHUJI20,#0MOV CODES,#0CLR AMOV A,MINUTE4MOV B,#10DIV ABMOV SHUJI20,AMOV column2,#32MOV pagef2,#6MOV CODES,SHUJI20 ;分高位CALL writerightMOV CODES,#0MOV column2,#24MOV pagef2,#6 ;显示:MOV CODES,#11CALL writerightMOV CODES,#0MOV SHUJI21,#0CLR AMOV A,HOUR4MOV B,#10DIV ABMOV A,BMOV SHUJI21,Amov column2,#16mov pagef2,#6MOV CODES,SHUJI21 ;时低位CALL writerightMOV SHUJI22,#0MOV CODES,#0CLR AMOV A,HOUR4MOV B,#10DIV ABMOV SHUJI22,AMOV column2,#8MOV pagef2,#6MOV CODES,SHUJI22 ;时高位CALL writerightMOV column2,#00MOV pagef2,#6MOV CODES,#12 ;时高位CALL writerightBB: RET////////////////////////////////////////////////////DISPLAY: MOV CODES,#0MOV SHUJI1,#0CLR AMOV A,SECONDMOV B,#10DIV ABMOV A,BMOV SHUJI1,AMOV column2,#40MOV pagef2,#2MOV CODES,SHUJI1 ;秒低位CALL writerightMOV SHUJI2,#0MOV CODES,#0CLR AMOV A,SECONDMOV B,#10DIV ABMOV SHUJI2,AMOV column2,#32MOV pagef2,#2MOV CODES,SHUJI2 ;秒高位CALL writerightMOV CODES,#0MOV column2,#24MOV pagef2,#2 ;显示:MOV CODES,#11CALL writerightMOV CODES,#0MOV SHUJI3,#0CLR AMOV A,MINUTEMOV B,#10MOV A,BMOV SHUJI3,AMOV column2,#16MOV pagef2,#2MOV CODES,SHUJI3 ;分低位CALL writerightMOV SHUJI4,#0MOV CODES,#0CLR AMOV A,MINUTEMOV B,#10DIV ABMOV SHUJI4,AMOV column2,#8MOV pagef2,#2MOV CODES,SHUJI4 ;分高位CALL writerightMOV CODES,#0MOV column2,#00MOV pagef2,#2 ;显示:MOV CODES,#11CALL writerightMOV CODES,#0MOV SHUJI5,#0CLR AMOV A,HOURMOV B,#10DIV ABMOV A,BMOV SHUJI5,Amov column,#56mov pagef,#2MOV CODES,SHUJI5 ;时低位lcall writeleftMOV SHUJI6,#0MOV CODES,#0CLR AMOV A,HOURMOV B,#10MOV SHUJI6,AMOV column,#48MOV pagef,#2MOV CODES,SHUJI6 ;时高位CALL writeleftRET////////////////////////////////////////////////writeleft1: ; 左半屏写入16*16数字子程序MOV DPTR,#TABLE2PUSH column1MOV cpage1,#2MOV ccolumn1,#0MOV A,pagef1ANL A,#07hORL A,#0b8hMOV COM,ACALL PRM0MOV A,column1ORL A,#40hMOV COM,ACALL PRM0MOV A,CODESMOV B,#32MUL ABADD A,DPLMOV DPL,AMOV A,BADDC A,DPHMOV DPH,AlOOp3: MOV A,#00hMOVC A,@A+DPTRMOV DAT,ACALL PRM1INC ccolumn1MOV A,ccolumn1INC DPTRCJNE A,#16,lOOp3CLR CYDEC cpage1INC pagef1MOV A,cpage1CJNE A,#0,DD1RET//////////////////////////////////////////////DD1: MOV A,pagef1ANL A,#07hORL A,#0b8hMOV COM,ACALL PRM0POP column1MOV A,column1ANL A,#3fhORL A,#40hMOV COM,ACALL PRM0MOV ccolumn1,#0AJMP lOOp3//////////////////////////////////////////////writeright1: ; 右半屏写入16*16数字子程序MOV DPTR,#TABLE2push column3MOV cpage3,#2MOV ccolumn3,#0MOV A,pagef3ANL A,#07hORL A,#0b8hMOV COM,ACALL PRR0MOV A,column3ORL A,#40hMOV COM,ACALL PRR0MOV A,CODESMOV B,#32MUL ABADD A,DPLMOV DPL,AMOV A,BADDC A,DPHMOV DPH,AlOOp4: MOV A,#00hMOVC A,@A+DPTRMOV DAT,ACALL PRR1INC DPTRINC ccolumn3MOV A,ccolumn3CJNE A,#16,lOOp4CLR CYDEC cpage3INC pagef3MOV A,cpage3CJNE A,#0,DD2RET/////////////////////////////////////////////DD2: MOV A,pagef3ANL A,#07hORL A,#0b8hMOV COM,ACALL PRR0POP column3MOV A,column3ANL A,#3fhORL A,#40hMOV COM,ACALL PRR0MOV ccolumn3,#0AJMP lOOp4///////////////////////////////////////////// writeleft: ; 左半屏写入8*16数字子程序MOV DPTR,#TABLE1PUSH columnMOV cpage,#2MOV ccolumn,#0MOV A,pagefANL A,#07hORL A,#0b8hMOV COM,ACALL PRM0MOV A,columnORL A,#40hMOV COM,ACALL PRM0MOV A,CODESMOV B,#16MUL ABADD A,DPLMOV DPL,AMOV A,BADDC A,DPHMOV DPH,A////////////////////////////////////////////////////LOOP1: MOV A,#00hMOVC A,@A+DPTRMOV DAT,ACALL PRM1INC DPTRINC ccolumnMOV A,ccolumnCJNE A,#8,LOOP1CLR CYDEC cpageINC pagefMOV A,cpageCJNE A,#0,DD3RET/////////////////////////////////////DD3: MOV A,pagefANL A,#07hORL A,#0b8hMOV COM,ACALL PRM0POP columnMOV A,columnANL A,#3fhORL A,#40hMOV COM,ACALL PRM0MOV ccolumn,#0AJMP LOOP1//////////////////////////////////////////////// writeright: ; 右半屏写入8*16数字子程序MOV DPTR,#TABLE1PUSH column2MOV cpage2,#2MOV ccolumn2,#0MOV A,pagef2ANL A,#07hORL A,#0b8hMOV COM,ACALL PRR0MOV A,column2ORL A,#40hMOV COM,ACALL PRR0MOV A,CODESMOV B,#16MUL ABADD A,DPLMOV DPL,AMOV A,BADDC A,DPHMOV DPH,A////////////////////////////////////////////////////LOOP: MOV A,#00hMOVC A,@A+DPTRMOV DAT,ACALL PRR1INC DPTRINC ccolumn2MOV A,ccolumn2CJNE A,#8,LOOPCLR CYDEC cpage2INC pagef2MOV A,cpage2CJNE A,#0,DD4RET/////////////////////////////////////DD4: MOV A,pagef2ANL A,#07hORL A,#0b8hMOV COM,ACALL PRR0POP column2MOV A,column2ANL A,#3fhORL A,#40hMOV COM,ACALL PRR0MOV ccolumn2,#0AJMP LOOP//////////////////////////////////////////////PRM0: CALL DECLR CSA ;写指令代码子程序(左)SETB CSBCLR RSCLR RWMOV OUTPUT,COMSETB ECLR ERET///////////////////////////////////////////////PRM1: CALL DECLR CSA ;写显示数据子程序(左)SETB CSBSETB RSCLR RWMOV OUTPUT,DATSETB ECLR ERET////////////////////////////////////////////////PRR0: CALL DECLR CSB ;写指令代码子程序(右)SETB CSACLR RSCLR RWMOV OUTPUT,COMSETB ECLR ERETPRR1: CALL DECLR CSB ;写显示数据子程序(右)SETB CSASETB RSCLR RWMOV OUTPUT,DATSETB ECLR ERET////////////////////////////////////////////DE: MOV R7,#10DEE2: MOV R6,#25DJNZ R6,$DJNZ R7,DEE2RET////////////////////////////////////////////CLEAR: MOV R4,#00H ;清屏子程序CLEAR1: MOV A,R4ORL A,#0B8HMOV COM,ALCALL PRM0LCALL PRR0MOV COM,#40HLCALL PRM0LCALL PRR0MOV R3,#40HCLEAR2: MOV DA T,#00HLCALL PRM1LCALL PRR1DJNZ R3,CLEAR2INC R4CJNE R4,#08H,CLEAR1RET///////////////////////////////////////////////////INT: MOV COM,#0C0H ;初始化子程序,设置显示起始行为第一行LCALL PRM0LCALL PRR0MOV COM,#3FH ;开显示设置LCALL PRM0LCALL PRR0RET////////////////定时器中断子程序////////////////////////////////INTP0: MOV TH0,#(65536-50000) / 256MOV TL0,#(65536-50000) MOD 256INC COUNTMOV A,COUNTCJNE A,#20,LOPMOV COUNT,#0CALL CHULILOP: RETI/////////////////////////////////////////////////CHULI: INC SECONDMOV A,SECONDCJNE A,#60,LOPMOV SECOND,#0INC MINUTEMOV A,MINUTECJNE A,#60,LOPMOV MINUTE,#0INC HOURMOV A,HOURCJNE A,#24,LOPMOV HOUR,#1RETI//////////////////按键处理模式//////////////////////////////// KEYSCAN: JB BT0,K11JB KEY1,K12SETB BT0LJMP K13K12: CLR BT0CLR BT1LJMP K13K11: JB KEY1,K12JB BT1,K13SETB BT1INC COUNT1MOV A,COUNT1CJNE A,#3,K13MOV COUNT1,#0K13: RET////////////////分加/////////////////////////KEYCHULI1:MOV A,COUNT1CJNE A,#1,K23CLR AIXINGMOV AIXING,MINUTECALL KK1MOV MINUTE,AIXINGRETKEYCHU1: MOV A,COUNT1CJNE A,#1,K23CLR AIXINGMOV AIXING,MINUTE1CALL KK1MOV MINUTE1,AIXINGRETKEYCHU2: MOV A,COUNT1CJNE A,#1,K23CLR AIXINGMOV AIXING,MINUTE2CALL KK1MOV MINUTE2,AIXINGRETKEYCHU3: MOV A,COUNT1CJNE A,#1,K23CLR AIXINGMOV AIXING,MINUTE3CALL KK1MOV MINUTE3,AIXINGRETKEYCHU4: MOV A,COUNT1CJNE A,#1,K23CLR AIXINGMOV AIXING,MINUTE4CALL KK1MOV MINUTE4,AIXINGRETKK1: JB BT2,K21JB KEY2,K22SETB BT2LJMP K23K22: CLR BT2CLR BT3LJMP K23K21: JB KEY2,K22JB BT3,K23SETB BT3INC AIXINGMOV A,AIXINGCJNE A,#60,K23MOV AIXING,#0K23: RET//////////////////时加///////////////////////////////// KEYCHULI11:MOV A,COUNT1CJNE A,#1,K33CLR AIXING1MOV AIXING1,HOURCALL KK2MOV HOUR,AIXING1RETKEYCHU11: MOV A,COUNT1CJNE A,#1,K33CLR AIXING1MOV AIXING1,HOUR1CALL KK2MOV HOUR1,AIXING1RETKEYCHU21: MOV A,COUNT1CJNE A,#1,K33CLR AIXING1MOV AIXING1,HOUR2CALL KK2MOV HOUR2,AIXING1RETKEYCHU31: MOV A,COUNT1CJNE A,#1,K33MOV AIXING1,HOUR3CALL KK2MOV HOUR3,AIXING1RETKEYCHU41: MOV A,COUNT1CJNE A,#1,K33CLR AIXING1MOV AIXING1,HOUR4CALL KK2MOV HOUR4,AIXING1RETKK2: JB BT4,K31JB KEY3,K32SETB BT4LJMP K33K32: CLR BT4CLR BT5LJMP K33K31: JB KEY3,K32JB BT5,K33SETB BT5INC AIXING1MOV A,AIXING1CJNE A,#24,K33MOV AIXING1,#0K33: RET/////////////////分减/////////////////////////////// KEYCHULI2:MOV A,COUNT1CJNE A,#2,K43CLR AIXINGMOV AIXING,MINUTECALL KK3MOV MINUTE,AIXINGRETKEYCHU5: MOV A,COUNT1CJNE A,#2,K43CLR AIXINGMOV AIXING,MINUTE1CALL KK3MOV MINUTE1,AIXINGRETKEYCHU6: MOV A,COUNT1CJNE A,#2,K43CLR AIXINGMOV AIXING,MINUTE2CALL KK3MOV MINUTE2,AIXINGRETKEYCHU7: MOV A,COUNT1CJNE A,#2,K43CLR AIXINGMOV AIXING,MINUTE3CALL KK3MOV MINUTE3,AIXINGRETKEYCHU8: MOV A,COUNT1CJNE A,#2,K43CLR AIXINGMOV AIXING,MINUTE4CALL KK3MOV MINUTE4,AIXINGRETKK3: JB BT2,K41JB KEY2,K42SETB BT2LJMP K43K42: CLR BT2CLR BT3LJMP K43K41: JB KEY2,K42JB BT3,K43SETB BT3DEC AIXINGMOV A,AIXINGCJNE A,#0FFH,K43MOV AIXING,#59K43: RET///////////////时减////////////////////////////////// KEYCHULI21:MOV A,COUNT1CJNE A,#2,K53CLR AIXING1MOV AIXING1,HOURMOV HOUR,AIXING1RETKEYCHU51:MOV A,COUNT1CJNE A,#2,K53CLR AIXING1MOV AIXING1,HOUR1CALL KK4MOV HOUR1,AIXING1RETKEYCHU61:MOV A,COUNT1CJNE A,#2,K53CLR AIXING1MOV AIXING1,HOUR2CALL KK4MOV HOUR2,AIXING1RETKEYCHU71:MOV A,COUNT1CJNE A,#2,K53CLR AIXING1MOV AIXING1,HOUR3CALL KK4MOV HOUR3,AIXING1RETKEYCHU81:MOV A,COUNT1CJNE A,#2,K53CLR AIXING1MOV AIXING1,HOUR4CALL KK4MOV HOUR4,AIXING1RETKK4: JB BT4,K51JB KEY3,K52SETB BT4LJMP K53K52: CLR BT4CLR BT5LJMP K53K51: JB KEY3,K52JB BT5,K53DEC AIXING1MOV A,AIXING1CJNE A,#0FFH,K53MOV AIXING1,#23K53: RET////////////////切换模式////////////////////////////////////// KEYSCAN1: JB BT8,K61JB KEY4,K62SETB BT8LJMP K63K62: CLR BT8CLR BT9LJMP K63K61: JB KEY4,K62JB BT9,K63SETB BT9CPL BT7K63: RET///////////////选择模式////////////////////////////////// CHULI1: JB BT10,K71JB KEY5,K72SETB BT10LJMP K73K72: CLR BT10CLR BT11LJMP K73K71: JB KEY5,K72JB BT11,K73SETB BT11INC COUNT4MOV A,COUNT4CJNE A,#5,K73MOV COUNT4,#0K73: RET///////////////选择模式调制////////////////////////////////// CHULI2: JB BT12,K81JB KEY6,K82SETB BT12LJMP K83K82: CLR BT12CLR BT13LJMP K83K81: JB KEY6,K82JB BT13,K83SETB BT13INC COUNT5MOV A,COUNT5CJNE A,#2,K83MOV COUNT5,#0K83: RET;*************************************字模表table1: ;数字字模表DB 0F0h,0F8h, 0Ch,04h,04h,0Ch,0F8h,0F0h,0Fh,1Fh,30h,20h,20h,30h,1Fh,0Fh ;0 /* (8 X 16 , 宋体)*/DB 00h,00h,08h,0F8h,0FCh,00h,00h,00h,00h,00h,20h,3Fh,3Fh,20h,00h,00h ;1 /* (8 X 16 , 宋体)*/DB 30h,38h,0Ch,04h,04h,0Ch,0F8h,0F0h,20h,30h,38h,2Ch,26h,23h,21h,38h ;2 /* (8 X 16 , 宋体)*/DB 10h,18h,0Ch,84h,84h,0CCh,78h,30h,08h,18h,30h,20h,20h,31h,1Fh,0Eh ;3/* (8 X 16 , 宋体)*/DB 00h,0C0h,70h,18h,0FCh,0FEh,00h,00h,07h,05h,04h,24h,3Fh,3Fh,24h,04h ;4 /* (8 X 16 , 宋体)*/DB 0FCh,0FCh,0C4h,44h,44h,0C4h,84h,04h,08h,18h,30h,20h,20h,30h,1Fh,0Fh ;5 /* (8 X 16 , 宋体)*/DB 0F0h,0F8h,8Ch, 44h,44h,0CCh,98h,10h,0Fh,1Fh,30h,20h,20h,30h,1Fh,0Fh ;6 /* (8 X 16 , 宋体)*/DB 1Ch,0Ch,0Ch,0Ch,0CCh,0ECh,3Ch,1Ch,00h,00h,3Ch,3Fh,03h,00h,00h,00h ;7 /* (8 X 16 , 宋体)*/DB 30h,78h,0CCh,84h,84h,0CCh,78h,30h,0Eh,1Fh,31h,20h,20h,31h,1Fh,0Eh ;8 /* (8 X 16 , 宋体)*/DB 0F0h,0F8h,0Ch,04h,04h,0Ch,0F8h,0F0h,08h,19h,33h,22h,22h,33h,1Fh,0Fh ;9 /* (8 X 16 , 宋体)*/DB 0F0h,0F8h,0Ch,04h,04h,0Ch,0F8h,0F0h,0Fh,1Fh,30h,20h,20h,30h,1Fh,0Fh ;10 /* (8 X 16 , 宋体)*/DB 00H ,00H ,00H ,0C0H ,0C0H ,00H, 00H ,00H ,00H ,00H, 00H ,30H ,30H ,00H ,00H ,00H;":",11/* (8 X 16 , 宋体)*/DB 00H, 00H ,00H, 00H, 00H ,00H ,00H ,00H, 00H ,01H, 01H ,01H, 01H ,01H, 01H ,01H;"-",12 /* (8 X 16 , 宋体)*/DB 00H ,80H, 80H ,0E0H ,80H ,80H, 00H, 00H ,00H, 00H ,00H ,1FH, 20H, 20H, 00H ,00H;"t",13/* (8 X 16 , 宋体)*/DB 00H ,80H, 80H ,98H ,00H ,00H ,00H, 00H, 00H ,20H ,20H ,3FH, 20H, 20H ,00H ,00H;"i",14 /* (8 X 16 , 宋体)*/DB 80H, 80H ,80H ,80H ,80H ,00H ,00H ,00H ,20H, 3FH ,00H ,3FH ,00H ,3FH ,20H, 00H;"m",15/* (8 X 16 , 宋体)*/DB 00H ,00H ,80H ,80H, 80H ,00H ,00H ,00H ,00H ,1FH ,22H ,22H ,22H ,13H, 00H ,00H;"e",16 /* (8 X 16 , 宋体)*/table2: ;汉字DB 00H,00H,00H,0BEH,2AH,2AH,2AH,0EAH,2AH,2AH,2AH,2AH,3EH,00H,00H,00H;DB 00H,48H,46H,41H,49H,49H,49H,7FH,49H,49H,49H,49H,49H,41H,40H,00H;"星",0/* (16 X 16 , System )*/DB 40H,44H,24H,14H,0FFH,94H,64H,40H,24H,14H,0FFH,0CH,34H,64H,24H,00H;DB 00H,80H,88H,88H,46H,45H,29H,31H,11H,09H,05H,03H,01H,00H,00H,00H;"梦",1/* (16 X 16 , System )*/DB 40H,44H,24H,94H,44H,3CH,05H,46H,84H,7CH,04H,14H,64H,24H,04H,00H;DB 00H,84H,85H,44H,24H,14H,0CH,07H,0CH,14H,24H,64H,0C4H,44H,04H,00H;"奕",2/* (16 X 16 , System )*/DB 20H,38H,0A7H,62H,10H,20H,0A0H,6CH,6BH,0AAH,2AH,3AH,26H,0A0H,20H,00H;DB 12H,13H,12H,0AH,29H,25H,12H,12H,49H,85H,7FH,02H,0DH,18H,08H,00H;"缘",3/* (16 X 16 , System )*/DB 00H,00H,00H,00H,0FFH,00H,00H,00H,80H,7FH,80H,00H,00H,00H,00H,00H;DB 40H,20H,18H,07H,80H,41H,36H,18H,07H,00H,01H,06H,18H,70H,20H,00H;"从",4/* (16 X 16 , System )*/DB 08H,08H,0C8H,0FFH,48H,88H,08H,00H,0FEH,02H,02H,02H,0FEH,00H,00H,00H;DB 04H,03H,00H,0FFH,00H,41H,30H,0CH,03H,00H,00H,00H,3FH,40H,78H,00H;"机",5/* (16 X 16 , System )*/DB 00H,80H,80H,80H,80H,80H,80H,80H,80H,80H,80H,80H,80H,0C0H,80H,00H;DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H;"一",6/* (16 X 16 , System )*/DB 00H,00H,04H,04H,04H,04H,04H,04H,04H,04H,04H,06H,04H,00H,00H,00H;DB 00H,10H,10H,10H,10H,10H,10H,10H,10H,10H,10H,10H,10H,18H,10H,00H;"二",7/* (16 X 16 , System )*/DB 00h,00h,00h,00h,00h,00h,00h,30h,30h,00h,00h,00h,00h,00h,00h,00h ; ":",8DB 00h,00h,00h,00h,00h,00h,00h,0Ch,0Ch,00h,00h,00h,00h,00h,00h,00h;/* (16 X 16 , 宋体)*/DB00H,82H,82H,82H,0BAH,0AAH,0AAH,0ABH,0AAH,0AAH,0BAH,82H,82H,0C2H,80H,00H; DB 02H,41H,40H,20H,10H,0EH,02H,02H,02H,3EH,40H,40H,42H,41H,70H,00H;"亮",9/* (16 X 16 , 宋体)*/DB 00H,02H,02H,0E2H,02H,02H,82H,7EH,0C2H,02H,82H,42H,33H,02H,00H,00H;DB 00H,40H,21H,10H,08H,06H,01H,00H,00H,03H,0CH,18H,30H,60H,20H,00H;"灭",10/* (16 X 16 , 宋体)*/DB 08H ,0F8H, 08H ,00H, 00H ,00H ,00H ,00H, 00H, 00H ,00H, 00H, 00H ,00H, 00H, 00H;DB 20H ,3FH ,20H ,20H ,20H ,20H, 30H, 00H ,00H ,00H ,00H ,00H ,00H, 00H ,00H, 00H;"L",11/* (16 X 16 , 宋体)*/DB 00H,00H,00H,00H,00H,00H,00H,00H,0FH,00H,10H,80h,16H,80H,16H,80H;DB 10H,80H,0FH,00H,00H,00H,00H,00H,00H,00H,00H,00h,00H,00H,00H,00H;"亮",12"E",12 /* (16 X 16 , 宋体)*/DB 08H ,0F8H ,08H ,08H ,08H ,10H ,0E0H ,00H ,00H ,00H ,00H ,00H ,00H ,00H, 00H,00H; DB20H ,3FH ,20H ,20H ,20H ,10H ,0FH ,00H ,00H ,00H ,00H ,00H ,00H ,00H ,00H ,00H;"D",13/* (16 X 16 , 宋体)*/////////"14-23"////////////////模式选择///////////////////////////////////////DB 02H,02H, 32H ,52H ,92H ,1FH ,32H ,52H ,12H ,1FH ,92H ,52H ,32H ,02H ,02H ,00H;DB 00H,42H, 42H, 22H ,12H ,0AH ,06H ,0FFH ,06H ,0AH ,12H ,32H ,62H ,22H ,02H ,00H;"菜",14/* (16 X 16 , 宋体)*/DB 00H ,00H ,0F8H ,28H ,29H ,2EH ,2AH ,0F8H ,28H ,2CH ,2BH ,2AH ,0F8H ,00H ,00H ,00H; DB 08H ,08H ,0BH ,09H ,09H ,09H ,09H ,0FFH ,09H ,09H ,09H ,09H ,0BH ,08H ,08H ,00H;"单",15/* (16 X 16 , 宋体)*/DB 00H ,0FCH ,44H ,44H ,44H ,0FCH ,10H ,90H ,10H ,10H ,10H ,0FFH ,10H ,10H ,10H ,00H; DB 00H ,07H ,04H ,04H ,04H ,07H ,00H ,00H ,03H ,40H ,80H ,7FH ,00H ,00H ,00H, 00H;"时",16/* (16 X 16 , 宋体)*/DB 40H ,30H, 2CH ,0EBH ,28H ,28H ,00H ,0F8H ,08H ,08H ,0FFH ,08H ,08H ,0F8H ,00H ,00H;DB 01H ,01H ,01H ,0FFH ,41H ,21H ,00H, 01H ,01H ,01H ,0FFH ,01H ,01H ,01H ,00H, 00H;"钟",17/* (16 X 16 , 宋体)*/DB 40H ,42H, 42H ,42H ,42H ,0FEH ,42H ,42H ,42H ,42H ,0FEH ,42H ,42H ,42H, 42H ,00H; DB 00H ,40H ,20H ,10H ,0CH ,03H ,00H ,00H ,00H ,00H ,7FH ,00H ,00H ,00H ,00H ,00H;"开",18/* (16 X 16 , 宋体)*/DB 00H,10H ,10H ,10H ,11H ,1EH ,14H ,0F0H ,10H ,18H ,17H ,12H ,18H, 10H ,00H, 00H;DB 01H,81H ,41H ,21H ,11H ,09H ,05H ,03H ,05H ,09H ,31H ,61H ,0C1H, 41H ,01H ,00H;"关",19/* (16 X 16 , 宋体)*/DB 20H ,21H ,0EEH ,04H ,00H ,00H ,0FFH ,29H ,0A9H, 0BFH ,0A9H ,0A9H ,01H ,0FFH ,00H ,00H;DB 00H ,00H ,1FH ,88H ,44H ,30H ,0FH ,00H ,0FH ,04H ,04H ,4FH ,80H ,7FH ,00H ,00H;"调",20/* (16 X 16 , 宋体)*/DB 00H ,40H ,42H, 44H ,5CH ,0C8H ,40H ,7FH ,40H ,0C0H ,50H ,4EH ,44H ,60H ,40H ,00H; DB 00H, 80H ,40H ,20H ,18H ,07H ,00H ,00H ,00H ,3FH ,40H ,40H ,40H ,40H ,78H ,00H;"光",21/* (16 X 16 , 宋体)*/DB 40H ,41H ,0CEH, 04H ,00H ,80H ,40H ,0BEH ,82H ,82H ,82H ,0BEH ,0C0H,40H ,40H ,00H;DB 00H ,00H ,7FH ,20H ,90H ,80H ,40H ,43H ,2CH ,10H ,10H ,2CH ,43H ,0C0H ,40H, 00H;"设",22/* (16 X 16 , 宋体)*/DB 00H ,10H ,0CH ,0A4H ,24H ,24H ,25H ,0E6H ,24H ,24H, 24H ,24H ,14H, 0CH,04H,00H; DB 40H ,20H ,18H ,07H ,08H ,10H ,20H ,7FH ,42H ,42H, 42H ,42H ,40H,40H ,00H,00H;"定",23/* (16 X 16 , 宋体)*/。
LCD1286显示模拟指针时钟
作者:
辅导老师:
摘要:现今,高精度的计时工具大多数都使用了石英体振荡器,于电子钟,石英表,石英钟都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调校,数字式电子钟用集成电路计时时,译码代替机械式转动,用LCD12864显示器代替数码管显示时间,即减小了计时误差,又不失传统的指针风格。
这种表具有时,分,秒显示时间的功能,还可以进行时和分的校对,灵活性好。
本系统利用单片机实现数字时钟功能的主要内容,其中AT89C52是核心元件同时采用LCD12864显示模拟指针时钟的“时”,“分”,“秒”。
它的计时周期为12小时,显满刻度为“11时59分59秒”,另外具有校时功能。
关键词:模拟指针时钟;12864;AT89C52;
LCD1286 display the simulation pointer clock
Abstract: today, high precision timing tool most used quartz oscillators, body in electric clock, quartz watch, quartz clocks are used quartz technology, so when the higher accuracy, good stability, easy to use, does not require constant adjustment, digital electric clock time with integrated circuit, decoding instead of mechanical rotation, with LCD12864 display instead of digital pipe display time, which reduced the timing error, and do not break the traditional pointer style. This table is, points, seconds show time function, and can be made, and the points when great flexibility. This system using the single chip microcomputer digital clock function of the main content, which is the core element and the AT89C52 LCD12864 display the simulation of the clock "" pointer," points ", "second". Its timing cycle for 12 hours, show when full scale for "11 59 points 59 seconds, in addition has the reset" function.
Keywords: simulation pointer clock; 12864; AT89C52;
一、12864点阵液晶显示器的原理介绍
通常所说的12864LCD显示块是所说的点阵液晶显示模块,就是由128*64个液晶显示点组成的一个128列*64行的阵列,所以也就叫成了12864。
每个显示点都对应着有一位二进制数,0表示灭,1表示亮。
存储这些点阵信息的RAM 被称为显示数据存储器。
如果要显示某个图形或汉字就是将相应的点阵信息写入到对应的存储单元中。
图形或汉字的点阵信息是由自己设计,这时候问题的关键是显示点在液晶屏上的位置与其在存储器中的地址之间的关系。
显示点在64*64液晶屏上的位置由列号(line,0~63)与行号(line,0~63)确定。
512*8 bits RAM 中某个存储单元的地址由页地址(Xpage,0~7)和列地址(Yaddress,0~63)确定。
每个存储单元存储8个液晶点的显示信息。
由于多数液晶显示模块的驱动电路是由一片行驱动器和两片列驱动器构成,所以12864液晶屏实际上是由左右两块独立的64*64液晶屏拼接而成,每半屏有一个512*8 bits显示数据RAM。
左右半屏驱动电路及存储器分别由片选信号CS1和CS2选择。
如果点亮12864的屏中(20,30)位置上的液晶点,因列地址30小于64,该点在左半屏第29列,所以CS1有效;行地址20除以8取整得2,取余得4,该点在RAM中页地址为2,在字节中的序号为4;所以将二进制数单元中即点亮(20,30)上的液晶点。
这是为了使液晶点位置信息与存储地址的对应关系更直
观关,将64*64液晶屏从上至下8等分为8个显示块,每块包括8行*64列个点阵。
每列中的8行点阵信息构成一个8bits二进制数,存储在一个存储单元中。
(需要注意:二进制的高低有效位顺序与行号对应关系因不同商家而不同)存放一个显示块的RAM区称为存储页。
即64*64液晶屏的点阵信息存储在8个存储页中,每页64个字节,每个字节存储一列(8行)点阵信息。
因此存储单元地址包括列地址(Yaddress,0~63)和页地址(Xpage,0~7)。
据00010000(也可能是00001000,高低顺序取决于制造商)写入Xpage=2,Yaddress=29的存储。
二、点阵LCD的显示原理
在数字电路中,所有的数据都是以0和1保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。
对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。
而对于中文,常用却有6000以上,于是我们的DOS 前辈想了一个办法,就是将ASCII表的高128个很少用到的数值以两个为一组来表示汉字,即汉字的内码。
而剩下的低128位则留给英文字符使用,即英文的内码。
那么,得到了汉字的内码后,还仅是一组数字,那又如何在屏幕上去显示呢?这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的'A'在字模的记载方式如图1所示:
图1 “A”字模图
而中文的“你”在字模中的记载却如图2所示:
图2 “你”字模图
在编写软件代码之前必须要先掌握汉字取模的方法。
要得到上表中的文字,我们可以借助取模软件来完成。
目前点阵LCD的取模软件有很多,我们以本开发板配套的取模软件为例来介绍一下汉字的取模方法。
打开取模软件出现如下显示界面:
在绿色输入区中输入图形,我们以输入一个时钟的表盘为例,了解其取模过程。
在绿色输入区中输入图形后按“生成字模”键后就看到字模已经在显示区显示出来了。
在“字模选项”中选择“C51格式”就可以在“点阵生成区”得到你要的显示代码。
经过以上步骤后一个模拟指针时钟就取模成功了,在程序中只要调用这段代码就可显示出,其它图形也用同样的方法。
取完要显示的全部图形代码后我们就可以编程了。
三、硬件电路设计
1. 系统方框图
本系统主要由单片机、DS18B20、DS1302、键盘、LCD显示模块组成。
系统设计框图如图所示。
2.总体设计思路
本系统采用STC89C52单片机作为控制器,通过输出各种电脉冲信号来驱动控制各部分电路正常工作;采用DS18B20作为温度芯片,实时显示当天的确定温度值;采用DS1302作为时钟芯片,自动对时、分、秒、年、月、日、星期进行计数;采用LCD12864作为显示模块对温度和时间进行显示;再加上按键调时,使时钟走时与标准时间一致。
这样就构成了一个多功能电子万年历。
四、程序流程图
五、测试方案与测试结果
1.测试方案
测量是否断路和短路采用测量电阻来换算;测量输入电阻采用串联电阻分压法;测量实际温度和电源电压采用仪表直接测量。
2.测试仪器
所使用的测试仪器设备如表1所示。
表1 测试仪器设备
的温度点,记录下标准温度计显示的温度和万年历显示的温度。
六、结论
本设计完成了题目基本部分和发挥部分的所有要求,程序采用模块化设计,硬件电路简单、高效,温度采集、LCD显示模块等各项功能均很好地达到了设计要求。
其中,调时模块是本设计的亮点之一。
七、参考文献
[1] 全国大学生电子设计竞赛组委会.全国大学生电子设计竞赛获奖作品精选.北京:北京理工大学出版社,2003.
[2]马彪.单片机应用技术.上海:同济大学出版社,2009.
[3]张永枫.单片机应用实训教程.西安:西安电子科技大学出版社,2005.
附录1
软件仿真电路图
附录3
硬件电路PCB板。