用独立按键控制1602逐个显示
单片机设计按键顺序控制加减计数(1602液晶显示)程序
![单片机设计按键顺序控制加减计数(1602液晶显示)程序](https://img.taocdn.com/s3/m/0abaa45cf56527d3240c844769eae009581ba2d1.png)
单片机设计按键顺序控制加减计数(1602液晶显示)程序#include#include#define uchar unsigned char#define uint unsigned int#define LCD_IO P2sbit KK1 = P3^2; //按键输入;sbit KK2 = P3^3; //按键输入;sbit LCD_RS = P3^5;sbit LCD_RW = P3^6;sbit LCD_EN = P3^7;uchar code LCD_line1[] = " The Counter";int idata mydata=0;/************************************************************** * 名称: Delay_1ms()* 功能: 延时子程序,延时时间为1ms * x* 输入: x (延时一毫秒的个数)* 输出: 无*************************************************************** / void Delay_1ms(uint x){uchar i, j;for(i = 0; i < x; i++) for(j = 0; j <= 148; j++);}/************************************************************** * 名称: lcd_bz( )* 功能: 测试忙碌子程序* 输入: 无* 输出: result/ bit lcd_bz(){bit result;LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();_nop_();_nop_();result=(bit)(P3&0x80);LCD_EN = 0;return result;}/************************************************************** * 名称: W_LCD_Com( )* 功能: 写指令子程序* 输入: com* 输出: 无*************************************************************** /void W_LCD_Com(uchar com){while(lcd_bz());LCD_RS = 0; LCD_RW=0; LCD_EN = 0; // LCD_RS和R/W同时为低电平时,可以写入指令LCD_IO = com; Delay_1ms(5); //下面用EN输入一个高脉冲LCD_EN = 1; Delay_1ms(5); LCD_EN = 0;}* 名称: W_LCD_Dat( )* 功能: 写数据子程序* 输入: dat* 输出: 无*************************************************************** /void W_LCD_Dat(uchar dat){while(lcd_bz());LCD_RS = 1; LCD_RW=0;LCD_EN = 0; // LCD_RS为高,LCD_RW为低时,可以写入数据LCD_IO = dat; Delay_1ms(5); //下面用EN输入一个高脉冲LCD_EN = 1; Delay_1ms(5); LCD_EN = 0;}/************************************************************** * 名称: W_LCD_STR( )* 功能: 写字符串子程序* 输入: *s* 输出: 无*************************************************************** /void W_LCD_STR(uchar *s){while(*s > 0) {W_LCD_Dat(*s); s++;}}/************************************************************** * 名称: LCD_cursor( )* 功能: 设置光标位置子程序* 输入: pos* 输出: 无*************************************************************** /void LCD_cursor(uchar pos) //LCD光标定位到处{W_LCD_Com(pos+0x80); //第一行地址是0x80}/************************************************************** * 名称: initial( )* 功能: 初始化子程序* 输入: 无* 输出: 无* 指令:#define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一#define LCD_DISPLAY_ON 0x0C //显示开#define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示*************************************************************** /void initial(){W_LCD_Com(0x06|0x04);W_LCD_Com(0x0c|0x08);W_LCD_Com(0x38);W_LCD_STR(LCD_line1);}/************************************************************** * 名称: Main()* 功能: 主函数*************************************************************** /void main(){bit flag;uchar temp;uchar pos;Delay_1ms(10) ;initial();while(1){pos=0x4f;if(mydata>255)mydata=0;else if(mydata<0)mydata=255;if(mydata>127) //把mydata当做-128~127的有符号数来显示{flag=1;temp=256-mydata;}else {temp=mydata;flag=0;}LCD_cursor(pos);W_LCD_Dat((temp%10)+'0');pos--;//光标左移(其实光标不显示,只是为了输出高位)Delay_1ms(10);if(temp/100 || temp/10){LCD_cursor(pos);W_LCD_Dat((temp/10)%10+'0');pos--;}Delay_1ms(10);if(temp/100){LCD_cursor(pos);W_LCD_Dat((temp/100)%10+'0'); pos--;}if(flag){LCD_cursor(pos);W_LCD_Dat('-');//负号}else{ LCD_cursor(pos);W_LCD_Dat(' ');//清除负号(空格代替)}if(!KK1){while(KK2);while(!KK2);mydata++;}else if(!KK2){while(KK1);while(!KK1);mydata--;}}}。
51单片机 1602液晶显示 TLC5615独立按键调频调幅
![51单片机 1602液晶显示 TLC5615独立按键调频调幅](https://img.taocdn.com/s3/m/110372eff8c75fbfc77db225.png)
#include <reg52.h>#include <math.h>#define uint unsigned int#define uchar unsigned char#define PI 3.14sbit CS=P2^5; //定义片选信号IO口sbit SCLK=P2^4; //定义时钟信号IO口sbit DIN=P2^3; //定义数据输入IO口uint kk=1;sbit Aup=P1^4; //频率+sbit Adowm=P1^5;//频率-sbit Fup=P1^6; //幅度+sbit Fdowm=P1^7;//幅度-uint DataNum=128;//定义一个周期的点数uint AmNum=256; //定义一个周期的点数/*--------延时子程序----------*/void delay(unsigned char pp) //延迟时间等于k*8ms{while(pp--){unsigned char j;// P2=P2&0XF8;for(j = 0;j<123;j++); //j进行的内部循环,1次延迟8us,延迟1ms}}/*----------DA转换----------*/void DAConvert(uint Data){uchar i;Data<<=6;CS=0;SCLK=0;for (i=0;i<12;i++){DIN=(bit)(Data&0x8000);SCLK=1;Data<<=1;SCLK=0;}CS=1;SCLK=0;for (i=0;i<12;i++);}/*正弦波参数换算程序*/uint GetSinData(uchar x){uint SinData;SinData=((sin(2*PI*x/DataNum)+1)/2.0)*AmNum;return SinData;}/*----------主程序----------*/main(){uint i;while(1){for(i=0;i<DataNum;i++)DAConvert(GetSinData(i));//输出正弦波P1 = 0xFF; // 发全0行扫描码,列线输入if((P1&0xFF) != 0xFF) // 若有键按下{delay(1);// 延时去抖动if((P1&0xFF) != 0xFF)switch(AmNum){case 512: AmNum=256;break;case 32: AmNum=256; break;}switch(DataNum){case 256: DataNum=128;break;case 16: DataNum=128; break;}switch(P1){case 0x7f: AmNum=AmNum+32;break;//幅度+case 0xbf: AmNum=AmNum-32; break;//幅度-case 0xdf: DataNum=DataNum+16; break;//频率-case 0xef: DataNum=DataNum-16; break;//频率+}}}}。
单片机用C51实现时间、星期、年月、温度在DS1602上显示的多功能数字钟
![单片机用C51实现时间、星期、年月、温度在DS1602上显示的多功能数字钟](https://img.taocdn.com/s3/m/245abe160b4e767f5acfce1d.png)
//***************************************************************************** //******用DS1602实现可调日期,时间,星期及温度实时监测的实用数字钟功能******* //*****************创建日期:2010-1-7***********************//功能介绍:用3*3按键在DS1602上显示第一排显示"2010-01-05 MON"第二排显示"23:59:00"//*******************功能介绍**************************************//********* K6:adjtime K3:hour K2:minute K1:OK*******************//********* K3:adjalarm K3:hh K1:OK**********************//********* K2:lookalarm K1:OK **********************//********* K1:alarm ON/OFF ***********************//********* K5:adjdate (K9:month)K8:day (K7:week)K4:OK*********//***********************************************************************#include "main.h"void lcd_data(unsigned char dat);//DS1602数据写入unsigned char kbscan();//按键扫描void ds1602();//DS1602初始化void lcd_com(unsigned char com);//DS1602命令写入void timer0();//用于延时的定时中断初始2mSvoid disp();//主程序的显示调用void display();//正常的显示void display_alarm();//查看闹铃void alarm();//闹铃void process();//按键的处理unsigned char hands();//与18B20通信握手void write_temp_date(unsigned char dat);//写温度数据18B20unsigned char read_temp_date();//读温度数据18B20void tmpdelay(unsigned char tmp);//ds18b20对时序要求严格unsigned char result();//计算月份的天数//*******************************//DS1602命令的写入//*******************************void lcd_com(unsigned char com){rs=0;rw=0;P0=com;dema=1;while(dema!=0);en=1;dema=1;while(dema!=0);en=0;}//*********************//DS1602数据的写入//*********************void lcd_data(unsigned char dat){rs=1;rw=0;P0=dat;dema=1;while(dema!=0);en=1;dema=1;while(dema!=0);en=0;}//***************************//3*3按键的扫描//***************************unsigned char kbscan(){unsigned char sccode,recode,tenp;P1=0XF8;tenp=P1;if(tenp!=0xf8){demb=3;while(demb!=0);if(tenp==P1){sccode=0xfe;while((sccode&0xf7)!=0){P1=sccode;if((P1&0xf8)!=0xf8){recode=P1&0Xf8;sccode=sccode&0xc7;return(recode|sccode);}elsesccode=sccode<<1|0x01;}}}return(0);}//**************************//*********每月的天数计算***//**************************unsigned char result(){switch(month){case 1:return 31;break;case 3:return 31;break;case 5:return 31;break;case 7:return 31;break;case 8:return 31;break;case 10:return 31;break;case 12:return 31;break;case 4:return 30;break;case 6:return 30;break;case 9:return 30;break;case 11:return 30;break;case 2:if(year%4==0){return 29;//闰年29天}else{return 28;//平年28天}}}//**************************//*********DS1602的初始化***//**************************void ds1602(){lcd_com(0x38);//16*2显示5*7矩阵dema=1;while(dema!=0);lcd_com(0x0c);//显示开,无光标无闪烁dema=1;while(dema!=0);lcd_com(0x06);//指针+1,整屏不动dema=1;while(dema!=0);lcd_com(0x01);//清屏}//*******************************//定时中断延时的初始化以及中断***//*******************************void timer0(){TMOD=0X01;TH0=0Xf8;TL0=0X30; //2mS初值12M晶振TR0=1;ET0=1;EA=1;}TIME0() interrupt 1{TR0=0;TH0=0Xf8;TL0=0X30; //2mS初值TR0=1;count++;if(count>=500)//1s{count=0;second++;if(second>=60)//1m{second=0;minute++;if(minute>=60)//1h{minute=0;hour++;if(hour>=24)//1day{hour=0;flag_week++;//星期调整if(flag_week>8){flag_week=1;}day++;if(day>(days=result()))//1month{day=1;month++;if(month>12)//1year{month=1;year++;if(year>100){year=0;}}}}}}}if(dema)dema--;//写命令的延时if(demb)demb--;//按键的延时//************闹铃**********if(demc){demc--;}if(demd){demd--;}flag++;if(flag>=200){flag=0;temp=1;deme++;if(deme>=2){demc=0;temp=0;}}}//**************************//正常日期时间显示//**************************void display(){a=hour/10;b=hour%10;c=minute/10;d=minute%10;e=second/10;f=second%10;m3=year/10;m4=year%10;m6=month/10;m7=month%10;m9=day/10;m10=day%10;//*****第一排显示**********lcd_com(0x81);//第一排从第2个位置开始显示lcd_data(0x32);lcd_com(0x82);lcd_data(0x30);lcd_com(0x83);lcd_data(0x30+m3);lcd_com(0x84);lcd_data(0x30+m4);lcd_com(0x85);lcd_data(0x2d);//"-"lcd_com(0x86);lcd_data(0x30+m6);lcd_com(0x87);lcd_data(0x30+m7);lcd_com(0x88);lcd_data(0x2d);//"-"lcd_com(0x89);lcd_data(0x30+m9);lcd_com(0x8a);lcd_data(0x30+m10);if(flag_week==1)//周1{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week1[n]);}}else if(flag_week==2)//周2 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week2[n]);}}else if(flag_week==3)//周3 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week3[n]);}}else if(flag_week==4)//周4 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week4[n]);}}else if(flag_week==5)//周5 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week5[n]);}}else if(flag_week==6)//周6 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week6[n]);}}else if(flag_week==7)//周7{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week7[n]);}}//*****第二排显示***********lcd_com(0xc1);//第二排从第3个位置开始显示lcd_data(0x30+a);lcd_com(0xc2);lcd_data(0x30+b);lcd_com(0xc3);lcd_data(0x3a);//":"lcd_com(0xc4);lcd_data(0x30+c);lcd_com(0xc5);lcd_data(0x30+d);lcd_com(0xc6);lcd_data(0x3a);//":"lcd_com(0xc7);lcd_data(0x30+e);lcd_com(0xc8);lcd_data(0x30+f);lcd_com(0xca);lcd_data(0x47);//"G"lcd_com(0xcb);lcd_data(0x47);//"G"lcd_com(0xcd);all_date=all_date%100;lcd_data(match[all_date/10]);//十位lcd_com(0xce);lcd_data(match[all_date%10]);//个位lcd_com(0xcf);lcd_data('C');//"temperapure" "C"}//********************************************** //*************************看闹钟*************** void display_alarm(){a=hh/10;b=hh%10;c=min/10;d=min%10;e=sec/10;f=sec%10;m3=year/10;m4=year%10;m6=month/10;m7=month%10;m9=day/10;m10=day%10;//*****第一排显示**********lcd_com(0x81);//第一排从第2个位置开始显示lcd_data(0x32);lcd_com(0x82);lcd_data(0x30);lcd_com(0x83);lcd_data(0x30+m3);lcd_com(0x84);lcd_data(0x30+m4);lcd_com(0x85);lcd_data(0x2d);//"-"lcd_com(0x86);lcd_data(0x30+m6);lcd_com(0x87);lcd_data(0x30+m7);lcd_com(0x88);lcd_data(0x2d);//"-"lcd_com(0x89);lcd_data(0x30+m9);lcd_com(0x8a);lcd_data(0x30+m10);if(flag_week==1)//周1{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week1[n]);}}else if(flag_week==2)//周2{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week2[n]);}}else if(flag_week==3)//周3 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week3[n]);}}else if(flag_week==4)//周4 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week4[n]);}}else if(flag_week==5)//周5 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week5[n]);}}else if(flag_week==6)//周6 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week6[n]);}}else if(flag_week==7)//周7 {lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week7[n]);}}//****第二排**************lcd_com(0xc1);//第二排从第3个位置开始显示lcd_data(0x30+a);lcd_com(0xc2);lcd_data(0x30+b);lcd_com(0xc3);lcd_data(0x3a);//":"lcd_com(0xc4);lcd_data(0x30+c);lcd_com(0xc5);lcd_data(0x30+d);lcd_com(0xc6);lcd_data(0x3a);//":"lcd_com(0xc7);lcd_data(0x30+e);lcd_com(0xc8);lcd_data(0x30+f);lcd_com(0xcd);all_date=all_date%100;lcd_data(match[all_date/10]);//十位lcd_com(0xce);lcd_data(match[all_date%10]);//个位lcd_com(0xcf);lcd_data('C');//"temperapure" "C"}//**********************//闹钟开的显示**********//**********************void display_onalarm(){a=hour/10;b=hour%10;c=minute/10;d=minute%10;e=second/10;f=second%10;m3=year/10;m4=year%10;m6=month/10;m7=month%10;m9=day/10;m10=day%10;//*****第一排显示**********lcd_com(0x81);//第一排从第2个位置开始显示lcd_data(0x32);lcd_com(0x82);lcd_data(0x30);lcd_com(0x83);lcd_data(0x30+m3);lcd_com(0x84);lcd_data(0x30+m4);lcd_com(0x85);lcd_data(0x2d);//"-"lcd_com(0x86);lcd_data(0x30+m6);lcd_com(0x87);lcd_data(0x30+m7);lcd_com(0x88);lcd_data(0x2d);//"-"lcd_com(0x89);lcd_data(0x30+m9);lcd_com(0x8a);lcd_data(0x30+m10);if(flag_week==1)//周1{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week1[n]);}}else if(flag_week==2)//周2{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week2[n]);}}else if(flag_week==3)//周3{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week3[n]);}}else if(flag_week==4)//周4{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week4[n]);}}else if(flag_week==5)//周5{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week5[n]);}}else if(flag_week==6)//周6{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week6[n]);}}else if(flag_week==7)//周7{lcd_com(0x8c);for(n=0;n<3;n++){lcd_data(week7[n]);}}//****第二排**************lcd_com(0xc1);//第二排从第3个位置开始显示lcd_data(0x30+a);lcd_com(0xc2);lcd_data(0x30+b);lcd_com(0xc3);lcd_data(0x3a);//":"lcd_com(0xc4);lcd_data(0x30+c);lcd_com(0xc5);lcd_data(0x30+d);lcd_com(0xc6);lcd_data(0x3a);//":"lcd_com(0xc7);lcd_data(0x30+e);lcd_com(0xc8);lcd_data(0x30+f);lcd_com(0xca);lcd_data(0x4B);//"K"lcd_com(0xcb);lcd_data(0x4B);//"K"lcd_com(0xcd);all_date=all_date%100;lcd_data(match[all_date/10]);//十位lcd_com(0xce);lcd_data(match[all_date%10]);//个位lcd_com(0xcf);lcd_data('C');//"temperapure" "C" }//*****************************//*******按键的处理************//***************************** void process(){if(key!=0){if(key==K6){display();while((key=kbscan())!=K1){display();if((key=kbscan())==K3){hour++;if(hour>=24){hour=0;}}if((key=kbscan())==K2){minute++;if(minute>=60){minute=0;}}}}else if(key==K2)//看闹铃{while(((key=kbscan())!=K1)){display_alarm();}}else if(key==K3)//调闹铃{display_alarm();while((key=kbscan())!=K1){display_alarm();if((key=kbscan())==K3){hh++;if(hh>=24){hh=0;}}if((key=kbscan())==K2){min++;if(min>=60){min=0;}}}}else if(key==K1)//开/关闹钟{flag_alarm=~flag_alarm; }else if(key==K5)//调日期星期{display();while((key=kbscan())!=K4)//ok{display();// if((key=kbscan())==K9)//month // {// month++;// if(month>12)// {// month=1;// }// }if((key=kbscan())==K8)//day{day++;flag_week++;if(flag_week>7){flag_week=1;}if(day>(days=result())){day=1;month++;if(month>12){month=1;year++;if(year>100){year=0;}}}// if((key=kbscan())==K7)//week // {// flag_week++;// if(flag_week>8)// {// flag_week=1;// }// }}}}}}//*************************************//*****************闹铃****************//*************************************void alarm(){if(flag_offalarm==1){if(flag_alarm==1){if(temp){TR0=0;TH0=0Xf8;TL0=0X30;TR0=1; //重装初值2mSdemd=2;while(demd!=0);//P37=~P37;}else{TR0=0;TH0=0XF8;TL0=0X30;TR0=1; //重装初值demc=1;while(demc!=0);//P37=~P37;}}else{P37=1;flag_offalarm=0;}}elseif((flag_alarm==1)&&(minute==min)&&(hour==hh)) {flag_offalarm=1;if(temp){TR0=0;TH0=0Xf8;TL0=0X30;TR0=1; //重装初值2mSdemd=2;while(demd!=0);//P37=~P37;}else{TR0=0;TH0=0XF8;TL0=0X30;TR0=1; //重装初值demc=1;while(demc!=0);//P37=~P37;}}}//**********************************//***********DS18B20时序控制*********** //**********************************void tmpdelay(unsigned char tmp)//注意!!{while(tmp>0){tmp--;}}//*tmdelay(1) ;//16.28us//增加一个就加6.5us // tmdelay(2) ;//22.78us// tmdelay(3) ;//29.30us// tmdelay(4) ;//35.81us// tmdelay(70) ;//465.49// tmdelay(74) ;//491.54// tmdelay(80) ;//530.60// tmdelay(115) ;//150us *//*例如16.28+(?*6.5)=490*///********************************//**************************************//**********DS18B20读取温度***********//*************************************unsigned char read_temp_date()//读温度数据18B20{unsigned char i;unsigned int y=0;value=0;for(i=8;i>0;i--){value>>=1;DQ=0;// tmpdelay(1);//>15usy++;y++;y++;y++;//1-15usDQ=1;// tmpdelay(1);//读温度对时序要求严格不能用tmpdelay(1)代替y++;if(DQ==1){value=value|0x80;}else{}tmpdelay(16);//120US}return (value);}//**************************************//**********DS18B20写指令温度***********//*************************************void write_temp_date(unsigned char dat)//写温度指令18B20{unsigned char i;for(i=8;i>0;i--){DQ=0;tmpdelay(1);//>15usif((dat&0x01)==1){DQ=1;tmpdelay(16);//120us}else{DQ=0;tmpdelay(16);//120usDQ=1;tmpdelay(1);//>15us}dat=dat>>1;}DQ=1;tmpdelay(1);//>15us}//**************************************//**********DS18B20复位*****************//*************************************unsigned char hands()//握手复位{temp=0;// noanswer:do{DQ=0;tmpdelay(72);//490uSDQ=1;tmpdelay(11);/*>60uS 注意:此处把函数名改为hans()后,这里两处的tmpdelay()括号内最好改成74和12*/}while(DQ!=0);temp=1;tmpdelay(35);//>240usDQ=1;return(temp);//此处可以采用两种方式表达,1用直到...才;2用goto转向// if(DQ==1)// {// goto noanswer;// }// else if(DQ==0)// {// temp=1;// tmpdelay(40);//>250uS// DQ=1;// }// return(temp);}void disp(){if(flag_alarm){display_onalarm();}else{display();}}//***********************//*******主程序**********//***********************main(void){timer0();//中断延时初始化ds1602();//初始化while(1){key=kbscan();//调用按键process();//按键处理alarm();//闹零if(hands()==1){write_temp_date(0xcc);//跳过write_temp_date(0x44);//温度转换tmpdelay(75);//500us// dema=250;// while(dema!=0);//500ms}if(hands()==1){write_temp_date(0xcc);//跳过write_temp_date(0xbe);//读取温度数据tmpdelay(75);//500us// dema=250;// while(dema!=0);//500ms}date_l=read_temp_date();//读取低位温度date_h=read_temp_date();//读取高位温度all_date=((date_h<<4)|(date_l>>4));// 整数位// dot_date=date_l&0x0f;// dot_date=dot_date*625;//小数位// all_date=all_date+dot_date/10000;disp();//显示}}。
LCD1602及其控制器的基本显示方法
![LCD1602及其控制器的基本显示方法](https://img.taocdn.com/s3/m/6ab61fd5d4bbfd0a79563c1ec5da50e2524dd1d6.png)
LCD1602及其控制器的基本显⽰⽅法LCD显⽰及键盘⽤法LCD1602及其控制器的基本显⽰⽅法向LCD输⼊的数据为ASCII码,需要通过数码扫描依次送到LCD显⽰,下⾯介绍LCD 控制器IP核LCD16X2A及其相关程序。
逻辑符号如下图:U_lcd_ctrl模块即为该控制器核在AltiumDesinger原理图中的符号表⽰。
其作⽤是接受前⾯⽤户⾃⼰的逻辑单元送来的ASCII码数据和控制信号,然后与外部的LCD显⽰器通讯,显⽰相应字符。
数据总线使⽤输⼊输出分离模式,IP核后⾯需要增加双向BUF控制单元(U8)。
L CD控制器端⼝说明如下:⽤户控制逻辑接⼝:CLK:控制器⼯作时钟,上升沿有效RST:复位信号,⾼电平有效DA TA[7..0]:ASCII码数据总线ADDR[3..0]:字符在LCD屏幕上的地址(共两⾏,每⾏16个字符)ADDR=“0000”~“1111”对应每⾏的第0~15个字符LINE:LCD1602屏幕上的⾏选择信号,LINE=0时数据在第⼀⾏显⽰,LINE=1时数据在第⼆⾏显⽰BUSY:控制器忙信号,数据未显⽰稳定时BUSY=1;反之为0STROBE:数据输⼊有效使能,⾼电平有效LCD显⽰器接⼝:LCD_E:LCD显⽰器使能LCD_RW:LCD读写⽅向控制LCD_RS:LCD命令,数据选择LCD_DA TA_TRI:LCD数据⾼阻态控制LCD_DA TAO:LCD数据输出总线LCD_DA TAI:LCD数据输⼊总线控制器⼯作原理如下:A 控制器复位当RST信号有效时(⾼电平),控制器进⼊LCD复位与初始化操作,此时,BUSY信号持续⾼电平,表⽰控制器忙,LCD不能进⾏⽤户请求的操作。
RST信号由⾼变低后的⼤约80us之后,LCD控制器初始化完成,可以响应⽤户的操作请求,此时,BUSY信号变低。
LCD处于显⽰模式。
B 字符显⽰上电后的LCD必须初始化⼀次,之后LCD控制器停留于“WAIT FOR DA TA”状态。
单片机1602显示程序
![单片机1602显示程序](https://img.taocdn.com/s3/m/3fbc8a2c52ea551810a687c0.png)
ORG 0000HAJMP STARTORG 0030H;液晶初始化START: MOV OUT,#01H;清屏LCALL WRMLMOV OUT,#38H;8为数据口,两行显示5*7点阵 LCALL WRMLMOV OUT,#06H;设置输入方式为光标向右移,屏幕上文字不移动LCALL WRMLMOV OUT,#0CH;设置显示方式,开显示屏LCALL WRML;第一行显示Hello!MOV OUT,#80H;设定第一行起始地址LCALL WRMLMOV R3,#80HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB1WRIN1: LCALL DISPDJNZ R4,WRIN1;第二行逐字显示Nice to meet youMOV OUT,#0FH;设置显示方式,开显示屏,有光标,光标闪烁LCALL WRMLMOV OUT,#0C0H;设定第二行起始地址LCALL WRMLMOV R3,#0C0HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB2WRIN2: LCALL DISPLCALL DELAYDJNZ R4,WRIN2MOV OUT,#08H;设置显示方式,关显示屏LCALL WRMLLCALL DELAYAJMP START;******************查表显示子程序******************DISP: PUSH AMOV A ,R5MOVC A,@A+DPTRMOV OUT,ALCALL WRDTINC R3INC R5POP ARET;*************判忙子程序************RDBF: MOV OUT,#0FFH;置位,准备读CLR RS;RS=0SETB RW ;R/W=1CLR ENOPSETB EJB OUT.7, RDBFRET;**************写命令子程序***************WRML: CLR RSCLR RWCLR ELCALL RDBFSETB ERET;*************写显示数据子程序*************WRDT: SETB RSCLR RW ;准备写入数据CLR E ;执行显示命令LCALL RDBF ;判断液晶模块是否忙?SETB ERET;*******************延时子程序*********** DELAY: MOV R6,#00HMOV R7,#00HDELAY1: NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RETTAB1: DB 20H,20H,20H,20H,20H,48H,65H,6CH,6CH,6FH,21H ;Hello!DB 20H,20H,20H,20H,20HTAB2: DB 4EH,69H,63H,65H,20H,74H,6FH,20H,6DH,65H,65H ;Nice to meet youDB 74H,20H,79H,6FH,75HEND。
proteus17 单片机控制RT1602液晶显示
![proteus17 单片机控制RT1602液晶显示](https://img.taocdn.com/s3/m/9d2410c826fff705cc170a1a.png)
程序编写及讲解(程序较长,对照 课本讲解)
LCD1602指令码(命令码)
Βιβλιοθήκη 此液晶上电的时候需要初始化,典型的指令码是38H, 也就是上电的时候需要调用 void wrc (unsigned char com)这个函数写指令码,用法是wrc(0x38);执行完这个 函数可以把液晶初始化成2行显示5x7的点阵8 位总线接 口。 此液晶支持的指令码有:
单片机控制RT1602液晶显示
单片机控制RT1602液晶显示
任务单
原理图绘制
程序编写及讲解
总结
任务单
任务 描述
通过本任务的学习,学会使用单片机控制 RT1602液晶显示
1.点按K1,用于设定调节“时、分、秒”时间功能和停止、 开始计时功能。 2.点按K2,用于调节“时、分、秒”加1功能。 3.点按K3,用于调节“时、分、秒”减1功能。 4.P0口为数据输出端直接连接液晶屏的数据端口,P2.0和 P2.1连接液晶屏的RS和E端。
LCD1602指令码(命令码)
1602LCD液晶屏的一般初始化(复位)过程指令设置: 延时30ms 写指令0x38;(不检测查忙) 延时5ms 写指令0x38;(不检测查忙) 延时5ms 写指令0x38;显示模式设置 写指令0x08;显示关闭 写指令0x01;显示清屏 写指令0x06;显示光标自动向右移动设置(无需人工干 预) 写指令0x0C;显示开及光标设置
0
0
0
0
0
1
N
S
LCD1602指令码(命令码)
解释:第一行指令主要能完成的功能是:控制液晶显示否, 光标显示否,光标闪烁否? 如0x08(显示关闭,不显示),0x0C(开显示,但不显 示光标和不闪烁)。 第二行指令主要能完成的功能是:地址指针加1还是减一, 光标左移还是右移?整屏是否移动? 如0x06(地址指针加一,显示光标自动向右移1位,但整屏 显示不移动)。 其它指令设置: 0x80(数据首地址,所以数据地址为:0x80+地址码) 0x01(显示清屏,地址指针=0,自动加1模式,光标或闪 烁回到显示屏左上角)。
51单片机控制1602LCD显示程序
![51单片机控制1602LCD显示程序](https://img.taocdn.com/s3/m/1203e1ea915f804d2a16c181.png)
LCD显示电路#include<reg51.h>sbit RS=P3^7; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P3^6; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^7; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,将BF位定义为P0.7引脚#define Lcd_Data P0#include <string.h>#include<intrins.h> //包含_nop_()函数定义的头文件unsigned char code string1[ ]={0x77,0x75,0x20,0x79,0x61,0x6E,0x67,0x20,0x79,0x61,0x6E,0x67,0x20,0x20,0x20,0x20}; //第一行显示的字符void Lcd_delay1ms() // 函数功能:延时1ms//注:不同单片机不同晶振需要对此函数进行修改{ unsigned char i,j;for(i=0;i<90;i++)for(j=0;j<33;j++);}void Lcd_delay(unsigned int n) // 函数功能:延时若干毫秒,入口参数:n{ unsigned int i;for(i=0;i<n;i++)Lcd_delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
result=1,忙碌;result=0,不忙***************************************************/bit Lcd_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 Lcd_WriteCom (unsigned char dictate){ while(Lcd_BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变,所以应先置ぜ? _nop_();_nop_(); //空操作两个机器周期,给硬件反应时间Lcd_Data=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:指定字符显示的实际地址x入口参数:注:此函数已经加上了0x80,故只需写上实际地址就行***************************************************/void Lcd_WriteAddress(unsigned char x){ Lcd_WriteCom(x|0x80); //显示位置的确定方法规定为80H+地址码x/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/void Lcd_WriteData(unsigned char y){while(Lcd_BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变所以应先置ぜ?Lcd_Data=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void Lcd_Int(void){Lcd_delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间Lcd_WriteCom(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口Lcd_delay(5); //延时5msLcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);设置模式次写9// Lcd_WriteCom(0x38);Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x0C); //显示模式设置:显示开,有光标,光标闪烁Lcd_delay(5);Lcd_WriteCom(0x06); //显示模式设置:光标右移,字符不移Lcd_delay(5);Lcd_WriteCom(0x01); //清屏幕指令,将以前的显示内容清零Lcd_delay(5); }void hanying_show(void){unsigned char Lcd_i;Lcd_WriteCom(0x01);//清显示:清屏幕指令Lcd_delay(2);Lcd_WriteAddress(0x00); // 设置显示位置为最左侧Lcd_delay(2);Lcd_i=0;while(string1[Lcd_i]!='\0') //'\0'是数组结束标志需先将字符存入{Lcd_WriteData(string1[Lcd_i]); // 显示字符Lcd_i++;Lcd_delay(4);}}void main(){Lcd_Int(); //1602初始化while(1){hanying_show();}}。
LCD1602滚动显示
![LCD1602滚动显示](https://img.taocdn.com/s3/m/69251a3c5727a5e9856a6169.png)
/********************************************************************************* 描述: LCD1602 滚动显示 ** 显示方式: ** 1、从左到右逐字显示,闪动二次,清屏。
** 2、再从右到左逐字显示,闪动二次,清屏。
** 3、周期性地重复上述显示方式。
* ********************************************************************************/#include <reg51.h>#include <intrins.h>typedef unsigned char BYTE;typedef bit BOOL;sbit LCD_RS = P2^6;sbit LCD_RW = P2^5;sbit LCD_EP = P2^7;BYTE code dis1[] = {" WELCOME TO "};BYTE code dis2[] = {" "};BYTE code dis3[] = {" OT EMOCLEW "};BYTE code dis4[] = {" MOC.NIHCERP.WWW "};delay(int ms){ // 延时子程序int i;while(ms--){for(i = 0; i< 250; i++){_nop_();_nop_();_nop_();_nop_();}}}BOOL lcd_bz(){ // 测试LCD忙碌状态BOOL result;LCD_RS = 0;LCD_RW = 1;LCD_EP = 1;_nop_();_nop_();_nop_();_nop_();result = (BOOL)(P0 & 0x80);LCD_EP = 0;return result;}lcd_wcmd(BYTE cmd){ // 写入指令数据到LCD while(lcd_bz());LCD_RS = 0;LCD_RW = 0;LCD_EP = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();LCD_EP = 1;_nop_();_nop_();_nop_();_nop_();LCD_EP = 0;}lcd_pos(BYTE pos){ //设定显示位置lcd_wcmd(pos | 0x80);}lcd_wdat(BYTE dat){ //写入字符显示数据到LCD while(lcd_bz());LCD_RS = 1;LCD_RW = 0;LCD_EP = 0;P0 = dat;_nop_();_nop_();_nop_();LCD_EP = 1;_nop_();_nop_();_nop_();_nop_();LCD_EP = 0;}lcd_init(){ //LCD初始化设定lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据delay(1);lcd_wcmd(0x0c); //显示开,关光标delay(1);lcd_wcmd(0x06); //移动光标delay(1);lcd_wcmd(0x01); //清除LCD的显示内容delay(1);}main(){BYTE i;lcd_init(); // 初始化LCDdelay(10);while(1){lcd_wcmd(0x06); //向右移动光标lcd_pos(0); //设置显示位置为第一行的第1个字符 i = 0;while(dis1[ i ] != '\0'){ //显示字符"WLCOME TO"lcd_wdat(dis1[ i ]);i++;delay(30); //控制两字之间显示速度}lcd_pos(0x40); //设置显示位置为第二行第1个字符 i = 0;while(dis2[ i ] != '\0')lcd_wdat(dis2[ i ]); //显示字符" "i++;delay(30); //控制两字之间显示速度}delay(800); //控制停留时间lcd_wcmd(0x01); //清除LCD的显示内容delay(1);lcd_wcmd(0x04); //向左移动光标lcd_pos(15); //设置显示位置为第一行的第16个字符 i = 0;while(dis3[ i ] != '\0'){ //显示字符"WLCOME TO"lcd_wdat(dis3[ i ]);i++;delay(30); //控制两字之间显示速度}lcd_pos(0x4F); //设置显示位置为第二行的第16个字符 i = 0;while(dis4[ i ] != '\0'){lcd_wdat(dis4[ i ]); //显示字符" "i++;delay(30); //控制两字之间显示速度}delay(800); //控制停留时间lcd_wcmd(0x01); //清除LCD的显示内容delay(200); //控制两屏转换时间}}。
最新按键复用(1602 液晶显示)
![最新按键复用(1602 液晶显示)](https://img.taocdn.com/s3/m/44ed41910066f5335a8121f6.png)
按键复用(1602液晶显示)按键复用(1602 液晶显示)AVR单片机单按键复用之程序AVR单片机中断法的按钮前一段就可以了,查询的居然卡住了。
先写一个51C的,在此基础上写了AVR GCC的,一直到今天才完成。
感觉二者还是有点区别的。
//查询法按键程序,单键复用。
P1.O接一按键,P1.1接一LED。
//11 05 13 E:\DPJ_C\OTHER\ONEKEY\ONEKEY.C#include <reg51.h>#define uchar unsigned charsbit LED1= P1^1;sbit LED2= P1^2;sbit KEY = P1^0;void delay(unsigned int ms ) {unsigned char i;while(ms--)for(i=0;i<123;i++);}void disp1(){LED1=1;}void disp2(){LED1=0;}void main(){uchar temp;while(1){while(!KEY){delay(10);if(KEY)temp=~temp;if(~temp)disp1();elsedisp2();}}}//查询法按键程序,单键复用。
PCO接一按键,PD0接一LED。
//11 05 13 E:\AVR\ONEKEY\onekey.c#include<avr/io.h>#include<util/delay.h>#define KEY PD0#define uchar unsigned charuchar temp,i;void disp1(){DDRC&=~_BV(PC0);//PB0端口低电平PORTC&=~_BV(PC0);//PB0高阻状态,LED无电流通过}void disp2(){DDRC|=_BV(PC0);//PC0端口高电平,输出PORTC&=~_BV(PC0);//PC0低电平输出,LED点亮}int main(){DDRD|=_BV(KEY); //PD0高电平,输出PORTD|=_BV(KEY);DDRD&=~_BV(KEY);while(1){while(!(PIND&_BV(KEY))){for(i=0;i<5;i++)_delay_ms(10);if((PIND&_BV(KEY)))//等待按键释放temp =~temp;if(temp==0xff)disp2();elsedisp1();}}}1602字符液晶详细资料和实例时间:2010-10-11 来源: 作者: 点击:816 字体大小:【大中小】1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。
2.超详细矩阵键盘控制1602程序实例说明
![2.超详细矩阵键盘控制1602程序实例说明](https://img.taocdn.com/s3/m/016ec1d7a58da0116c17494b.png)
2、超详细矩阵键盘控制1602程序实例说明(带电路图)By 即墨天2 一、电路图/*----------------------------------------------//程序功能:通过矩阵键盘在LCD1602任意位置输入0~9,且可通过光标二次修改;------------ 能退格,能清除显示,还能自己任意定义16个按键的意义.//调试状态:仿真实现//时间:2014-7-25-----------------------------------------------*/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit Lcd_RS = P2^0;sbit Lcd_RW = P2^1;sbit Lcd_EN = P2^2;uchar code table[] = "51201314" ;uchar code table1[] = "20140815" ;uchar code key16[]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77} ; //该键盘特征码是在特定的接线下有效,请参见电路原理图uchar key_number;void delayMS(uint x){uchar i;while(x--) for(i = 0; i < 120; i++);}//----------------------------------------------//忙检查//-----------------------------------------------bit Busy_Check(){bit state;Lcd_RS = 0;Lcd_RW = 1;Lcd_EN = 1;delayMS(1);state=(bit)(P0&0x80); //屏蔽底7位,state的值仅有高位决定Lcd_EN = 0;delayMS(1);return state;}//---------------------------------------------//向LCD写数据//----------------------------------------------void LCD_Wdata(uchar dat){while(Busy_Check()); //忙等待Lcd_RS = 1;Lcd_RW = 0;Lcd_EN = 0;P0 = dat;Lcd_EN = 1; //高脉冲delayMS(1);Lcd_EN = 0;}//---------------------------------------------//向LCD写指令//----------------------------------------------void LCD_Wcmd(uchar cmd){while(Busy_Check()); //忙等待Lcd_RS = 0;Lcd_RW = 0;P0 = cmd;delayMS(1);Lcd_EN = 0;Lcd_EN = 1; //高脉冲delayMS(1);Lcd_EN = 0;}//---------------------------------------------------------//LCD初始化//---------------------------------------------------------void Init_Lcd(){LCD_Wcmd(0x38);//显示模式设置delayMS(1);LCD_Wcmd(0x0f);//开显示,显示光标,光标闪烁delayMS(1);LCD_Wcmd(0x06);//当读写一个字符后地址指针加一,且光标加一delayMS(1);LCD_Wcmd(0x01);//清屏delayMS(1);}//---------------------------------------------------------//键盘模块//---------------------------------------------------------bit pushkey() //判断是否有键按下{P1=0xf0;if(P1!=0xf0)return (1);elsereturn (0);}void key_scan()//矩阵扫描{ uchar keycode,p;delayMS(15); // 延时消抖if(P1!=0xf0){P1 = 0xf7; //键盘扫描码初值,逐行扫描,P1.3=0,扫描第4列while(1){keycode = P1; //读出数据,看是否在此行上的某列按键被按下if((keycode&0xf0)!=0xf0) break;// 如果扫描到按下的键,则退出P1=_cror_(P1,1); //否则,左移,扫描下一列}while((pushkey())); //等待按键释放for(p = 0 ; p<16 ;p++){if ( keycode== key16[p])key_number=p; //与特征值对比得与哪个键按下}}}void LCD_address(uchar hang,uchar lie )//显示字符先输入显示的位置{if (hang%2==1) LCD_Wcmd(0x80+(lie%16)-1);else LCD_Wcmd(0x80+0x40+(lie%16)-1);}void LCD_display(){ uchar j;LCD_address(1,1);while(table1[j]!='\0'){LCD_Wdata(table[j]);j++;}}void main(){ uchar n=0;Init_Lcd(); //初始化LCDLCD_display();while(1){if(pushkey())//判断是否有键按下{key_scan();switch(key_number){case 10: LCD_Wcmd(0x10);break; //光标左移(相当于A 被按下)case 11: LCD_Wcmd(0x14);break; //光标右移(相当于B被按下)case 12: n++; //光标下移(相当于C被按下)if((n%2)==1) //第二次被按下的时候,光标回到第一行{LCD_Wcmd(0x80+0x40);break;}else LCD_Wcmd(0x80);break;case 13: LCD_Wcmd(0x10);LCD_Wdata(0x00);LCD_Wcmd(0x10);break; //产生退格功能,按下一次后清除前一次的显示case 15: LCD_Wcmd(0x01);break;//清屏default: LCD_Wdata(key_number+0x30);break;}}} ;}。
1602显示简易电子时钟,可按键调整时间
![1602显示简易电子时钟,可按键调整时间](https://img.taocdn.com/s3/m/e942ab214b35eefdc8d33392.png)
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit RS=P2^6;sbit RW=P2^5;sbit lcden=P2^7;sbit s1=P1^1; //功能键sbit s2=P1^2; //加一键sbit s3=P1^3; //减一键sbit a=P1^4;sbit c1=P2^0; //功能键sbit c2=P2^1; //加一键sbit c3=P2^2; //减一键uchar count,s1num,c1num,i,j;char nian,yue,ri,shi,fen,miao;uchar code table[]=" 2011-08-18 THU";uchar code table1[]=" 23:59:53";uchar code week1[]="MON";uchar code week2[]="TUE";uchar code week3[]="WED";uchar code week4[]="THU";uchar code week5[]="FRI";uchar code week6[]="SAT";uchar code week7[]="SUN";/*****************************************************************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=250;y>0;y--);}/*****************************************************************************/ void write_com(uchar com) //写指令{RS=0;RW=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/void write_date(uchar date) //写数据{RS=1;RW=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/ void init(){uchar num;lcden=0;write_com(0x38); //显示模式设置write_com(0x0c); //显示开关write_com(0x06); //显示光标设置write_com(0x01); //显示清零write_com(0x80);for(num=0;num<16;num++){write_date(table[num]);delay(20);}write_com(0x80+0x40);for(num=0;num<13;num++){write_date(table1[num]);delay(20);}TMOD=0x01;TH0=(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_nyr(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 write_nian(uchar add,uchar date) //千位计算{uchar shi,ge;// bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);// write_date(0x30+qian);// write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);} *//*****************************************************************************/ void keyscan() //判断按键函数{a=0;if(s1==0) //判断功能键是否被按下{delay(5); //消抖if(s1==0){s1num++;while(!s1); //松手检测if(s1num==1) //功能键被按下一次{TR0=0; //时间停止write_com(0x80+0x40+12); //光标向前移一位write_com(0x0f); //光标闪烁}if(s1num==2) //功能键被按下两次{write_com(0x80+0x40+9);}if(s1num==3) //功能键被按下三次{write_com(0x80+0x40+6);}if(s1num==4) //功能键被按下四次{s1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(s1num!=0) //判断功能键是否被按下{if(s2==0) //判断加一键是否被按下{delay(5);if(s2==0) //确认加一键被按下{while(!s2);if(s1num==1) //判断指针指向“秒"{miao++;if(miao==60)miao=0;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen++;if(fen==60)fen=0;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi++;if(shi==24)shi=0;write_sfm(5,shi);write_com(0x80+0x40+5);}}}if(s3==0) //判断减一键是否被按下{delay(5);if(s3==0){while(!s3);if(s1num==1) //判断指针指向“秒"{miao--;if(miao==-1)miao=59;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen--;if(fen==-1)fen=59;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi--;if(shi==-1)shi=23;write_sfm(5,shi);write_com(0x80+0x40+5);}}}}}/*****************************************************************************/ void keyscan1() //调整日期{if(c1==0){delay(5);if(c1==0){c1num++;while(!c1);if(c1num==1) //指向”星期“{TR0=0; //时间停止write_com(0x80+15); //光标向前移一位write_com(0x0f); //光标闪烁}if(c1num==2) //指向”日“{write_com(0x80+11);}if(c1num==3) //指向”月“{write_com(0x80+8);}if(c1num==4) //指向”年“{write_com(0x80+5);}if(c1num==5){c1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(c1num!=0) //判断功能键是否被按下{if(c2==0) //判断加一键是否被按下{delay(5);if(c2==0) //防抖{while(!c2); //松手检测if(c1num==1) //指向“星期”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向”日“{ri++;if(ri==32)ri=1;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向”月“{yue++;if(yue==13)yue=1;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向”年“{nian++;write_nyr(4,nian);write_com(0x80+4);}}}if(c3==0) //减一功能键按{delay(5);if(c3==0){while(!c3);if(c1num==1) //指向“星”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向“日”{ri--;if(ri==0)ri=31;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向“月”{yue--;if(yue==0)yue=12;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向“年”{nian--;write_nyr(4,nian);write_com(0x80+4);}}}}}/*****************************************************************************/ void main(){init();while(1){keyscan();keyscan1();if(count==20) //定时1秒{count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;ri++;i++;if(ri==32){ri=1;yue++;if(yue==13){yue=1;nian++;write_nyr(3,nian);}write_nyr(7,yue);}write_nyr(10,ri);if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}write_sfm(5,shi);}write_sfm(8,fen);}write_sfm(11,miao);}}}/*****************************************************************************/ void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;}。
1602的使用方法及3个代码
![1602的使用方法及3个代码](https://img.taocdn.com/s3/m/88bef5cb9ec3d5bbfd0a74cd.png)
void delay(uint xms)
{ //延时函数
uint i,j;
for(i = xms;i > 0;i--)
for(j = 110;j > 0;j--);
}
/*******************************************************************/
(2)读/写控制设置为写模式,即低电平。
(3)将数据或命令送达数据线上。
(4)将E一个高脉冲将数据送入液晶控制器,完成写操作。
1602
/*程序功能:在1602液晶上显示1 2 3 4 5*/
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
{
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(1);
lcd_wcmd(0x0c); //设置开显示,不显示光标
delay(1);
lcd_wcmd(0x06); //写一个字符后地址指针加1
delay(1);
lcd_wcmd(0x01); //显示清0,数据指针清0
{
lcd_wcmd(0x18); //全屏字符同时左移一格,写在屏幕外的字符慢慢显示出来
delay(800); //控制移动时间
}
}
}
综合实验三:按键控制
/*此程序功能:按下4个按键可在1602液晶上显示不同字样*/
#include <reg52.h> //52系列单片机头文件
液晶上显示时钟并带按键调整时和分(1602)
![液晶上显示时钟并带按键调整时和分(1602)](https://img.taocdn.com/s3/m/a3f7d98302d276a200292ec3.png)
液晶上显示时钟并带按键调整时和分说明:1、此程序只需将之前的时钟程序的数码管显示部分改为液晶显示2、在主函数中进行定时中断初始化、调用时分秒处理子程序、调用按键扫描子程序3、在定时中断子程序中每+1s就调用液晶显示子程序,在此处调用显示程序可以避免闪烁现象;在显示子程序中调用液晶显示初始化、写指令、写数据等子函数4、时分秒处理子程序将时分秒的十位和个位数暂存于数组中5、由于液晶的使用也需要用到独立按键的那几个IO口,所以用按键调整时间时不要用到独立按键,在矩阵键盘中,将P3.7口置0后,s9、s13、s17、s21也相当于独立按键,s9使分加1,s13使分减1,s17使时减1,s21使时加1.程序如下:#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar table1[11]={'0','1','2','3','4','5','6','7','8','9','-'}; uchar table2[8]={0,0,10,0,0,10,0,0}; //存放时、分、秒uchar table3[11]="liu jun luo";sbit dula=P2^6; //初始化时将数码管的位选和段选信号赋值为0,因为液晶sbit wela=P2^7; //和数码管都是从P0口传数据的,防止将数据传到数码管sbit en=P3^4; //使能信号控制端sbit rs=P3^5; //数据/命令选择端(H/L)sbit rw=P3^6; //读/写控制端 (H/L)//定义开发板上的按键sbit s2 = P3^0; //每按一次分加1sbit s3 = P3^1; //每按一次分减1sbit s4 = P3^2; //每按一次时加1sbit s5 = P3^3; //每按一次时减1sbit p3_7=P3^7; //让其置0时,s9、s13、s17、s21相当于独立按键uchar count; //定义无符号字符型数据“count”,用于计数20次达到20*50ms=1suint shi,fen,miao,shis,shig,fens,feng,miaos,miaog; //定义时、分、秒以及时、分、秒的十位和个位//延时子程序1用于读写操作时序图上的的短暂延时void delay1(uint z){uint x,y;for(x=z;x>0;x--)for(y=10;y>0;y--);}//延时子程序2用于控制整屏移动速度的快慢void delay2(uint z){uint x,y;for(x=z;x>0;x--)for(y=10;y>0;y--);}//写指令子程序void write_com(uchar com){P0=com; //将命令传至P0口rs=0; //写的是命令故将其置零en=0; //根据写操作时序图,传命令前en=0delay1(10); //根据写操作时序图,延时一小会en=1; //en=1时开始传输命令delay1(10); //延时一会待命令传完en=0; //命令传完再将其置0}//写数据子程序void write_date(uchar date){P0=date; //将数据传至P0口rs=1; //写的是数据故将其置1en=0; //根据写操作时序图,传数据前en=0delay1(10); //根据写操作时序图,延时一小会en=1; //en=1时开始传输数据delay1(10); //延时一会待数据传完en=0; //数据传完再将其置0}//液晶初始化子程序void init(){P0=0; //P0初始化为0dula=0; //防止将数据传到数码管wela=0;rw=0; //程序牵涉写操作没有读操作,直接置0 write_com(0x38); //设置16*2显示模式delay1(20); //传完命令适当延时一会write_com(0x0c); //设置开显示、不显示光标delay1(20) ;write_com(0x06); //当读或写一个字符后地址指针加1,且光标加1 delay1(20);write_com(0x01); //显示清屏delay1(20);}//显示子程序void display(){uchar a,b,c;init();write_com(0x80+5);//选择数据地址指针delay1(20);for(a=0;a<8;a++) //一共要显示8位,所以写八次{write_date(table1[table2[a]]); //在第一行显示时钟}write_com(0x80+0x40+3);delay1(20);for(b=0;b<11;b++)//一共要显示11位,所以写11次{write_date(table3[b]); //在第二行显示我的名字}}void process() //时、分、秒处理子程序{table2[7]=miao%10;table2[6]=miao/10;table2[4]=fen%10;table2[3]=fen/10;table2[1]=shi%10;table2[0]=shi/10;}//定时器中断函数,定时50ms,每隔1秒,miao++;void timer0() interrupt 1 using 1{count++; //每50ms,count就+1if(count==20) //当count=20时即计数到1s的时候执行if大括号内的语句{display(); //调用液晶显示子程序(在这里调用避免闪烁)count=0;miao++;if(miao==60){miao=0; //当到60秒的时候,分+1 ,同时秒从0重新开始计时fen++;if(fen==60){fen=0; //当到60分的时候,时+1 ,同时分从0重新开始计时shi++;if(shi==12){shi=0; //当到12小时的时候,时从0重新开始计 }}}}TH0 = 0x3c; //到了50ms后重新装入初值TL0 = 0xb0;}void key() //按键判断子程序{if(s2==0) //判断s2是否按下键盘{delay2(100); //延时,软件消抖if(s2==0) //确认按键按下{fen++; //分加1if(fen==60) //加到60时返回0继续加{fen=0;}}while(s2==0); // 等待按键放开. 即每按一次只加1}if(s3==0) //判断s3是否按下键盘{delay2(100); //延时,软件消抖if(s3==0) //确认按键按下{fen--; //分减1if(fen==-1) //减到0时返回60继续减{fen=60;}}while(s3==0); // 等待按键放开. 即每按一次只加1}if(s4==0) //判断s4是否按下键盘{delay2(100); //延时,软件消抖if(s4==0) //确认按键按下{shi++; //时加1if(shi==12) //加到12时返回0继续加{shi=0;}}while(s4==0); // 等待按键放开. 即每按一次只加1}if(s5==0) //判断s2是否按下键盘{delay2(100); //延时,软件消抖if(s5==0) //确认按键按下{shi--; //时减1if(shi==-1) //减到0时返回12继续减{shi=12;}}while(s5==0); // 等待按键放开. 即每按一次只加1}}//主函数void main(){p3_7=0; //将矩阵键盘的这个接口一直呈低电平后s9、s13、s17、s21相当于独立按键count=0;TMOD = 0x01; //选择T0定时器工作方式1ET0 = 1; //开中断EA = 1; //开总中断TH0 = 0x3c; //设置初值,定时50msTL0 = 0xb0;TR0 = 1; //开启计数while(1){process(); //调用时、分、秒处理子程序key(); //调用键盘扫描子程序}}。
单片机控制的lcd1602字符液晶滚动电路功能说明
![单片机控制的lcd1602字符液晶滚动电路功能说明](https://img.taocdn.com/s3/m/79ff172ef4335a8102d276a20029bd64793e6249.png)
单片机控制的lcd1602字符液晶滚动电路功能说明功能说明:单片机控制的LCD1602字符液晶滚动电路该电路是由单片机控制的LCD1602字符液晶显示屏的滚动功能。
通过单片机的程序控制,可以实现字符的滚动显示,从而达到信息展示的目的。
具体功能说明如下:1. 显示屏控制:该电路使用LCD1602字符液晶显示屏作为显示器,通过单片机的控制,可以控制显示屏上的字符显示。
显示屏具有2行16列的字符显示区域。
2. 滚动显示:通过单片机的程序控制,可以实现字符的滚动显示。
滚动显示可以从左向右或者从右向左进行,可以设置滚动速度和滚动内容。
3. 单片机控制:该电路使用单片机作为控制核心,通过单片机的GPIO口控制显示屏的数据和控制信号。
单片机可以根据用户的需求,通过编程实现不同的滚动效果。
4. 滚动速度调节:用户可以通过调节单片机程序中的延时参数,来控制滚动速度。
延时时间越短,滚动速度越快;延时时间越长,滚动速度越慢。
5. 滚动内容设置:用户可以通过编程将需要滚动显示的内容存储在单片机的内存中,然后通过单片机控制,将内容逐个字符地显示在LCD1602字符液晶显示屏上。
6. 滚动方向选择:用户可以通过编程设置滚动的方向,可以选择从左向右滚动或者从右向左滚动。
7. 硬件连接:该电路需要将单片机的GPIO口与LCD1602字符液晶显示屏的数据和控制信号引脚连接起来,通过连接线进行数据传输和控制。
总结:该电路通过单片机控制LCD1602字符液晶显示屏的滚动功能,可以实现字符的滚动显示,从而达到信息展示的目的。
用户可以通过编程设置滚动速度、滚动内容和滚动方向,灵活控制滚动效果。
这种电路在信息展示、广告宣传等领域有着广泛的应用。
STM32F103C8T6控制1602液晶显示
![STM32F103C8T6控制1602液晶显示](https://img.taocdn.com/s3/m/dccb091bde80d4d8d15a4fb1.png)
Send_Com(0x80+0x40);
for(num=0;num<10;num++)
{
Send_Dat(table1[num]);
Delay(2000000);
}
while(1);
}
}
{
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
#define Set_EN (GPIO_SetBits(GPIOB,GPIO_Pin_2))
//定义RS,RW,EN=1时分别是CLR_RS,CLR_RW,CLR_EN
#define CLR_RS (GPIO_ResetBits(GPIOB,GPIO_Pin_0))
#define CLR_RW (GPIO_ResetBits(GPIOB,GPIO_Pin_1))
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
#define CLR_EN (GPIO_ResetBits(GPIOB,GPIO_Pin_2))
GPIO_InitTypeDef GPIO_InitStructure;
键盘控制1602液晶显示(单片机)
![键盘控制1602液晶显示(单片机)](https://img.taocdn.com/s3/m/f3377c0d7cd184254b353526.png)
lcden=1;//使能端开始拉高
delay(5);//由时序图,使能端拉低一段时间thD2后,数据传输?
lcden=0;//然后将使能端拉低。
}
void main()
{
uint a,b,c,d,e;
init();//定义一个初始化函数,个人习惯不在main函数中有太多的语句,大量运用函数调用
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit lcdwr=P2^6;//读写选择端,H/L;
sbit lcden=P2^7;//使能端
sbit lcdrs=P2^5;//RS数据/命令选择端。H/L;
}
}
for(c=0;c<10;c++)
{
write_dat(tabl);
write_com(0x01);
}
if(key4==0)
{
write_com(0x01);//清屏指令,如果不清屏,将会有别的乱码影响,可以考虑写在别的位置
for(e=10;e>0;e--)
delay(5);//由时序图,使能端拉低一段时间thD2后,数据传输完成
lcden=0;//然后将使能端拉低
}
void write_dat(uchar dat)
{
lcdrs=1;//因为在数据写入函数中,一直写的是数据,所以可以一直设置为1
P0=dat;//由时序图可知,在使能en触发时,早就有数据写入。
{
uint x,y;
for(x=z;x>0;x--)