1602液晶显示+计数器倒计时完整程序
1602LCD显示的秒表 C语言程序
源程序代码://名称:用1602LCD设计的秒表//说明:首先按下K1键时开始计时,自此按下时暂停,第三次按下时继续累积计时,再次按下时停止计时,K2键用于清零秒表。
//#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define delayNOP ( ) ﹛_nop_( ); _nop_( ); _nop_( ); _nop_( );﹜//LCD控制函数void LCD_Initialize( );void LCD_Set_POS(uchar);void LCD_Write_Date(uchar);void Display_String(uchar﹡,uchar);sbit K1 = P1^0;sbit K2 = P1^1;sbit BEEP = P3^0;sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;uchar KeyCount = 0;uchar code msg1[] = ﹛〞Second Watch 0 〞﹜;uchar code msg2[] = ﹛〞>>>> 0 〞﹜;uchar code Prompts[] [16] ={﹛〞:: 1- - - - > 〞﹜,﹛〞:: 1- - - - > ::2 〞﹜,﹛〞:: 1 - >2 ::3- - > 〞﹜,﹛〞:: 1 - >2 ::3- - >4 〞﹜};// 计时缓冲与显示缓冲uchar Time_Buffer[] ={0,0,0,0};uchar LCD_Display_Buffer[]={〞00: 00: 00:00〞}; //// 蜂鸣器//void Beep ()﹛uchar i,j = 70;for (i = 0;i< 180;i++ )﹛while(--j);BEEP = ~BEEP;﹜BEEP = 0;﹜//// 延时//void DelayX(uint ms){uchar i;while(ms--) for (i= 0;i< 120;i++);﹜//// 显示计时//void Show_Second( ){uchar i;LCD_Set_POS(0x45); //设置LCD显示起点for(i = 3;i != 0xff ;i--);{//将两位整数的1/100s,秒,分,时转换为8位数字字符LCD_Display_Buffer[2﹡i+1] = Time_Buffer[i] / 10 + ˊ0 ˊ;LCD_Display_Buffer[2﹡i] = Time_Buffer[i] % 10 + ˊ0 ˊ;//在 = 3,2,1,0时分别显示时,分,秒,1/100sLCD_Writer_Date(LCD_Display_Buffer[2﹡i+1])LCD_Writer_Date(LCD_Display_Buffer[2﹡i])LCD_Writer_Date(ˊ: ˊ)}}//// Time0中断//Void Time0( ) interrupt 1 using 0{THO = -10000 / 256;TLO = -10000 % 256;Time_Buffer[0] ++if(Time_Buffer[0] == 100){Time_Buffer[0] = 0; Time_Buffer[1]++;}if(Time_Buffer[1] == 60) //秒{Time_Buffer[1] = 0; Time_Buffer[2]++;}if(Time_Buffer[2] == 60) //分{Time_Buffer[2] = 0; Time_Buffer[3]++;}if(Time_Buffer[3] == 24) //时Time_Buffer[3] = 0;}////主函数//void main( ){uchar i;IE = 0x82;TMOD = 0x01;THO = -10000 / 256;TLO = -10000 % 256;LCD_Initialize( );Display_String(msg1,0x00);Display_String(msg2,0x40);While(1){if(k1 == 0){DelayX(100);i = ++KeyCount;switch (i){case 1:case 3: TRO = 1;Display_String(Prompts[i-1],0);Break;case 2:case 4: TRO = 0;Display_String(Prompts[i-1],0);break;default:TRO = 0;break;}While (K1 == 0); // 等待释放K1键Beep( );}elseif(K2 == 0){TRO = 0;KeyCount = 0;for(i = 0;i < 4; i++)Time_Buffer [i] = 0; // 清零计数缓冲Display_String(msg1,0);Beep( );DelayX(100);while (K2 == 0); // 等待释放K2键}Show_Second( );}}//// 1602LCD显示驱动函数//#include 〈reg51.h〉#include 〈intrins.h〉#define uchar unsigned char#define uint unsigned int#define DellayNOP( )﹛_nop_( ); _nop_( ); _nop_( ); _nop_( );﹜sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;bit LCD_Busy_Check( );void LCD_Initialize( );void LCD_Set_POS(uchar);void LCD_Write_Command(uchar);void LCD_Write_ Date(uchar);//// 延时//void DelayMS(uint ms){uchar t;while(ms--) for (t =0;t < 120;t++);}//// LCD忙检查//bit LCD_Busy_Check( );{bit Rsult;LCD_RS = 0; LCD_RW = 1; LCD_EN = 1;DelayNOP( );Result = (bit)(p0 ﹠ 0x80);LCD_EN = 0return Result;}//// 向LCD写指令//void LCD_Write_Command(uchar cmd);{while(LCD_Busy_Check() );LCD_RS = 0; LCD_RW = 0; LCD_EN = 0;_nop_( ); _nop_( );pO = cmd; DelayNOP( );LCD_EN = 1;DelayNOP( );LCD_EN = 0;}//// 向LCD写数据//void LCD_Write_Date(uchar str);{while(LCD_Busy_Check() );LCD_RS = 1; LCD_RW = 0; LCD_EN = 0;pO = str; DelayNOP( ); LCD_EN = 1;DelayNOP( );LCD_EN = 0;}//// 初始化LCD//void LCD_Initialize( );{DelayMS(5); LCD_Write_Command(0x38);DelayMS(5); LCD_Write_Command(0x0c);DelayMS(5); LCD_Write_Command(0x06);DelayMS(5); LCD_Write_Command(0x01);DelayMS(5);}//// 设置显示位置//void LCD_Set_POS(uchar Poition){LCD_Write_Command(Position ︱ 0x80);}////显示函数,在LCD指定行上显示字符串//void Display_String(uchar﹡str,uchar LineNO) {uchar k;LCD_Set_POS(LineNO);for (k = 0;k < 16;k++) LCD_Write_Date(str[k]) }。
单片机LCD1602A秒表程序
ORG 0030H
MAIN:
ACALL SET_LCD
;LCD 初始化设置子程序
TOOP:
ACALL WR_THL ACALL RESET_18B20
;将报警上下线写入暂存寄存器 ;18B20 复位子程序
JNB FLAG,TOOP1
;18B20 不存在
ACALL MEU_OK
;显示"OK"菜单
ACALL RE_THL
6
嵌入式应用软件园,版权所有,请勿转载/销售。
第 2 章 程序功能
1.1 程序功能 程序中包含 LCM 用到的所有函数:初始化、写指令、写数据、判
忙碌、清屏幕。 在单片机的 P1 端口上接有 LCD 模块,用来显示计时时间。P3.3、
P3.4 端口分别接有按键 K1、K2,做秒表的计时控制按钮。 K1:暂停和起动秒表。只能暂停和起动二次。 K2:重新开始计时,计时值从 0 开始。
1.2 操作方法 1. 按一下 K2 键,准备计时。 2. 按一下 K1 键,计时开始。 3. 按一下 K1 键,暂停计时。 4. 按一下 K1 键,计时开始,在第 2 步的基础上累计时。 5. 按一下 K1 键,暂停计时。 6. 重复第 1~5 步,循环使用秒表。
7
1.3 原理图
嵌入式应用软件园,版权所有,请勿转载/销售。
MOV A,#0CCH
;跳过 ROM 匹配
ACALL WRITE_18B20
;调写入子程序
MOV A,#44H
;发出温度转换命令
ACALL WRITE_18B20
;调写入子程序
ACALL RESET_18B20
;调复位子程序
MOV A,#0CCH
;跳过 ROM 匹配
1602液晶显示计算器电路图及程序
#include <reg51.h>#include <intrins.h>#include <stdio.h>#include <stdlib.h>unsigned char code Error[]={"error"};unsigned char code Systemerror[]={"system error"};unsigned char code Lcd[]={"lcd calculate"};char str[16];sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit BF=P0^7;/***********************函数功能:延时1ms***********************/void delay1ms(){unsigned char i,j;for (i=0;i<10;i++)for (j=0;j<33;j++);}/************************函数功能:延时n毫秒入口参数:n************************/void delaynms(unsigned char n){unsigned char i;for (i=0;i<n;i++)delay1ms();}/************************************函数功能:判断液晶模块的忙碌状态返回值:result。
result=1,忙碌;result=0,不忙。
************************************/bit BusyTest(void){bit result;RS=0; //根据规定,RS为低电平、RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读/写_nop_();_nop_();_nop_();_nop_();result=BF; //将忙碌标志电平赋给resultE=0;return result;}/*************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate**************************************/void WriteInstruction(unsigned char dictate){while(BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同为低电平时,可以写入指令RW=0;E=0;_nop_();_nop_();P0=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_();E=1; //E置高电平_nop_();_nop_();_nop_();_nop_();E=0;}/*****************************************函数功能:指定字符显示的实际地址入口参数:x,y*****************************************/void WriteAddress(unsigned char x,unsigned char y){unsigned char temp;if(x==0){switch(y){case 0:temp=0x00; break;case 1:temp=0x01; break;case 2:temp=0x02;break;case 3:temp=0x03;break;case 4:temp=0x04;break;case 5:temp=0x05;break;case 6:temp=0x06;break;case 7:temp=0x07;break;case 8:temp=0x08;break;case 9:temp=0x09;break;case 10:temp=0x0a;break;case 11:temp=0x0b;break;case 12:temp=0x0c;break;case 13:temp=0x0d;break;case 14:temp=0x0e;break;case 15:temp=0x0f;break;}}if(x==1){switch(y){case 0:temp=0x40;break;case 1:temp=0x41;break;case 2:temp=0x42;break;case 3:temp=0x43;break;case 4:temp=0x44;break;case 5:temp=0x45;break;case 6:temp=0x46;break;case 7:temp=0x47;break;case 8:temp=0x48;break;case 9:temp=0x49;break;case 10:temp=0x4a;break;case 11:temp=0x4b;break;case 12:temp=0x4c;break;case 13:temp=0x4d;break;case 14:temp=0x4e;break;case 15:temp=0x4f;break;}}WriteInstruction(temp|0x80); //显示位置的确定方法规定为“80H+地址码x”}/*****************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y*****************************************/void WriteData (unsigned char y){while(BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0;P0=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();_nop_();E=0; //当E由高电平跳变成低电平时,液晶模块开始执行指令}/*****************************************函数功能:对LCD的显示模式进行初始化设置*****************************************/void LcdInitiate(void){delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间WriteInstruction(0x38); //显示模式设置delaynms(5);WriteInstruction(0x38);delaynms(5);WriteInstruction(0x38);delaynms(5);WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁delaynms(5);WriteInstruction(0x06); //显示模式设置:光标右移,字符不移delaynms(5);WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除delaynms(5);}/***************************************函数功能:显示字符串***************************************/void display_error(){unsigned char i;WriteAddress(0,0);i=0;while(Error[i]!='\0'){WriteData(Error[i]);i++;delaynms(100);}}void display_systemerror(){unsigned char i;WriteAddress(0,0);i=0;while(Systemerror[i]!='\0'){WriteData(Systemerror[i]);i++;delaynms(100);}}void display_lcd(){unsigned char i;WriteAddress(0,0);i=0;while(Lcd[i]!='\0'){WriteData(Lcd[i]);i++;delaynms(100);}}/*************************** 函数功能:按键判断**************************/bit judge(){unsigned char keycode;P1=0x0f;keycode=P1;if(keycode==0x0f)return(0);elsereturn(1);}/*****************************函数功能:键盘扫描*****************************/ unsigned char scan(){unsigned char keycode,keyscan;keyscan=0xef;while(keyscan!=0xff){P1=keyscan;keycode=P1;if((keycode&0x0f)!=0x0f)break;keyscan=(keycode<<1)|0x0f;}keycode=~keycode;return(keycode);}/*******************************函数功能:扫描键盘返回值******************************/ unsigned char Key_Num(){unsigned char keycode;unsigned char yong;if(judge()){delaynms(20);if(judge()){keycode=scan();while(judge());switch(keycode){case 0x11:yong='7';break;case 0x12:yong='4';break;case 0x14:yong='1';break;case 0x18:yong=0;break;case 0x21:yong='8';break;case 0x22:yong='5';break;case 0x24:yong='2';break;case 0x28:yong='0';break;case 0x41:yong='9';break;case 0x42:yong='6';break;case 0x44:yong='3';break;case 0x48:yong='=';break;case 0x81:yong='/';break;case 0x82:yong='*';break;case 0x84:yong='-';break;case 0x88:yong='+';break;default:display_systemerror() ;}return(yong);}}elsereturn(0xff);}/************************************** itoa函数定义*********************************/ unsigned char itoa(long int num){unsigned char i,j,L;unsigned char temp[16];for(i=0;num!=0;i++){temp[i]=num%10+48;num=num/10;}L=i;if(i>16){display_systemerror();}for(j=0;j<=L;j++){str[j]=temp[i];i--;}return(L);}/*****************************************函数功能:主函数****************************************/void main(){long int a;long int b;unsigned char flag;unsigned char sign;unsigned char i,j,s,x;unsigned char num;unsigned char fgh;unsigned char temp[16];LcdInitiate();display_lcd();delaynms(20);WriteInstruction(0x01);flag=1;while(1){num=Key_Num();if(num!=0xff){if(fgh==1){WriteInstruction(0x01);fgh=0;}if((num!='+')&&(num!='-')&&(num!='*')&&(num!='/')&&(num!='.')&&(num!='=')){if(flag==1){a=a*10+num-48;}else{b=num-48+b*10;}}if(num==0){i=0;flag=1;a=0;b=0;WriteInstruction(0x01);}if((num=='+')||(num=='-')||(num=='*')||(num=='/')){flag=0;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/': {if(b!=0){ a=a/b;break; }else{WriteInstruction(0x01);flag=1;WriteAddress(0,1);display_error();delaynms(40);WriteInstruction(0x01);break;}}default:break;}sign=num;b=0;}if(num=='='){flag=1;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/':a=a/b;break;default:break;}temp[i]=num;WriteAddress(0,i);WriteData(num);for(s=0;s<16;s++)temp[s]=0;s=0;//WriteAddress(1,8);//WriteData(a+48);x=itoa(a); //函数转换WriteAddress(1,1);while(s<=x){WriteData(str[s]);s++;delaynms(100);}sign=0;a=b=0;j=0;for(s=0;s<16;s++)str[s]=0;s=0;fgh=1;i=0;}if(i<16){if(num!='='){if((i==1)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符{temp[0]=num; //如果是1-9数字,说明0没有用,则直接替换第一位0WriteAddress(0,0);//输出数据WriteData(num);}else{temp[i]=num;WriteAddress(0,i);//输出数据WriteData(num);i++; //输入数值累加}}}else{i=0;WriteInstruction(0x01);}}}}枯藤老树昏鸦,小桥流水人家,古道西风瘦马。
lcd倒计时
淮阴师范学院物理与电子电气工程学院课程设计报告学生姓名石伟学号171108025 班级1108专业电气工程及其自动化题目LCD1602显示数字倒计时器的设计指导教师魏东旭、周凯杰2013 年12 月1 任务和设计要求基于AT89C52单片机的LCD1602数字倒计时器。
功能如下:⑴LCD1602显示倒计时时间。
⑵倒计时过程中能设置闹钟,当到达闹钟时间时会发出报警。
⑶通过按键能对倒计时设定初值。
2 系统设计系统框图3 硬件设计3.1 电路原理图3.2 主要单元电路LCD电路图蜂鸣器电路独立键盘电路复位电路3.3 元件清单4 软件设计4.1 程序流程图4.2 主要功能程序设计void time() interrupt 1{TH0=(65536-5000)/256;TL0=(65536-5000)%256;count++;if (count==200)count=0;miao--;if(miao==-1){miao=59;fen--;if(fen==-1){fen=59;shi--;if(shi==-1){shi=23;}}}}}4.3 程序清单#include <reg52.h>#define uchar unsigned charsbit beep=P2^3;sbit key1=P3^4;sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;sbit lcdrs=P2^0;sbit lcden=P2^1;uchar num,m,n;int miao,fen,shi,count,nn,keyon,alarm,exit;uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; void delay(uchar x);uchar scan();void display1();void display2();void lcdwritecom(uchar);void lcdwritedata(uchar);void init();{alarm=0;exit=0;m=0;n=0;EA=1;ET0=1;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TR0=1;miao=10;fen=10;shi=8;while(1){init();nn=scan();if(keyon){switch(nn){case 1:if(alarm){m++;if(m==24)m=0;}if(!alarm){shi++;if(shi==24)shi=0;miao=59;}keyon=0;break;case 2:if(alarm){n++;if(n==60)n=0;}if(!alarm){fen++;if(fen==60)fen=0;miao=59;}keyon=0;break;case 3:alarm=1;keyon=0;break;case 4:exit=1;alarm=0;keyon=0;break;}}if(alarm){display2();}if(!alarm){display1();}if(exit){if(shi==m&fen==n&miao==0){beep=0;}if(shi==m&fen==n-1&miao==50){beep=1;exit=0;}}}}void time() interrupt 1{TH0=(65536-5000)/256;TL0=(65536-5000)%256;count++;if (count==200){count=0;miao--;if(miao==-1){miao=59;fen--;if(fen==-1){fen=59;shi--;if(shi==-1){shi=23;}}}}void delay(uchar x){uchar m,n;for(m=x;m>0;m--)for(n=100;n>0;n--); }uchar scan(){keyon=0;if(key1==0){delay(50);if(key1==0){keyon=1;num=1;}while(!key1);delay(10);while(!key1);}if(key2==0){delay(50);if(key2==0){keyon=1;num=2;}while(!key2);delay(5);while(!key2);if(key3==0){delay(50);if(key3==0){keyon=1;num=3;}while(!key3);delay(5);while(!key3);}if(key4==0){delay(50);if(key4==0){keyon=1;num=4;}while(!key4);delay(5);while(!key4);}return num;}void writecom(uchar com) {lcdrs=0;lcden=0;P0=com;lcden=1;delay(10);lcden=0;}void writedata(uchar date){lcdrs=1;lcden=0;P0=date;lcden=1;delay(10);lcden=0;}void init(){lcden=0;writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x80);}void display1(){writedata(table[shi/10]);writedata(table[shi%10]);writedata(0x3a);writedata(table[fen/10]);writedata(table[fen%10]);writedata(0x3a);writedata(table[miao/10]);writedata(table[miao%10]); }void display2(){writedata(table[m/10]);writedata(table[m%10]);writedata(0x3a);writedata(table[n/10]);writedata(table[n%10]);writedata(0x3a);writedata(table[0]);writedata(table[0]);}5 系统仿真及调试5.1 仿真原理图5.3 仿真结果及分析Key1表示设置时钟初始值的时或闹钟的时;Key2表示设置时钟初始值的分或闹钟的分;Key3表示进入设置闹钟时间;Key4表示退出设置闹钟时间;复位键按下回到程序初始。
LCD1602显示的倒计时装置设计
课程设计名称:单片机原理及接口技术设计题目: LCD1602显示的倒计时装置设计完成期限:自2014 年 1 月 6 日至2014 年 1 月17 日共 2 周设计依据、要求及主要内容:一.设计的目的1.进一步熟悉和掌握单片机系统设计和编程原理。
2.掌握单片机的接口技术及相关外围芯片的外特性、控制方法。
3.通过设计,掌握以单片机核心的电路设计的基本方法和技术。
4.通过实际程序设计和调试,掌握模块化程序设计方法和调试技术。
5.通过完成一个包括电路设计和程序开发的完整过程,了解开发单片机应用系统的全过程,为今后从事相应开发打下基础。
二.设计的基本要求1.认真认识设计的意义,掌握设计工作程序,学会使用工具书和技术参考资料,并培养科学的设计思想和良好的设计作风。
2.提高模型建立和设计能力,学会应用相关设计资料进行设计计算的方法。
3.提高独立分析、解决问题的能力,逐步增强实际应用训练。
4.设计的说明书要求简洁、通顺,电路图内容完整、清楚、规范。
三.设计主要内容a) 设计实现功能STC12C5A60S2(引脚排序及基本功能同AT89S51)作为主控芯片,设计利用LCD1602显示时间和倒计时时间(最大99:59:59)的装置。
一是扩展DS12C887时钟电路设计;二是利用LCD1602显示时间和倒计时剩余时间;三是在倒计时时间减为零以后,进行加1时间显示;四是设计启动、暂停、停止按键。
b) 原理图设计1.原理图设计要符合项目的工作原理,连线要正确。
2.图中所使用的元器件要合理选用,电阻、电容等器件的参数要正确标明。
3.原理图要完整,CPU、外围器件、外扩接口、输入/输出装置要一应俱全。
c) 程序调计1.根据要求,将总体功能分解成若干个子功能模块,每个功能模块完成一个特定的功能。
2.根据总体要求及分解的功能模块,确定各功能模块之间的关系,设计出完整的程序流程图。
d) 程序调试1.编写相关程序,并进行仿真。
2.将程序下载到单片机,进行运行调试。
1602液晶显示器基本操作时序
1602液晶显示器基本操作时序标题:1602液晶显示器基本操作时序简介:本文将介绍1602液晶显示器的基本操作时序,帮助读者了解如何正确使用该显示器。
正文:1602液晶显示器是一种常用的显示设备,广泛应用于各种电子产品中。
为了正确使用该显示器,了解其基本操作时序是非常重要的。
第一步是连接显示器。
首先,将显示器的VSS引脚连接到地,VDD 引脚连接到电源正极。
接着,将V0引脚连接到可变电阻器的中间引脚,两侧引脚分别连接到地和电源正极。
然后,将RS引脚连接到控制器的某个I/O口,RW引脚连接到地,E引脚连接到控制器的另一个I/O口。
最后,将D4-D7引脚分别连接到控制器的其他四个I/O 口。
第二步是初始化显示器。
在连接完成后,需发送一系列指令来初始化显示器。
首先,将RS引脚置低电平,表示发送的是指令。
然后,发送0x33指令,接着发送0x32指令。
这两个指令用于设置显示模式。
接下来,发送0x28指令,用于设置显示器的行数和字体大小。
最后,发送0x0C指令,用于开启显示器并关闭光标。
第三步是写入数据。
在初始化完成后,可以向显示器写入数据进行显示。
将RS引脚置高电平,表示发送的是数据。
然后,发送0x80指令,将光标定位到第一行第一列。
接着,通过发送ASCII码来显示相应的字符或数字。
发送完一个字符后,将光标右移一位,直到显示完所有内容。
第四步是清屏和光标复位。
如果需要清除屏幕上的内容,只需发送0x01指令即可。
同时,可以将光标复位到第一行第一列,发送0x80指令即可。
在使用1602液晶显示器时,需要注意以上基本操作步骤和时序。
确保连接正确,并按照指令发送数据,才能正常显示内容。
同时,注意避免触碰显示器的其他部分,以免损坏设备。
总结:本文介绍了1602液晶显示器的基本操作时序,包括连接显示器、初始化显示器、写入数据以及清屏和光标复位。
正确操作显示器,能够实现准确的显示效果,提升用户体验。
希望本文能为读者在使用1602液晶显示器时提供一些帮助。
LCD1602液晶显示秒表程序
1.LCD1602驱动程序的编程要想让LCD1602显示出我们需要的内容,就的严格按照LCD1602的工作时序来进行编程。
驱动LCD1602显示程序主要有几个子程序组成:1.1 初始化子程序;*****************************************************************;LCD 初始化子程序;8位数据传送方式,双行显示,字形5*7点阵。
;开显示,不显示光标。
;*****************************************************************; INIT_LCD:ACALL DELAY5MS ;延时15MS,等待LCD电源稳定ACALL DELAY5MSACALL DELAY5MSMOV A,#38H ;双行显示,字形5*7点阵,8位数据转移。
ACALL WCOM_NC ;不检测忙信号ACALL DELAY5MSMOV A,#38HACALL WCOM_NCACALL DELAY5MSMOV A,#38HACALL WCOM_NCACALL DELAY5MSMOV A,#38H ;双行显示,字形5*7点阵,8位数据转移。
ACALL WCOM ;检测忙信号ACALL DELAY5MSMOV A,#0CH ;开显示,不显示光标,光标不闪烁。
ACALL WCOMACALL DELAY5MSMOV A,#06H ;移动光标(光标加1)ACALL WCOMACALL DELAY5MSMOV A,#01H ;清除 LCD 显示屏ACALL WCOMACALL DELAY5MSRET完全可以根据自己实际的使用情况来对LCD1602进行初始化操作。
例如:选择单行显示时,选择下列操作指令。
MOV A,#30H ;单行显示,字形5*7点阵,8位数据转移。
ACALL WCOM ;检测忙信号LCD控制器的指令有许多,详细内容请参阅在《电子制作》发表的相关文章。
1602电子时钟程序
#include<reg52.h> //52单片机头文件#define uchar unsigned char //宏定义#define uint unsigned intsbit rs=P1^0; //声明单片机P1口的第一位读写指令还是数据端sbit rw=P1^1; //声明单片机P1口的第二位读写数据端sbit lcden=P1^2; //声明单片机P1口的第三位液晶使能端sbit s1=P2^5; //声明单片机P2口的第六位按键控制端sbit s2=P2^6; //声明单片机P2口的第七位按键控制端sbit s3=P2^7; //声明单片机P2口的第八位按键控制端sbit s4=P2^0; //声明单片机P2口的第一位按键控制端sbit s5=P2^4; //声明单片机P2口的第五位按键控制端sbit a=P3^5; //声明单片机P3口的第六位按键控制端char count,shi,fen,miao,s1num,xp,s5num,date1; //定义有符号字符形变量char nian,tian,yue,nshi,nfen; //定义有符号字符形变量uchar code table[]=" 2000-01-01 Mon "; //定义日期时间数组uchar code table1[]=" 00:00:00";uchar code table2[]=" Alarm clock"; //定义日期时间数组uchar code table3[]=" 00:00";void delay(uint z){uint x,y;for(x=z;x>0;x--) //延时子函数for(y=110;y>0;y--);}void write_com(uchar com) //指令子函数{rs=0; //选择写指令lcden=0; //使能端初始为底P0=com; //将送到要写的指令数据线上delay(5); //延时待数据稳定lcden=1; //使能端给一个高脉冲把数据写入1602液晶delay(5); //延时lcden=0; //拉低使能端完成高脉冲}void write_date(uchar date) //数据子函数{rs=1; //选择写数据lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init() //初始子函数{uchar num; //定义变量用来调用数组rw=0; //选择只写数据到液晶lcden=0; //初始使能端为低电平write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口write_com(0x0c); //开显示,不显示光标write_com(0x06); //写一个字符指针自动加1write_com(0x01); //显示清零,数据指针清零write_com(0x80); //将数据指针定位到第一行第一个字处for(num=0;num<15;num++){write_date(table[num]); //写日期数组数据delay(20);}write_com(0x80+0x40); //选择将时间写到液晶第二行for(num=0;num<12;num++){write_date(table1[num]); //写时间数组数据delay(20);}write_com(0x80+16); //使用移屏操作for(num=0;num<13;num++){write_date(table2[num]); //写闹钟名称delay(20);}write_com(0x80+0x40+16); //选择移屏第二行for(num=0;num<10;num++){write_date(table3[num]); //写闹钟初始值delay(20);}TMOD=0x01; //选择定时器工作方式为方式1TH0=(65536-50000)/256; //装初值TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //选择定时器零TR0=1; //开定时器零}void write_sfm(uchar add,uchar date ) //子函数写时间日期到液晶上{uchar shi,ge; //定义变量用以分离十位和个位上的数字shi=date/10; //分离十位上的数字ge=date%10; // 分离个位上的数字write_com(0x80+0x40+add) ; //给出写的位置指令write_date(0x30+shi); //写十位上的数字write_date(0x30+ge); //写个位上的数字}void write_sfn(uchar add,uchar date) //子函数写时间日期到液晶上{uchar shi,ge; //定义变量用以分离十位和个位上的数字shi=date/10; //分离十位上的数字ge=date%10; // 分离个位上的数字write_com(0x80+add) ; //给出写的位置指令write_date(0x30+shi); //写十位上的数字write_date(0x30+ge); //写个位上的数字}void keyscan() //按键子函数{{s4=0; //让共同接口置零if(s1==0) //判断s1是否被按下{delay(5); //延时5ms去斗if(s1==0) //再次判断s1是否真被按下{s1num++; //设置变量判断s1被按下几次while(!s1); //松手检测if(s1num==1) //S1被第一次按下{TR0=0; //关定时器write_com(0x80+0x40+11); //确定指针位置在秒钟write_com(0x0f); //开显示显示光标光标闪烁}}if(s1num==2){write_com(0x80+0x40+8); //确定指针位置在分钟}if(s1num==3){write_com(0x80+0x40+5); //确定指针位置在时针}if(s1num==4){write_com(0x80+4); //确定指针位置在时针}if(s1num==5){write_com(0x80+7); //确定指针位置在时针}if(s1num==6){write_com(0x80+10); //确定指针位置在时针}if(s1num==7){write_com(0x80+14); //确定指针位置在时针}if(s1num==8){uchar num ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ; //移屏操作write_com(0x18) ;write_com(0x18) ;write_com(0x18) ; //整屏左移同时光标也跟着移动write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x80+0x40+22); //确定指针位置在时针}if(s1num==9){write_com(0x80+0x40+25); //确定指针位置在时针}if(s1num==10){uchar n;while(n<24){n++; //移屏操作write_com(0x18);}s1num=0;n=0;write_com(0x0c); //结束光标显示表开始走TR0=1;}}}if(s1num!=0) //说明已S1被按下{if(s2==0) //判断S2是否被按下{delay(5); //判断S2是否真被按下if(s2==0); //判断S2是否真被按下{while(!s2); //松手检测if(s1num==1) //判断S1被按下一下{miao++; //秒自加一if(miao==60) //判断miao是否为60miao=0; //秒清零write_sfm(10,miao) ; //把秒数据写到指定位置write_com(0x80+0x40+11); //不让指针向后移}if(s1num==2) //判断S1被按下两下{fen++; //分自加一if(fen==60) //判断fen是否为60fen=0; //fen清零write_sfm(7,fen) ; //把fen数据写到指定位置write_com(0x80+0x40+8); //不让指针向后移}if(s1num==3) //判断S1被按下三下{shi++; //shi自加一if(shi==24) //判断shi是否为24shi=0; //shi清零write_sfm(4,shi) ; //把shi数据写到指定位置write_com(0x80+0x40+5); //不让指针向后移}if(s1num==4) //判断S1被按下四下{nian++; //nian自加一write_sfn(3,nian) ; //把年数据写到指定位置write_com(0x80+4); //不让指针向后移}if(s1num==5) //判断S1被按下五下{yue++; //yue自加一if(yue==13) //使月循环加yue=1;write_sfn(6,yue) ; //把月数据写到指定位置write_com(0x80+7); //不让指针向后移}if(s1num==6) //判断S1被按下六下{tian++; //tian自加一if(yue==1,3,5,7,8,10,12){if(tian==32)tian=1;}if(yue==2){if(tian==29)tian=1;}if(yue==4){if(tian==31) //解决不同的月有不同的天的问题tian=1;}if(yue==6){if(tian==31)tian=1;}if(yue==9){if(tian==31)tian=1;}if(yue==11){if(tian==31)tian=1;}write_sfn(9,tian) ; //把天数据写到指定位置write_com(0x80+10); //不让指针向后移}if(s1num==8) //判断S1被按下八下{nshi++; //闹钟的时自加一if(nshi==24)nshi=0;write_sfm(21,nshi) ;write_com(0x80+0x40+22);}if(s1num==9) //判断S1被按下九下{nfen++; //闹钟的分自加一if(nfen==60) //判断nfen是否为60nfen=0; //nfen清零write_sfm(24,nfen) ; //把nfen数据写到指定位置write_com(0x80+0x40+25); //不让指针向后移}}}if(s1num==7) //判断S1被按下七下{if(s5==0){delay(5);if(s5==0){s5num++;while(!s5);if(s5num==1){write_com(0x80+12);write_date(0x4D);write_com(0x80+13);write_date(0x6F); //写星期一write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==2){write_com(0x80+12);write_date(0x54);write_com(0x80+13); //写星期二write_date(0x75);write_com(0x80+14);write_date(0x65);write_com(0x80+14);}if(s5num==3){write_com(0x80+12);write_date(0x57);write_com(0x80+13);write_date(0x65); //写星期三write_com(0x80+14);write_date(0x64);write_com(0x80+14);}if(s5num==4){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x68); //写星期四write_com(0x80+14);write_date(0x75);write_com(0x80+14);}if(s5num==5){write_com(0x80+12);write_date(0x46);write_com(0x80+13);write_date(0x72); //写星期五write_com(0x80+14);write_date(0x69);write_com(0x80+14);}if(s5num==6){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x61); //写星期六write_com(0x80+14);write_date(0x74);write_com(0x80+14);}if(s5num==7){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x75); //写星期日write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==7){s5num=0;}}}}if(s3==0) //判断S3是否被按下{delay(5); //判断S3是否真被按下if(s3==0) //判断S3是否真被按下{while(!s3); //松手检测if(s1num==1) //判断S1被按下一下{miao--; //秒自减一if(miao==-1) //当秒等于-1时miao=59; //把秒赋值为59write_sfm(10,miao); //把秒数据写到指定位置write_com(0x80+0x40+11); //不让指针向后移}if(s1num==2) //判断S1被按下两下{fen--; //分自减一if(fen==-1) //当分等于-1时fen=59; //把分赋值为59write_sfm(7,fen); //把分数据写到指定位置write_com(0x80+0x40+8); //不让指针向后移}if(s1num==3) //判断S1被按下三下{shi--; //时自减一if(shi==-1) //当时等于-1时shi=23; //把时赋值为59write_sfm(4,shi); //把时数据写到指定位置write_com(0x80+0x40+5); //不让指针向后移}if(s1num==4) //判断S1被按下四下{nian--; //年自减一if(nian==-1){nian=0; //不让年少于2000}write_sfn(3,nian); //把时数据写到指定位置write_com(0x80+4); //不让指针向后移}if(s1num==5) //判断S1被按下五下{yue--; //月自减一if(yue==-1) //当月等于-1时yue=12; //把月赋值为12if(yue==0)yue=12; //解决月第一次减不正确的问题write_sfn(6,yue); //把时数据写到指定位置write_com(0x80+7); //不让指针向后移}if(s1num==6) //判断S1被按下六下{tian--; //天自减一if(yue==2){if(tian==-1)tian=28;if(tian==0)tian=28;}if(yue==4){if(tian==-1)tian=30;if(tian==0) // 解决不同的月有不同的天的问题tian=30;}if(yue==6){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==9){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==11){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==1,3,5,7,8,10,12){if(tian==-1)tian=31;if(tian==0)tian=31;}write_sfn(9,tian); //把时数据写到指定位置write_com(0x80+10); //不让指针向后移}if(s1num==8) //判断S1被按下八下{nshi--; //闹钟的时自减一if(nshi==-1)nshi=23;write_sfm(21,nshi) ; //把nshi数据写到指定位置write_com(0x80+0x40+22); //不让指针向后移}if(s1num==9) //判断S1被按下九下{nfen--; //闹钟的分自加一if(nfen==-1) //判断nfen是否为-1nfen=59; //nfen为59write_sfm(24,nfen) ; //把nfen数据写到指定位置write_com(0x80+0x40+25); //不让指针向后移}}}}}void main() //主函数{init(); //初始化函数while(1){keyscan(); //控制按键}}void timer0() interrupt 1 //中断子函数{TH0=(65536-50000)/256; //重装初值TL0=(65536-50000)%256;count++; //用以计时的变量if(count==20) //判断中断时间是否为一秒{count=0; //为一秒count清零重新计时miao++; //秒加一if(miao==60) //判断miao是否为60{miao=0; //为60miao清零fen++; //fen加一if(fen==60) //判断fen是否为60{fen=0; //为60fen清零shi++; //时加一if(shi==24) //判断shi是否为24{shi=0; //为24shi清零tian++; //天自加一s5num++;if(s5num==1){write_com(0x80+12);write_date(0x4D);write_com(0x80+13);write_date(0x6F); //写星期一write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==2){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x75); //写星期二write_com(0x80+14);write_date(0x65);write_com(0x80+14);}if(s5num==3){write_com(0x80+12);write_com(0x80+13);write_date(0x65); //写星期三write_com(0x80+14);write_date(0x64);write_com(0x80+14);}if(s5num==4){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x68); //写星期四write_com(0x80+14);write_date(0x75);write_com(0x80+14);}if(s5num==5){write_com(0x80+12);write_date(0x46);write_com(0x80+13);write_date(0x72); //写星期五write_com(0x80+14);write_date(0x69);write_com(0x80+14);}if(s5num==6){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x61); //写星期六write_com(0x80+14);write_date(0x74);write_com(0x80+14);}if(s5num==7){write_com(0x80+12);write_com(0x80+13);write_date(0x75); //写星期日write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==7){s5num=1;}if(yue==1,3,5,7,8,10,12){if(tian==32)tian=1;}if(yue==4){if(tian==31) //解决天循环问题tian=1;}if(yue==6){if(tian==31)tian=1;}if(yue==9){if(tian==31)tian=1;}if(yue==11){if(tian==31)tian=1;}if(yue==2){if(tian==29)tian=1;}write_sfn(9,tian); //写天到指定位置if(tian==1){yue++;if(yue==13) //月循环{yue=1;}if(yue==1)nian++;write_sfn(3,nian); //写年到指定位置}write_sfn(6,yue); //写月到指定位置}write_sfm(4,shi); //写小时到指定位置}write_sfm(7,fen); //写分钟到指定位置if(shi==nshi&&fen==nfen){uchar n,s;while(n<60){n++;if(s5==0){ //控制闹钟delay(5);if(s5==0){while(!s5);s++;}}if(s!=1){s=0;a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50); //蜂鸣器的响与断a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);}}if(n==60){fen++;if(fen==60){fen=0; shi++;} write_sfm(4,shi); //闹钟响一分钟分自加一}write_sfm(7,fen); //写分钟到指定位置n=0;s=0;}}}write_sfm(10,miao); //写秒钟到指定位置}。
1602液晶显示计算器00.
1602液晶显示计算器院系:机械工程学院班级:测控1003姓名:金飞完成时间:2012年11月18日摘要本设计由51单片机作为核心,4*4矩阵键盘作为输入,将数据输入到单片机内部处理,并通过1602液晶显示出来运算及其结果。
本设计具有成本低廉,操作简单。
可作为日常简单计算使用。
关键词:51单片机、矩阵键盘、1602液晶。
一、外观介绍:二、电路仿真:P0.0~P0.7引脚接lcd的D0-D7,P3口接矩阵键盘。
单片机的P2.4、P2.0、P2.3脚分别接到LCD的RS、R/W、E管。
三、显示电路,LCD1602A的引脚详细介绍:采用LCD1602A来显示,要求能显示两行。
它的D—7D引脚分别接到单片机的P0.0~P0.7引脚;RS、R/W、E管脚分别接到单片机的P2.4、P2.0、P2.3 。
具体连接见后面的电路图。
以下是1602的16进制ASCII码表三、矩阵键盘扫描电路P3口的P3.0,P3.1,P3.2和P3.3四根线作为按键的行输出线,用P3.4,P3.5,P3.6和P3.7作为按键的列输入线。
依次给某一行低电平,再判断哪一列是低电平。
于是就判断出哪行和哪列导通。
对于不同的组合可以确定所有按键位置,将位置赋值到一个变量中,以供使用。
具体来说:假如按下的是数字5键(编号6——位于第二行第二列),首先置第一行为低电平其他7位为高电平P0=0xfe,再检测高四位的电平(P0=P&0xf0 ),因为列没有一条与第一行相导通,所以P0的高位还是高电平的。
然后再换第二行P0=0xfd,同理检测高四位(P0=P&0xf0 )得出P0=0xd0,则5键所在位置为第二行第二列,然后num赋值为6。
四、程序分析可知共分为七个模块:键盘扫描部分,定义各个位置上的键值部分,延迟部分,存贮部分,液晶显示部分,运算部分,动态显示部分。
主程序流程图如下:否判断是否有键按下五、程序#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit lcden=P2^3;sbit rs=P2^4;sbit rw=P2^0;sbit busy=P0^7;char i,j,temp,num,num_1;long a,b,c;float a_c,b_c;uchar flag,fuhao;uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0x2b-0x30}; void delay(uchar z){uchar y;for(z;z>0;z--)for(y=0;y<110;y++);}void check(){do{P0=0xFF;rs=0;rw=1;lcden=0;delay(1);lcden=1;}while(busy==1);}void write_com(uchar com){P0=com;rs=0;rw=0;lcden=0;check();lcden=1;}void write_date(uchar date) {P0=date;rs=1;rw=0;lcden=0;check();lcden=1;}void init(){num=-1;lcden=1;write_com(0x01);write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x80);write_com(0x01);num_1=0;i=0;j=0;a=0;b=0;c=0;flag=0;fuhao=0;}void keyscan(){P3=0xfe;if(P3!=0xfe){delay(20);if(P3!=0xfe){temp=P3&0xf0;{case 0xe0:num=0;break;case 0xd0:num=1;break;case 0xb0:num=2;break;case 0x70:num=3;break;}}while(P3!=0xfe);if(num==0||num==1||num==2){if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}Else{b=b*10+table[num];}}else{flag=1;fuhao=4;}i=table1[num];write_date(0x30+i);}P3=0xfd;if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;{case 0xe0:num=4;break;case 0xd0:num=5;break;case 0xb0:num=6;break;case 0x70:num=7;break;}}while(P3!=0xfd);if(num==4||num==5||num==6&&num!=7) {if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}else{b=b*10+table[num];}}Else{flag=1;fuhao=3;}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;{case 0xe0:num=8;break;case 0xd0:num=9;break;case 0xb0:num=10;break;case 0x70:num=11;break;}}while(P3!=0xfb);if(num==8||num==9||num==10) {if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}Else{b=b*10+table[num];}}else if(num==11){flag=1;fuhao=2;}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;break;case 0xb0:num=14;break;case 0x70:num=15;break;}}while(P3!=0xf7);switch(num){case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;} break;case 13:{if(flag==0){a=a*10;write_date(0x30);P1=0;}else if(flag==1){b=b*10;write_date(0x30);}}break;case 14:{j=1;if(fuhao==1){write_com(0x80+0x4f);write_com(0x04);c=a+b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x80+0x4f);write_com(0x04);if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x80+0x4f);write_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x80+0x4f);write_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;i++;if(i==3)write_date(0x2e);}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}break;}}}main(){init();while(1){keyscan();}}以下程序才对#include<reg52.h> //头文件#define uint unsigned int //#define uchar unsigned charsbit lcden=P2^5; //定义引脚sbit rs=P2^4;sbit rw=P2^0;sbit busy=P0^7;char chufa=0;char chenfa=0;char jiafa=0;char jianfa=0;/***sbit dula=P2^6;sbit wela=P2^7;***/uchar code table2[]="overflow";char i,j,temp,num,num_1;long a,b,c; //a,第一个数b,第二个数c,得数long a_c,b_c; //floatuchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0x2b-0x30};void delay(uchar z) // 延迟函数{uchar y;for(z;z>0;z--)for(y=0;y<110;y++);}void check() // 判断忙或空闲{do{P0=0xFF;rs=0; //指令rw=1; //读lcden=0; //禁止读写delay(1); //等待,液晶显示器处理数据lcden=1; //允许读写}while(busy==1); //判断是否为空闲,1为忙,0为空闲}void write_com(uchar com) // 写指令函数{P0=com; //com指令付给P0口rs=0;rw=0;lcden=0;check();lcden=1;}void write_date(uchar date) // 写数据函数{P0=date;rs=1;rw=0;lcden=0;check();lcden=1;}void init() //初始化{num=-1;/***dula=0;wela=0;***/lcden=1; //使能信号为高电平write_com(0x38); //8位,2行write_com(0x0c); //显示开,光标关,不闪烁*/write_com(0x06); //增量方式不移位write_com(0x80); //检测忙信号write_com(0x01); //显示开,光标关,不闪烁num_1=0;i=0;j=0;a=0; //第一个参与运算的数b=0; //第二个参与运算的数c=0;flag=0; //flag表示是否有符号键按下,fuhao=0; // fuhao表征按下的是哪个符号}void keyscan() // 键盘扫描程序{P3=0xfe;if(P3!=0xfe){delay(20); //延迟20msif(P3!=0xfe){temp=P3&0xf0;switch(temp){case 0xe0:num=0;break;case 0xd0:num=1;break;case 0xb0:num=2;break;case 0x70:num=3;break;}}while(P3!=0xfe);if(num==0||num==1||num==2)//如果按下的是'7','8'或'9if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'/'{flag=1;fuhao=4;//4表示除号已按chufa++;if (chufa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chufa = 0;}/*** chenfa++;if(chenfa==1){write_date(0x21);chenfa=0;}***/}i=table1[num];write_date(0x30+i);}if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;switch(temp){case 0xe0:num=4;break;case 0xd0:num=5;break;case 0xb0:num=6;break;case 0x70:num=7;break;}}while(P3!=0xfd);if(num==4||num==5||num==6)//如果按下的是'4','5'或'6' {if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'/'{flag=1;fuhao=3;//3表示乘号已按chenfa++;if (chenfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chenfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;switch(temp){case 0xe0:num=8;break;case 0xd0:num=9;break;case 0xb0:num=10;break;case 0x70:num=11;break;}}while(P3!=0xfb);if(num==8||num==9||num==10)//如果按下的是'1','2'或'3' {if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else if(num==11)//如果按下的是'-' {flag=1;fuhao=2;//2表示减号已按jianfa++;if (jianfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jianfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;case 0xb0:num=14;break;case 0x70:num=15;break;}}while(P3!=0xf7);switch(num){case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"break;case 13:{ //按下的是"0"if(flag==0)//没有按过符号键{a=a*10;write_date(0x30);P1=0;}else if(flag==1)//如果按过符号键{b=b*10;write_date(0x30);}}break;case 14:{j=1;rw=0;rs=0;if(fuhao==1){write_com(0x0f);//按下等于键,光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格c=a+b;delay(10);while(c!=0){write_date(0x30+c%10);//c=c/10;write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x0f);//光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x0f); //0x80+0x4fwrite_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);//write_date(0x30);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x40+0x4f); //0x80+0x4fwrite_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;if(i==3)write_date(0x2e);}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;jiafa++;if (jiafa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jiafa = 0;}}break;}}}/*void key(){P3=0xfe;if(P3!=0xfe){delay(5);if(P3!=oxfe){temp=P3&0xf0;}}}*/main(){init();while(1) {keyscan(); }}。
lcd1602液晶显示数字钟
{
time[1]=0;//超过,分清零
time[0]++;//小时加1
if(time[0]>23)//是否超过23
{
time[0]=0; //小时清零
•}
•
}
时间计算
• void main(void)
•{
•
uchar i;
•
•
while(1)
•
{
• 计时
for(i=0;i<250;i++)//循环调用显示程序250次,实现1秒
display_code[]={0x3f,0x60,0x5b,0x4 f,0x66,0x5d,0x7d,0x07,0x7f,0x6f,0x 40}; • uchar time[4]={0,0,0,0}; //时间初 值全为0
• void delay(void);//延时0.5毫秒 •{
定时1秒
• uchar i;
• for(i=250;i>0;i--);
•}
• void display()
/*程序用于P0口接数码管的断码,P2接数码管的位码*/
•{
•
uchar i,k;
•
k=0x80;
//k初始化,指向第一位数码管
•
for(i=0;i<8;i++) //循环8次,i值为0~7
•
{
•
P2=0;
//关闭显示
•
P0=display_code[time[i]/10]; //输出十位数的断码
•
•
{
•
display();//调用动态显示,动态显示一次约4毫秒
•
}
1602液晶显示程序
ListLength = 0; Y &= 0x1; X &= 0xF; //限制 X 不能大于 15,Y 不能大于 1 while (DData[ListLength]>0x20) //若到达字串尾则退出 { if (X <= 0xF) //X 坐标应小于 0xF { DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符 ListLength++; X++; } } } //5ms 延时 void Delay5Ms(void) { unsigned int TempCyc = 5552; whilehar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Delay5Ms(void); void Delay400Ms(void); unsigned char code csdn[] = {"csdn"}; unsigned char code net[] = {}; void main(void) { LCMInit(); //LCM 初始化 Delay5Ms(); //延时片刻(可不要) DisplayListChar(0, 5, csdn); DisplayListChar(1, 0, net); ReadDataLCM();//测试用句无意义 while(1); } //写数据 void WriteDataLCM(unsigned char WDLCM) { ReadStatusLCM(); //检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在这后加小的延时 LCM_E = 0; //延时 LCM_E = 1; } //写指令 void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC 为 0 时忽略忙检测 { if (BuysC) ReadStatusLCM(); //根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; } //读数据 unsigned char ReadDataLCM(void) { LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0;
项目六 1602液晶显示计数器制作
void disp_one(uchar x, uchar y,uchar dispbuf);//到指定位置显示单个字符 的函数声明 void disp_mul(uchar x, uchar y,uchar code *dispbuf);//到指定的位置显示 多个字符的函数声明
高等教育出版社
Higher Education Press
高等教育出版社
Higher Education Press
任务一 1602液晶显示字符
2.1602液晶显示模块知识
(3)模块的使用——驱动函数
/******到指定的位置显示多个字符****************/ void disp_mul(uchar x, uchar y,uchar code *dispbuf) { uchar len, i; len=strlen(dispbuf); //计算要显示的字符串长度 y&=0x01; //限制X,Y位置 x&=0x0F; if(x<=0x0F) //X坐标小于一行执行显示 { for (i=0;i<len;i++) { disp_one(x,y,dispbuf[i]); //显示单个字符 x++; } } 等教育出版社 } 高 Higher Education Press
Higher Education Press
E
DB0-DB7 LEDA LEDK
输入
输入/输出
使能信号,下降沿触发
数据总线从低位到高位 背光电源正端(+5V) 背光电源负端(0V)
1602液晶引脚及其功能
任务一 1602液晶显示字符
2.1602液晶显示模块知识
(2)模块显示字符原理
51单片机实现LCD1602显示定时计数器(自己整理的)
每隔一分钟,蜂鸣器响一次,按键按一下,计数器清0。
从新开始、#include<>#include<>#define uchar unsigned char#define uint unsigned intsbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;uchar code dis2[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};uchar code p[]="-";//code 可以不加,加了之后就是固定了这个数组不能对其进行操作、、这个一定要注意。
uchar j,k,kk,miao,miao1,fen,fen1,shi,shi1;void delay_ms(int x)//延时程序,延时1ms{uint i;while(x--)for(i=0;i<120;i++);}uchar busy()//对LCD1602进行判断是否为忙{uchar status;RS=0;RW=1;EN=1;delay_ms(1);status=P1;EN=0;return status;}void write_cmd(uchar cmd)//写命令程序,首先对其进行判忙{while((busy()&0x80)==0x80);//对返回进行判断,如果为忙就进行等待RS=0;RW=0;EN=0;P1=cmd;EN=1;delay_ms(1);EN=0;}void write_data(uchar dat){while((busy()&0x80)==0x80);RS=1;RW=0;EN=0;P1=dat;EN=1;delay_ms(1);EN=0;}void canshu(){write_cmd(0x38);delay_ms(1);write_cmd(0x01);delay_ms(1);write_cmd(0x06);delay_ms(1);write_cmd(0x0c);delay_ms(1);}/*void xianshi(uchar x,uchar y,uchar *str){uint i=0;if(y==0)write_cmd(0x80|x);if(y==1)write_cmd(0xc0|x);for(i=0;i<16;i++){write_data(str[i]);if(p=='\0')break;}} */void aaa() interrupt 1{TH0=(65535-50000)/256;TL0=(65535-50000)%256;if(++kk==18){miao++;if(miao==10){if(miao1++==5){if(fen++==10){if(fen1++==5){if(shi++==10){if(shi1++==1){shi1=0;shi=0;}shi=0;}fen1=0;}fen=0;}miao1=0;}miao=0;}kk=0;}}void main(){canshu();//xianshi(0,0,p);//xianshi(0,1,p+16);EA=1;ET0=1;TMOD=0x01;TH0=(65535-50000)/256;//如果不准可对其进行修改,比如4000可能更准确TL0=(65535-50000)%256;TR0=1;while(1){write_cmd(0x80|1);write_data(dis2[shi]);write_cmd(0x80|2);write_data(dis2[shi1]);write_cmd(0x80|3);write_data(p[0]);write_cmd(0x80|4);write_data(dis2[fen1]);write_cmd(0x80|5);write_data(dis2[fen]);write_cmd(0x80|6);write_data(p[0]);write_cmd(0x80|7);write_data(dis2[miao]);write_cmd(0x80|8);write_data(dis2[miao1]);}}。
1602LCD的指令说明及时序
1602LCD的指令说明及时序
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
指令1:清显示,指令码01H,光标复位到地址00H位置
指令2:光标复位,光标返回到地址00H
指令3:光标和显示模式设置
I/D:光标移动方向,高电平右移,低电平左移
S:屏幕上所有文字是否左移或者右移,高电平表示有效,低电平则无效。
时序如表所示
指令4:显示开关控制
D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示
C:控制光标的开与关,高电平表示有光标,低电平表示无光标
B:控制光标是否闪烁,高电平闪烁,低电平不闪烁
指令5:光标或显示移位
S/C:高电平时移动显示的文字,低电平时移动光标
指令6:功能设置命令
DL:高电平时为位总线,低电平时为8位总线;N:低电平时为单行显示,高电平时双行显示;F:低电平时显示5X7的点阵字符,高电平时显示5X10的点阵字符
指令7:字符发生器RAM地址设置
指令8:DDRAM地址设置
指令9:读忙信号和光标地址
BF:忙标志位,高电平表示忙,此时模块不能接收命令或者数据低电平表示不忙
指令10:写数据
指令11:读数据。
1602液晶显示计算器电路图及程序
#include <>#include <>unsigned char code Error[]={"error"};unsigned char code Systemerror[]={"system error"};unsigned char code Lcd[]={"lcd calculate"};char str[16];sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit BF=P0^7;/***********************函数功能:延时1ms***********************/void delay1ms(){unsigned char i,j;for (i=0;i<10;i++)for (j=0;j<33;j++);}/************************函数功能:延时n毫秒入口参数:n************************/void delaynms(unsigned char n){unsigned char i;for (i=0;i<n;i++)delay1ms();}/************************************函数功能:判断液晶模块的忙碌状态返回值:result。
result=1,忙碌;result=0,不忙。
************************************/bit BusyTest(void){bit result;RS=0; 0a0c0f4a4c4f0c0f0f0f0f0f&&(num!='=')) {if(flag==1){a=a*10+num-48;}else{b=num-48+b*10;}}if(num==0){i=0;flag=1;a=0;b=0;WriteInstruction(0x01);}if((num=='+')||(num=='-')||(num=='*')||(num=='/')){flag=0;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/': {if(b!=0){ a=a/b;break; }else{WriteInstruction(0x01);flag=1;WriteAddress(0,1);display_error();delaynms(40);WriteInstruction(0x01);break;}}default:break;}sign=num;b=0;}if(num=='='){flag=1;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/':a=a/b;break;default:break;}temp[i]=num;WriteAddress(0,i);WriteData(num);for(s=0;s<16;s++)temp[s]=0;s=0;//WriteAddress(1,8);//WriteData(a+48);x=itoa(a); //函数转换WriteAddress(1,1);while(s<=x){WriteData(str[s]);s++;delaynms(100);}sign=0;a=b=0;j=0;for(s=0;s<16;s++)str[s]=0;s=0;fgh=1;i=0;}if(i<16){if(num!='='){if((i==1)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符{temp[0]=num; //如果是1-9数字,说明0没有用,则直接替换第一位0WriteAddress(0,0);//输出数据WriteData(num);}else{temp[i]=num;WriteAddress(0,i);//输出数据WriteData(num);i++; //输入数值累加}}}else{i=0;WriteInstruction(0x01);}}}}。
浙江科技学院1602液晶显示计算器
浙江科技学院1602液晶显示计算器摘要本设计由51单片机作为核心,4*4矩阵键盘作为输入,利用51单片机控制LCD1602,实现加减乘除运算。
一、外观介绍:清0 = +零1 2 3 -4 5 6 *7 8 9 /二、电路仿真:P0.0~P0.7引脚接lcd的D0-D7,P3口接矩阵键盘。
单片机的P2.7、P2.5、P2.6脚分别接到LCD的RS、R/W、E管。
三、显示电路,LCD1602A的引脚详细介绍:采用LCD1602A来显示,要求能显示两行。
它的D—7D引脚分别接到单片机的P0.0~P0.7引脚;RS、R/W、E管脚分别接到单片机的P2.4、P2.0、P2.3 。
具体连接见后面的电路图。
以下是1602的16进制ASCII码表三、矩阵键盘扫描电路P3口的P3.0,P3.1,P3.2和P3.3四根线作为按键的行输出线,用P3.4,P3.5,P3.6和P3.7作为按键的列输入线。
依次给某一行低电平,再判断哪一列是低电平。
于是就判断出哪行和哪列导通。
对于不同的组合可以确定所有按键位置,将位置赋值到一个变量中,以供使用。
具体来说:假如按下的是数字5键(编号6——位于第二行第二列),首先置第一行为低电平其他7位为高电平P0=0xfe,再检测高四位的电平(P0=P&0xf0 ),因为列没有一条与第一行相导通,所以P0的高位还是高电平的。
然后再换第二行P0=0xfd,同理检测高四位(P0=P&0xf0 )得出P0=0xd0,则5键所在位置为第二行第二列,然后num赋值为6。
四、程序分析可知共分为七个模块:键盘扫描部分,定义各个位置上的键值部分,延迟部分,存贮部分,液晶显示部分,运算部分,动态显示部分。
主程序流程图如下:五、程序#include<reg51.h>#define uint unsigned int#define uchar unsigned char sbit lcden=P2^7;sbit rs=P2^6;sbit rw=P2^5;sbit busy=P0^7; 判断是否有键按下否有按下数字键则将键值存入指定内存单元,并在液晶上显示出来,若是第二次则须完成四则运算并将结果保存在指定内存单元按下加减乘除四个功能按键时,将数码管显示清零,以等待下一个数字键值输入若按下的是等号键时,则要将运算结果在数码管上显示出来液晶显示电路,将各种输入值和运算结果显示出来键盘扫描char i,j,temp,num,num_1;long a,b,c;float a_c,b_c;uchar flag,fuhao;uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0x2b-0x30}; void delay(uchar z){uchar y;for(z;z>0;z--)for(y=0;y<110;y++);}void check(){do{P0=0xFF;rs=0;rw=1;lcden=0;delay(1);lcden=1;}while(busy==1);}void write_com(uchar com){P0=com;rs=0;rw=0;lcden=0;check();lcden=1;}void write_date(uchar date){P0=date;rs=1;lcden=0;check();lcden=1;}void init(){num=-1;lcden=1;write_com(0x01);write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x80);write_com(0x01);num_1=0;i=0;j=0;a=0;b=0;c=0;flag=0;fuhao=0;}void keyscan(){P3=0xfe;if(P3!=0xfe){delay(20);if(P3!=0xfe){temp=P3&0xf0;switch(temp){case 0xe0:num=0;break;case 0xd0:num=1;break;case 0xb0:num=2;break;case 0x70:num=3;break;}while(P3!=0xfe);if(num==0||num==1||num==2){if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}else{b=b*10+table[num];}}else{flag=1;fuhao=4;}i=table1[num];write_date(0x30+i);}P3=0xfd;if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;switch(temp){case 0xe0:num=4;break;case 0xd0:num=5;break;case 0xb0:num=6;break;case 0x70:num=7;break;}while(P3!=0xfd);if(num==4||num==5||num==6&&num!=7) {if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}else{b=b*10+table[num];}}else{flag=1;fuhao=3;}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;switch(temp){case 0xe0:num=8;break;case 0xd0:num=9;break;case 0xb0:num=10;break;case 0x70:num=11;break;}while(P3!=0xfb);if(num==8||num==9||num==10){if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}else{b=b*10+table[num];}}else if(num==11){flag=1;fuhao=2;}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;break;case 0xb0:num=14;break;case 0x70:num=15;break;}while(P3!=0xf7);switch(num){case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;} break;case 13:{if(flag==0){a=a*10;write_date(0x30);P1=0;}else if(flag==1){b=b*10;write_date(0x30);}}break;case 14:{j=1;if(fuhao==1){write_com(0x80+0x4f);write_com(0x04);c=a+b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x80+0x4f);write_com(0x04);if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x80+0x4f);write_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x80+0x4f);write_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;i++;if(i==3)write_date(0x2e);}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;} break;}}}main(){init();while(1){keyscan(); }}。
(完整word版)1602液晶时钟程序(51单片机)
1602液晶时钟程序程序按郭天袢《新概念51单片机C语言教程》第十四章扩展显示年、月、日、星期调节功能。
1)时间显示在1602液晶上,并按秒实时更新2)能调节按键调整时、分、秒、年、月、日和星期3)每次按键按下时有短滴声响声4)断电后下次上电会接着上次断电前的时间数继续运行原理图如图//原代码如下:#include<reg52.h>//#include"24c02.h"#define uchar unsigned char#define uint unsigned int#include"24c02.h"sbit dula=P2^6;sbit wela=P2^7;sbit LCDEN=P3^4;sbit LCDRS=P3^5;sbit s1=P3^0;//定义按键--功能键sbit s2=P3^1;//定义按键--增大键sbit s3=P3^2;//定义按键--减小键sbit rd=P3^7;//按键公共脚sbit beep=P2^3;//定义蜂鸣器脚uchar count,s1_num;//定义中断次数计数变量功能键按键次数变量uchar week,day,month,year;//定义变量:星期日月年char miao,shi,fen;//定义秒分时变量uchar code table[]=" 2012-11-28 Wed";//void write_week(char we);//显示星期几函数void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di()//蜂鸣器响一声函数{beep=0;delay(100);beep=1;}void write_com(uchar com) //液晶写命令函数{LCDRS=0;P0=com;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_date(uchar date) //液晶写数据函数{LCDRS=1;P0=date;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_week(char we) //写星期几显示函数{write_com(0x80+12);switch(we){case 1: write_date('M');delay(5); //星期一Mondaywrite_date('o');delay(5);write_date('n');delay(5);break;case 2: write_date('T');delay(5); //星期二Tuesdaywrite_date('u');delay(5);write_date('e');delay(5);break;case 3: write_date('W');delay(5); //Wednesdaywrite_date('e');delay(5);write_date('d');delay(5);break;case 4: write_date('T');delay(5); //Thursdaywrite_date('h');delay(5);write_date('u');delay(5);break;case 5: write_date('F');delay(5); //星期五Fridaywrite_date('r');delay(5);write_date('i');delay(5);break;case 6: write_date('S');delay(5); //星期六Saturdaywrite_date('a');delay(5);write_date('t');delay(5);break;case 7: write_date('S');delay(5); //星期日Sundaywrite_date('u');delay(5);write_date('n');delay(5);break;default: break;}}void write_sfm(uchar add,uchar date) //写时分秒函数{uchar shiwei,gewei;shiwei=date/10;gewei=date%10;write_com(0x80+0x40+add);//设置显示位置write_date(0x30+shiwei);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+gewei);}void write_year_month_day(uchar add,uchar day) //写年月日数函数{uchar shi,ge;shi=day/10;ge=day%10;write_com(0x80+add);//设置显示位置write_date(0x30+shi);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+ge);}void init() //初始化函数{uchar num;rd=0;beep=1;dula=0;wela=0;LCDEN=0;//将使能端置0以完成高脉冲fen=0;miao=0;shi=0;count=0;//计数初始为0init_24c02();write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针自动加1write_com(0x01);//显示清0,数据指针清0write_com(0x80); //设置显示初始坐标for(num=0;num<15;num++) //显示年月日{write_date(table[num]);delay(5);}write_com(0x80+0x40+6); //写出时间显示部分的两个冒号write_date(0x3a);delay(5);write_com(0x80+0x40+9);write_date(0x3a);delay(5);miao=read_add(1);//开机上电时读取24c02 IIC的数据赋值fen=read_add(2);shi=read_add(3);week=read_add(4);//读取星期几day=read_add(5);//读取多少日month=read_add(6);year=read_add(7);write_sfm(10,miao);//分别送去液晶显示write_sfm(7,fen);write_sfm(4,shi);write_week(week);//开机从24c02读取的星期几数从新写入液晶显示出来write_year_month_day(9,day);write_year_month_day(6,month);write_year_month_day(3,year);//定时器初始化TMOD=0x01; //设置定时器0工作模式1TH0=(65536-45876)/256; //定时器装初值TL0=(65536-45876)%256;EA=1; //开总中断ET0=1; //打定时器0中断TR0=1; //启动定时器0}void keyscan() //按键扫描函数{if(s1==0){delay(5);if(s1==0){s1_num++; //功能键按下次数记录while(!s1); //按键释放确认di();if(s1_num==1) //只按一次按键时TR0=0; //关闭定时器write_com(0x80+0x40+11);write_com(0x0f); //打开光标闪烁}if(s1_num==2) //第二次按下光标闪烁定位到分钟位置{write_com(0x80+0x40+8);}if(s1_num==3) //第三次按下光标闪烁定位到小时位置{write_com(0x80+0x40+5);}/**************************************if(s1_num==4) //第三四次按下退出{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}***************************************/if(s1_num==4) //光标处星期{write_com(0x80+14);}if(s1_num==5) //光标处日{write_com(0x80+10);}if(s1_num==6) //光标处月{write_com(0x80+7);}if(s1_num==7) //光标处年{write_com(0x80+4);}if(s1_num==8) //当第八次按功能键时退出光标闪烁及开始计时{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}}if(s1_num!=0){if(s2==0)//增加键确认按下{delay(5);if(s2==0){while(!s2);di();if(s1_num==1){miao++;if(miao==60)miao=0;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen++;if(fen==60)fen=0;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi++;if(shi==24)shi=0;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4)//按四次功能键后光标至星期几处,可调节星期几{week++;if(week==8)week=1;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5) //光标至显示日处,可调节多少日{day++;if(day==32)day=1;write_year_month_day(9,day);write_com(0x80+10);write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month++;if(month==13)month=1;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year++;if(year==100)year=00;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}if(s3==0) //确认减小键被按下{delay(5);//按键防抖延时if(s3==0) //确认减小键被按下{while(!s3);di();if(s1_num==1){miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4){week--;if(week==0)week=7;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5)//光标至显示日处,可调节多少日{day--;if(day==0)day=31;write_year_month_day(9,day);write_com(0x80+10);//光标位置移回在显示多少日的个位write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month--;if(month==0)month=12;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year--;if(year==-1)year=99;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}}}void main(){init();//首先初始化各数据while(1){keyscan(); //按键扫描函数}}void timer0() interrupt 1 //定时器0中断服务程序{TH0=(65536-45876)/256;TL0=(65536-45876)%256;count++; //中断次数累加,计数if(count==20) //50微秒乘以20等于1秒{count=0;miao++;if(miao==60) //秒加到60则进位分钟{miao=0; //同时秒数清0fen++;if(fen==60) //分钟加到60则进位小时{fen=0; //同时分钟清0shi++;if(shi==24) //小时加到24则小时清0{shi=0;}write_sfm(4,shi);//小时若变化则重新写入write_add(3,shi);//写入24c02存储起来,小时数的写入地址为3 }write_sfm(7,fen);//分钟若变化则重新写入write_add(2,fen);}write_sfm(10,miao);//秒若变化则重新写入write_add(1,miao);}}/***********************************24C02.h头文件,将以下源代码需存为与保存的C代码根目录下。
1602液晶电子时钟程序51单片机
1602液晶电子时钟程序[日期:2009-06-11 ] [来源:net 作者:佚名] [字体:大中小] (投递新闻)连线图:; DB0---DPROT.0 DB4---DPROT.4 RS-------------P1.2; DB1---DPROT.1 DB5---DPROT.5 RW-------------P1.3; DB2---DPROT.2 DB6---DPROT.6 E--------------P1.4; DB3---DPROT.3 DB7---DPROT.7 VLCD接10K可调电阻到GND*#include "reg52.h"//头文件#include "intrins.h"#define uchar unsigned char//宏定义#define uint unsigned int//宏定义sbit RS=P1^2;//定义I/O的硬件接口sbit RW=P1^3;sbit E=P1^4;sbit led_1=P1^7;//;;;LED秒闪烁uchar Hours=0;//定义小时uchar Minutes=0;//定义分钟uchar Seconds=0;//定义秒bit Seconds_Scintillation=1;//定义秒闪烁标志#define DPDR P0//并行数据接口定义uchar code DispTab_1[]={'0','1','2','3','4','5','6','7','8','9'};//1602:0-9 数字uchar code DispTab_2[]={'A','B','C','D','E','a','b','c','d','e'};//1602:A-e 字母uchar DispBuf[8]; //8字节的显示缓冲区char char_char_1[]={" "};//定义字符串char char_char_2[]={" "};//定义空字符串void delay(uint z)//1ms延时{uchar x,x1;for(;z>0;z--){for(x=0;x<114;x++){for(x1=0;x1<1;x1++);}}}void Timer0() interrupt 1{static uchar Count_50;//uchar temp;TH0=0xb7;TL0=0xff;//定时时间为20ms,每20ms中断一次Count_50++;if(Count_50==50)//20ms*50=1秒{ Seconds_Scintillation=~Seconds_Scintillation; led_1=~led_1;Count_50=0;Seconds++;if(Seconds==60){Seconds=0;Minutes++;if(Minutes==60){Minutes=0;Hours++;if(Hours==24){Hours=0;}}}}if(Seconds_Scintillation==1)//秒闪烁标志判断DispBuf[6]=':';elseDispBuf[6]=' ';DispBuf[0]=Hours/10;//转换成10进制显示DispBuf[1]=Hours%10;DispBuf[2]=Minutes/10;DispBuf[3]=Minutes%10;DispBuf[4]=Seconds/10;DispBuf[5]=Seconds%10;temp=DispBuf[0];DispBuf[0]=DispTab_1[temp];//查表取字符temp=DispBuf[1];DispBuf[1]=DispTab_1[temp];temp=DispBuf[2];DispBuf[2]=DispTab_1[temp];temp=DispBuf[3];DispBuf[3]=DispTab_1[temp];temp=DispBuf[4];DispBuf[4]=DispTab_1[temp];temp=DispBuf[5];DispBuf[5]=DispTab_1[temp];}void write_Directive(uchar a)//写指令{RS=0;RW=0;delay(1);E=0;DPDR=a;delay(1);E=1;delay(1);E=0;delay(1);}void write_Data(uchar a)//写数据{RS=1;RW=0;delay(1);E=0;DPDR=a;delay(1);E=1;delay(1);E=0;delay(1);}void init()//初始化{ uchar i;TMOD=0x01;TH0=0xb7;TL0=0xff;//定时时间为20ms,每20ms中断一次ET0=1; //开T0中断EA=1; //开总中断TR0=1; //T0开始运行DispBuf[6]=':';delay(15);write_Directive(0x38);delay(5);write_Directive(0x38);delay(5);write_Directive(0x38);write_Directive(0x01);write_Directive(0x02);//初始化后数据地址为0x80;即第一行,第一个位置write_Directive(0x0c);//不显示光标write_Directive(0x80+0x40);//第二行第一位地址for(i=0;i<16;i++){write_Data(char_char_1[i]);//显示字符串" "}}void write_Data_String()//显示时间函数{write_Directive(0x80+0x04);//第一行,第五个位置地址write_Data(DispBuf[0]);//第一行,第五个位置write_Data(DispBuf[1]);//第一行,第六个位置write_Data(DispBuf[6]);//第一行,第七个位置write_Data(DispBuf[2]);//第一行,第八个位置write_Data(DispBuf[3]);//第一行,第九个位置write_Data(DispBuf[6]);//第一行,第十个位置write_Data(DispBuf[4]);//第一行,第十一个位置write_Data(DispBuf[5]);//第一行,第十二个位置}void main(){init();while(1){write_Data_String();//调用写连续的16 个字符,1表示第一行;2表示第二行delay(100);//延时100ms,扫描一次}}液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/****************************************************************/
/****************************************************************/
void init()
{ unsigned int i;
write_com(0x38); //16*2显示,5*7点阵,8位数据
char b[]=" 00:00:00";
/****************************************************************/
/* */
void write_sfm(unsigned char add,unsigned char date)
{ unsigned char shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
result = (bit)(P1&0x80);
LCD_EN = 0;
return result;
}
/****************************************************************/
/* */
/* 延时子程序 */
/* */
/****************************************************************/
void delay(int ms)
{
int i;
while(ms--)
{
for(i = 0; i< 250; i++)
#include<reg52.h>
#include <intrins.h>
sbit LCD_RS = P2^4;
sbit LCD_RW = P2^3;
sbit LCD_EN = P2^2;
unsigned char tt,miao,fen,shi;
unsigned char a[]="QQ:287712876 ";
/* */
/****************************************************************/
write_com(0x06); //移动光标
delay(5);
write_com(0x01); //清除LCD的显示内容
delay(5);
write_com(0x80);
for( i=0;i<16 ;i++)
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* LCD初始化设定 */
/* */
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
delay1( unsigned int z)
{ unsigned char x,y;
for( x=z;x>0;x--)
for( y=110;y>0;y--);
void write_com(unsigned char com)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
/* */
/****************************************************************/
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
P1 = com;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
write_date(0x30+ge);
}
/****************************************************************/
/* */
/* */
/****************************************************************/
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
{ write_date( a[i]);
delay1(5);
}
write_com(0x80+0x40);
for(i=0;i<12;i++)
{ write_date(b[i]);
delay1(5);
}
TMOD=0X01;
void write_date (unsigned char date)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P1 = date;
delay(5);
write_com(0x38);
delay(5);
write_com(0x38);
delay(5);
write_com(0x0c); //显示开,关光标
delay(5);
/********************AT89C52实验开发板例程************************
1602液晶显示+计数器倒计时 晶振:11.0592MHZ
*****************************************************************/
}
/****************************************************************/
/* */
bit lcd_busy()
{
bit
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();