单片机设计 按键顺序控制加减计数(1602 液晶显示) 程序

合集下载

51单片机控制lcd1602实现计算器

51单片机控制lcd1602实现计算器

//利用51单片机控制LCD1602,实现加减乘除运算#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define DATE_IO P0//P0口并行传输数据(LCD1602的数据端接P0口)sbit RS=P1^0;//LCD1602寄存器选择端sbit E=P1^2; //使能信号端sbit RW=P1^1;//读写控制端sbit deng=P1^3;//结果sbit shuzi11=P3^2;//前面的数字加1(因为我的按键是与P3口相连的)sbit shuzi22=P3^7; //后面的数字加1sbit jia=P3^3;//加号sbit jian=P3^4;//减号sbit cheng=P3^5;//乘号sbit chu=P3^6;//除号uint countqian=0,counthou=0;//数值uchar qian,bai,shi,ge,a=0;uchar code table1[]="0123456789";uchar code table2[]="+-*/";//**********************延时函数***************************************** void delay_us(unsigned int n){if(n==0)return ;while(--n);}void delay_ms(uint i){unsigned char a,b;for (a=1;a<i;a++)for(b=1;b;b++);}void delay(uint z){uint x,y;for(x=110;x>0;x--)for(y=z;y>0;y--);}//***********************************************************************//*********************控制LCD1602的函数*******************************void write_command(uchar come)//写指令函数{RS=0;//选择指令寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=come;delay_us(5);E=0;RS=1;}void write_date(uchar date)//写数据函数{RS=1;//选择数据寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=date;delay_us(5);E=0;RS=0;}//***************************************************************************** ***//**************************液晶初始化函数(基本上就是这个模式)*******************void init()//液晶初始化函数{RW=0;//低电平时进行写操作(高电平时进行读操作)E=0;write_command(0x38);//设置LCD两行显示,一个数据由5*7点阵表示,数据由8跟线传输delay_ms(5);write_command(0x01);//清除屏幕显示delay_ms(5);write_command(0x06);//设定输入方式,增量不移位delay_ms(5);write_command(0x0c);//开整体显示,关光标,不闪烁delay_ms(5);}//***************************************************************************** *****void jiayiqian()//前边数字加1计数函数{if(shuzi11==0)//如果前面加1的按键按下{delay(50);//消除抖动countqian=countqian+1;}if(countqian==999)//记到999归0countqian=0;}void jiayihou()//后边数字加1计数函数{if(shuzi22==0)//如果后面加1的按键按下{delay(50);//消除抖动counthou=counthou+1;}if(counthou==999)//记到999归0counthou=0;}void fuhao()//+,-,*,/运算号{if(jia==0)//如果加号按下{while(!jia);//等待按键的释放write_date(table2[0]);//显示'+'a=1;//加号按下的标志}if(jian==0)//如果减号按下{while(!jian);//等待按键的释放write_date(table2[1]);//显示'-'a=2;//减号按下的标志}if(cheng==0)//如果乘号按下{while(!cheng);//等待按键的释放write_date(table2[2]);//显示'*'a=3; //乘号按下的标志}if(chu==0)////如果除号按下{while(!chu);//等待按键的释放write_date(table2[3]);//显示'/'a=4;//除号按下的标志}}void chaiqian()//将前边各位数字拆开函数{bai=countqian/100;//求百位数字shi=countqian%100/10;//求十位数字ge=countqian%10;//求各位数字}void chaihou()//将后边各位数字拆开函数{bai=counthou/100;//求百位数字shi=counthou%100/10;//求十位数字ge=counthou%10;//求各位数字}void chaijiejia()//将相加结果各位数字拆开函数{qian=(countqian+counthou)/1000;//求千位数字bai=(countqian+counthou)%1000/100;//求百位数字shi=(countqian+counthou)%100/10;//求十位数字ge=(countqian+counthou)%10;//求各位数字}void chaijiejian()//将相减结果各位数字拆开函数{qian=(countqian-counthou)/1000;//求千位数字bai=(countqian-counthou)%1000/100;//求百位数字shi=(countqian-counthou)%100/10;//求十位数字ge=(countqian-counthou)%10;//求各位数字}void chaijiecheng()//将相乘结果各位数字拆开函数{qian=(countqian*counthou)/1000;//求千位数字bai=(countqian*counthou)%1000/100;//求百位数字shi=(countqian*counthou)%100/10;//求十位数字ge=(countqian*counthou)%10;//求各位数字}void chaijiechu()//将相除结果各位数字拆开函数(只取了模值){qian=(countqian/counthou)/1000;//求千位数字bai=(countqian/counthou)%1000/100;//求百位数字shi=(countqian/counthou)%100/10;//求十位数字ge=(countqian/counthou)%10;//求各位数字}void xianshiqian()//显示前边数字{write_command(0x80);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位fuhao();//显示运算号delay(50);//改变数值可以修改数字滚动的速度}void xianshihou()//显示后边数字{write_command(0x80+4);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void xianshijie()//显示结果{write_command(0xc0);//设置显示地址为LCD第二行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[qian]);//第一位显示千位write_date(table1[bai]);//第二位显示百位write_date(table1[shi]); //第三位显示十位write_date(table1[ge]); //第四位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void main()//主函数{init();//调用液晶初始化函数while(1){jiayiqian();//调用前边数字加1计数函数chaiqian();//调用将前边数字各位数字拆开函数xianshiqian();//显示前边数字jiayihou();//调用后边数字加1计数函数chaihou();//调用将后边数字各位数字拆开函数xianshihou();//显示后边数字if(deng==0)//控制显示结果的按键按下{if(a==1)//计算的是加法{chaijiejia();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==2)//计算的是减法{chaijiejian(); //将结果的各位数字拆分开xianshijie();//显示结果}if(a==3)//计算的是乘法{chaijiecheng();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==4) //计算的是除法{chaijiechu();//将结果的各位数字拆分开xianshijie(); //显示结果}}}}。

C8051F350单片机1602液晶显示程序

C8051F350单片机1602液晶显示程序

#include <C8051F350.h>#include <stdio.h>#include <math.h>//-----------------------------------------------------------------------------// 16-bit SFR Definitions for 'F35x//-----------------------------------------------------------------------------sfr16 TMR2RL = 0xCA; // Timer2 reload valuesfr16 TMR2 = 0xCC; // Timer2 countersfr16 ADC0DEC = 0x9A; // ADC0 Decimation Ratio Register//sfr16 ADC0 = 0xbd;//-----------------------------------------------------------------------------// Global CONSTANTS//-----------------------------------------------------------------------------#define SYSCLK 24500000 // SYSCLK frequency in Hz#define MDCLK 2457600 // Modulator clock in Hz (ideal is// (2.4576 MHz)#define OWR 960 // Desired Output Word Rate in Hz ADC0输出字速率,最大960 #define BAUDRATE 115200 // Baud rate of UART in bps#define uchar unsigned char#define uint unsigned int#define DataPort P0sbit LCM_EN=P1^0;sbit LCM_RS=P1^1;unsigned char D1,D2,D3,D4,D5,D6,D7,D8;//sbit LED = P0^7;unsigned int k;//-----------------------------------------------------------------------------// Function PROTOTYPES//-----------------------------------------------------------------------------void Oscillator_Init (void);void Port_Init (void);void UART0_Init (void);void ADC0_Init(void);void delay(int i);void WriteCommandLCM(uchar CMD);void WriteDataLCM(uchar dataW);void InitLcd();void lcd_write_char(uchar x,uchar y,uchar dataW) ;//-----------------------------------------------------------------------------// MAIN Routine//-----------------------------------------------------------------------------void main (void){PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer// enable)Oscillator_Init(); // Initialize system clockPort_Init(); // Initialize Crossbar and GPIO// UART0_Init(); // Initialize UART0 for printf'sInitLcd();ADC0_Init(); // Initialize ADC0AD0INT = 0;ADC0MD = 0x83; // Start continuous conversions EA = 1; // Enable global interruptswhile (1) { // Spin forever}}//-----------------------------------------------------------------------------// Initialization Subroutines//-----------------------------------------------------------------------------void delay(int i) //大概0.43ms{int j,k;for(j=0;j<i;j++)for(k=0;k<2000;k++);}void lcd_write_char(uchar x,uchar y,uchar dataWord) //y是行,x是列,都是从0开始计数{unsigned char add;if(y==0)add=0x80+x;elseadd=0xc0+x;WriteCommandLCM(add);WriteDataLCM(dataWord);}void WriteCommandLCM(uchar CMD){//delay(2);LCM_EN=0;LCM_RS=0;DataPort&=0xf0;// delay(2);DataPort|=(CMD&0xf0)>>4; delay(5);LCM_EN=1;delay(10);LCM_EN=0;delay(10);//CMD=CMD>>4;DataPort&=0xf0;// delay(2);DataPort|=(CMD&0x0f); delay(10);LCM_EN=1;delay(10);LCM_EN=0;}void WriteDataLCM(uchar dataW) // delay(2);LCM_EN=0;LCM_RS=1;// delay(2);DataPort&=0xf0;// delay(2);DataPort|=(dataW&0xf0)>>4; delay(2);LCM_EN=1;delay(5);LCM_EN=0;delay(5);// dataW=dataW>>4;DataPort&=0xf0;// delay(2);DataPort|=(dataW&0x0f);delay(2);LCM_EN=1;delay(5);LCM_EN=0;}void InitLcd(){delay(2000);WriteCommandLCM(0x28); //4位数据总线//delay(5);WriteCommandLCM(0x01); //清屏WriteCommandLCM(0x0C); //显示开及光标设置// WriteCommandLCM(0x0f);// delay(200);}//----------------------------------------------------------------------------- // Oscillator_Init//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This routine initializes the system clock to use the internal 24.5MHz// oscillator as its clock source. Also enables missing clock detector reset.////-----------------------------------------------------------------------------void Oscillator_Init (void){OSCICN = 0x83; // Configure internal oscillator for 配置内部振荡器// its lowest frequency RSTSRC = 0x04; // Enable missing clock detector}//-----------------------------------------------------------------------------// Port_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None////ThisfunctioninitializestheGPIO and the Crossbar 初始化GPI0和交叉开关//// Pinout://// P0.4 - UART TX (digital, push-pull)// P0.5 - UART RX (digital, open-drain)//// AIN0.2 - ADC0 input////-----------------------------------------------------------------------------void Port_Init (void){// XBR0 = 0x01; // UART0 SelectedXBR1 = 0x40; // Enable crossbar and weak pull-ups P0MDOUT |= 0xDf; // TX, LEDs = Push-pullP1MDOUT |=0x03;}//-----------------------------------------------------------------------------// UART0_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None//// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.////-----------------------------------------------------------------------------/*void delay(unsigned int time){unsigned int i;while(--time){for(i=0;i<125;i++);}}*//*void UART0_Init (void){SCON0 = 0x10; // SCON0: 8-bit variable bit rate 串口控制寄存器// level of STOP bit is ignored// RX enabled// ninth bits are zeros// clear RI0 and TI0 bits if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2);CKCON |= 0x08; // T1M = 1; SCA1:0 = xx} else if (SYSCLK/BAUDRATE/2/256 < 4) {TH1 = -(SYSCLK/BAUDRATE/2/4);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01CKCON |= 0x01;} else if (SYSCLK/BAUDRATE/2/256 < 12) {TH1 = -(SYSCLK/BAUDRATE/2/12);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00} else if (SYSCLK/BAUDRATE/2/256 < 48) {TH1 = -(SYSCLK/BAUDRATE/2/48);CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10CKCON |= 0x02;} else {while (1); // Error. Unsupported baud rate }TL1 = TH1; // Init Timer1 定时器1是用来确定有相同的波特率TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreloadTMOD |= 0x20;TR1 = 1; // START Timer1TI0 = 1; // Indicate TX0 ready}*///-----------------------------------------------------------------------------// ADC0_Init//-----------------------------------------------------------------------------//// Return Value : None// Parameters : None//// Initialize the ADC to use the temperature sensor. (non-differential)////-----------------------------------------------------------------------------void ADC0_Init (void){REF0CN |= 0x03; // Enable internal VrefADC0CN = 0x00; // Gain = 1, Unipolar mode 最后三位PGA增益=1,ADC控制寄存器ADC0CF = 0x00; // Interrupts upon SINC3 filter output ADC0配置寄存器,位4选择哪一个滤波器转换结束后使AD0INT中断标志置1,// and uses internal VREF 位2是VREF源选择位ADC0CLK = (SYSCLK/MDCLK)-1; // Generate MDCLK for modulator. 调制器时钟分频系数,由最佳调制器时钟频率反求系数// Ideally MDCLK = 2.4576MHz// Program decimation rate for desired OWRADC0DEC = ((unsigned long) MDCLK / (unsigned long) OWR / // ADC0抽取比寄存器,确定ADC输出字速率,由输出字速率反求抽取比(unsigned long) 128) - 1;ADC0BUF = 0x00; // Turn off Input BuffersADC0MUX = 0x08; // Select AIN0.2 模拟多路选择控制寄存器ADC0MD = 0x81; // Start internal calibration ADC0控制寄存器,校准和转换选择while(AD0CALC != 1); // Wait until calibration is completeEIE1 |= 0x08; // Enable ADC0 Interrupts 转换结束中断允许ADC0MD = 0x80; // Enable the ADC0 (IDLE Mode)}//-----------------------------------------------------------------------------// Interrupt Service Routines//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// ADC0_ISR//-----------------------------------------------------------------------------//// This ISR prints the result to the UART. The ISR is called after each ADC // conversion.////-----------------------------------------------------------------------------void ADC0_ISR (void) interrupt 10{unsigned long ADC_OutputVal;static double accumulator = 0;// unsigned long int i;static unsigned int measurements = 0;static unsigned int number=0;// static unsigned long average;static unsigned int flag = 1;unsigned int result=0;while(!AD0INT);AD0INT = 0;// InitLcd();ADC_OutputVal=0x00000000;ADC_OutputVal = ADC0H;ADC_OutputVal <<= 16;ADC_OutputVal += (long)ADC0L + ((long)ADC0M << 8); //ADC_OutputVal=ADC_OutputVal*0.9992+10126; accumulator += ADC_OutputVal;measurements++;if( measurements== 1){number++;if(number==1){result = accumulator / measurements;/*D1=result/10000000+0x30;D2=(result%10000000)/1000000+0x30;D3=(result%1000000)/100000+0x30;D4=(result%100000)/10000+0x30;D5=(result%10000)/1000+0x30;D6=(result%1000)/100+0x30;D7=(result%100)/10+0x30;D8=(result%10)+0x30;*/number=0;/*D1=1;D2=2;D3=3;D4=4;D5=5;D6=6;D7=7;D8=8;*//* HighData=result>>8; // 串口发送数据LowData=result; a[0]=HighData & 0X0F;a[1]=LowData;for(i=0;i<2;i++){SBUF0=a[i];while(TI0==0){};TI0=0;}*/lcd_write_char(0,0,'A'); lcd_write_char(1,0,'D'); lcd_write_char(2,0,'C'); lcd_write_char(3,0,'0'); lcd_write_char(4,0,':'); lcd_write_char(0,1,'A'); lcd_write_char(1,1,'A'); lcd_write_char(2,1,'1'); lcd_write_char(3,1,'2'); lcd_write_char(4,1,'3'); lcd_write_char(5,1,'4'); lcd_write_char(6,1,'5'); lcd_write_char(7,1,'6');lcd_write_char(8,1,'7');lcd_write_char(9,1,'8');lcd_write_char(10,1,'B');lcd_write_char(11,1,'B');delay(1000);if (flag==1){//WriteCommandLCM(0x01);InitLcd();flag=0;}}measurements = 0;accumulator=0;/* if(number==200) //采集的个数受到accumulator的限制{ average=accumulator/number;//average=average*0.9992+10126;a[0] =average>>24;a[1] =average>>16;a[2] =average>>8;a[3] =average;for(i=1;i<4;i++){SBUF0=a[i]; // 发送完成,产生中断,需要软件清零while(TI0==0){};TI0=0;}accumulator=0;number=0;}*/}}//----------------------------------------------------------------------------- // End Of File//-----------------------------------------------------------------------------。

基于51单片机1602液晶显示简易计算器设计..

基于51单片机1602液晶显示简易计算器设计..

#include<reg52.h>#include<math.h>#define uint unsigned int#define uchar unsigned char#define PI 3.141592sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;sbit led=P2^4;sbit speek=P3^7;uchar table0[]={"Welcome to use"};uchar table1[]={"made by Ms. Li"};uchar table2[]={"error"};uchar count;void main(void){uchar error=0,i,first=0,dot1,dot2,dot1_num,dot2_num,minus1,minus2;//错误标志、第一次清屏标记、小数点标记以及小数点个数负号标记、负号个数uchar Sin,Cos,Tan,ln;uchar Key_num,last_key_num; //键号uchar flag=0,equal_flag;double num1=0,num2=0,num=0,result=0,save_result; //运算符、等于符//第一个数、第二个数、计算结果uchar first_num=0,Ans=0,second_num=0; InitLcd();EA=1;ET0=1;TMOD=0X01;TH0=(65536-500)/256;TL0=(65536-500)%256;write_com(0x80+0x40+15);write_Dat('0');write_com(0x80);while(1){while(key_scan()==0xff);TR0=1;if(first==0){first=1;write_com(0x01);}Key_num=key_scan();switch(key_scan()){case 1:if(last_key_num!=Key_num){write_Dat('l');write_Dat('n');ln=1;}break;case 2:if(last_key_num!=Key_num){write_Dat('s');write_Dat('i');write_Dat('n');Sin=1;}break;case 3:if(last_key_num!=Key_num){write_Dat('c');write_Dat('o');write_Dat('s');Cos=1;}break;case 4:if(last_key_num!=Key_num){write_Dat('t');write_Dat('a');write_Dat('n');Tan=1;}break;case 5:if(last_key_num!=Key_num){write_Dat('^');flag=5;}break;case 6:write_Dat('7');num=7;break; case 7:write_Dat('8');num=8;break; case 8:write_Dat('9');num=9;break; case 9:if(last_key_num!=Key_num){write_Dat('+');flag=1;}break;case 10:if(last_key_num!=Key_num){write_Dat('T');flag=6;}break;case 11:write_Dat('4');num=4;break; case 12:write_Dat('5');num=5;break; case 13:write_Dat('6');num=6;break; case 14:if(last_key_num!=Key_num){write_Dat('-');flag=2;}break;case 15:if(last_key_num!=Key_num){if(equal_flag==1){write_com(0x01);write_com(0x80);write_Dat('A');write_Dat('n');write_Dat('s');write_Dat('=');save_result=result;}else{if(Key_num!=1&&Key_num!=2&&Key_num!=3&&Key_num!=4&&Key_num!=22&&Key_num!=23 &&Key_num!=25){write_Dat('A');write_Dat('n');write_Dat('s');if(flag==0){num1=save_result;first_num=1;}else{num2=save_result;second_num=1;}}}}break;case 16:write_Dat('1');num=1;break;case 17:write_Dat('2');num=2;break;case 18:write_Dat('3');num=3;break;case 19:if(last_key_num!=Key_num){write_Dat('*');flag=3;}break;case 21:write_Dat('0');num=0;break;case 22:if(last_key_num!=Key_num){if(flag==0){minus1++;if(minus1==1){write_Dat('-');}}else{minus2++;if(minus2==1){write_Dat('-');}}} break;case 23:if(last_key_num!=Key_num){if(flag==0){dot1++;if(dot1==1){write_Dat('.');}}else{dot2++;if(dot2==1){write_Dat('.');}}} break;case 24:if(last_key_num!=Key_num){write_Dat('/');flag=4;}break;case 25:if(last_key_num!=Key_num){write_Dat('=');equal_flag=1;}break;}if(Key_num!=1&&Key_num!=2&&Key_num!=3&&Key_num!=4&&Key_num!=15&&Key_num!=22 &&Key_num!=23&&Key_num!=25)// 第一个数{if(flag==0){num1=num1*10+num;num=0;if(dot1!=0){dot1_num++;}first_num=1;}if(flag!=0){num2=num2*10+num;num=0;if(dot2!=0){dot2_num++;}second_num=1;}}if(equal_flag==1&&first_num==1){if(dot1!=0){num1=num1/pow(10,dot1_num);dot1=0;}if(dot2!=0){num2=num2/pow(10,dot2_num);dot2=0;}if(minus1!=0){num1=num1*(-1);}if(minus2!=0){num2=num2*(-1);}if(second_num!=0){switch(flag){case 1:result=num1+num2;break;case 2:result=num1-num2;break;case 3:result=num1*num2;break;case 4:if(num2!=0){result=num1/num2;}else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}error=1;} break;case 5: result=pow(num1,num2);break;case 6: result=pow(num1,1/num2);break;}}else if(second_num==0&&Sin==0&&Cos==0&&Tan==0&&ln==0) result=num1;else if(second_num==0&&(Sin==1||Cos==1||Tan==1||ln==1)) {if(Sin==1)result=sin(num1/180*PI)+0.005;if(Cos==1)result=cos(num1/180*PI)+0.005;if(Tan==1)result=tan(num1/180*PI)+0.005;if(ln==1){if(num1>0)result=log(num1)+0.005;else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}error=1;}}}if(error!=1)display(result);}// 清零if(Key_num==20){num1=num2=result=0;flag=equal_flag=0;error=0;first=0;dot1_num=dot2_num=0;minus1=0;minus2=0;first_num=0,second_num=0;Sin=Cos=Tan=ln=0;write_com(0x01);write_com(0x80+0x40+15);write_Dat('0');}last_key_num=Key_num;while(key_scan()!=0xff);}}void time0() interrupt 1{TH0=(65536-600)/256;TL0=(65536-600)%256;count++;speek=!speek;if(count>50){TR0=0;count=0;}}void delay(uint x){uchar y;while(x--)for(y=0;y<120;y++);}void write_com(unsigned char c) {RS=0;RW=0;EN=1;delay(5);P0=c;EN=0;}void write_Dat(unsigned char c) {RS=1;RW=0;EN=1;delay(5);P0=c;EN=0;}void InitLcd(){write_com(0x38); //display modewrite_com(0x06); // write_com(0x0c); // write_com(0x01); // } 显示光标挪动地点显示开及光标设置显示清屏uchar key_scan(){uchar key_num=0xff;uint temp;P3=0x03;P1=0xe0;temp=(P3<<8)|P1;if((temp&0x03e0)!=0x03e0){delay(10);if((temp&0x03e0)!=0x03e0){// 第一行P3=0x03;P1=0xfe;temp=(P3<<8)|P1;switch(temp){case 0x03de:key_num=1; break;case 0x03be:key_num=2; break;case 0x037e:key_num=3; break;case 0x02fe:key_num=4; break;case 0x01fe:key_num=5; break;}//第二行P3=0x03;P1=0xfd;temp=(P3<<8)|P1;switch(temp){case 0x03dd:key_num=6; break;case 0x03bd:key_num=7; break;case 0x037d:key_num=8; break;case 0x02fd:key_num=9; break;case 0x01fd:key_num=10; break;}//第三行P3=0x03;P1=0xfb;temp=(P3<<8)|P1;switch(temp){case 0x03db:key_num=11; break;case 0x03bb:key_num=12; break;case 0x037b:key_num=13; break;case 0x02fb:key_num=14; break;case 0x01fb:key_num=15; break;}//第四行P3=0x03;P1=0xf7;temp=(P3<<8)|P1;switch(temp){case 0x03d7:key_num=16; break;case 0x03b7:key_num=17; break;case 0x0377:key_num=18; break;case 0x02f7:key_num=19; break;case 0x01f7:key_num=20; break;}P3=0x03;//第五行P1=0xef;temp=(P3<<8)|P1;switch(temp){case 0x03cf:key_num=21; break;case 0x03af:key_num=22; break;case 0x036f:key_num=23; break;case 0x02ef:key_num=24; break;case 0x01ef:key_num=25; break;}}}return key_num;}void display(double Data){uchar xs=0,fs=0,i;if(Data<0){fs=1;Data=Data*(-1);}if(Data>(long)Data){xs=1;}if(Data<10)//0~9{if(xs==1){Data=Data*100;write_com(0x80+0x40+11);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+14);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data+'0');}}else if(Data<100)//10~99{if(xs==1){Data=Data*100;write_com(0x80+0x40+10);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000+'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+13);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10+'0');write_Dat((long)Data%10+'0');}}else if(Data<1000)//100~999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+9);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+12);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<10000)//1000~9999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+8);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100000+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+11);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<100000)//10000~99999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+7);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000000+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+10);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000+'0');write_Dat((long)Data/1000%10+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<1000000) //100000~999999{if(xs==1){Data=Data*100;write_com(0x80+0x40+7);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000000+'0');write_Dat((long)Data/1000000%10+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');}else if(xs==0){write_com(0x80+0x40+9);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100000+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}}}。

51单片机控制1602LCD显示程序

51单片机控制1602LCD显示程序

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();}}。

51单片机计算器1602显示程序

51单片机计算器1602显示程序
{
delay_jsq(5);
if(P2!=0xfb)
{
if(P2!=0xfb)
{
temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=8;
break;
case 0xd0:num=9;
break;
case 0xb0:num=10;
break;
case 0x70:num=11;
case 0x70:num=7;
break;
}
}
while(P2!=0xfd);
if(j!=0)
{
write_lcd1602(0x01,0);
delay(1);
j=0;
}
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
{
if(flag1==0)//没有按过符号键
break;
}
}
}
}
void main()
{
ini_lcd1602();
while(1)
{
keyscan_4_4();
}
}
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
num_1=0;
i=0;
j=0;
a=0; //第一个参与运算的数
b=0; //第二个参与运算的数
c=0;
flag1=0; //flag1表示是否有符号键按下,
fuhao=0; // fuhao表征按下的是哪个符号

单片机设计_按键顺序控制加减计数(1602_液晶显示)_程序

单片机设计_按键顺序控制加减计数(1602_液晶显示)_程序

#include<reg51.h>#include<intrins.h>#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液晶显示 电子时钟【带闹铃和整点报时】

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
{
write_date(week6[num]);
delay1();
}
};
break;
}
}
void display() //显示时间子程序
{
write_week(week);
write_ymd(3,year);
write_ymd(6,months);
write_ymd(9,day);
write_sfm(0,shi);
write_sfm(3,fen);
write_sfm(6,miao);
}
void display_1() //显示闹钟子程序
{
write_week(week_1);
write_ymd(3,year1);
write_ymd(6,months1);
write_ymd(9,day1);
write_sfm(0,shi1);
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
}
void write_week(uchar add) //周几显示
{
switch(add)
{
case 0:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
{
write_date(week3[num]);
delay1();
}
};
break;
case 4:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)

DS18B20万年历温度时间按键控制1602显示51单片机程序

DS18B20万年历温度时间按键控制1602显示51单片机程序

uint year=2015;
uchar month=2;
uchar day=27,daytemp;
uchar weekdayflag=5;
char H=12;
char M=0;
char S=0;
uchar displaybuf[9];
uchar code cdis1[20]= {"0123456789:.C- "};
sbit LCD_RS = P2^0; //LCD1602数据/命令选择端
sbit LCD_RW = P2^1; //LCD1602读/写选择端
sbit LCD_EN = P2^2; //LCD1602使能端
sbit DQ=P3^3; //DS18B20信号端
delayNOP();
}
//液晶初始化
void lcd_init() //1602液晶初始化函数
{
delay(5);
write_control(0x38); //16*2显示,5*7点阵,8位数据
**********************************************************/
void delayNOP()
{
_nop_(); //一个机器周期1us延时
_nop_();
_nop_();
_nop_();
_nop_();
delayNOP(); //5us延时
result = (bit)(P0&0x80); //确保STA7为0,说明为“闲”状态,为1位“忙”操作;(bit)(P0&0x80)为强制类型转换
LCD_EN = 0; //读取数据结束之后,复位执行使能操作

液晶上显示时钟并带按键调整时和分(1602)

液晶上显示时钟并带按键调整时和分(1602)

液晶上显示时钟并带按键调整时和分说明: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与矩阵按键实现3位数的加减乘除有清屏和清数

lcd1602与矩阵按键实现3位数的加减乘除有清屏和清数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LCD_Clear(void)
{
LcdWriteCom(0x01);
{
sign++;
flag=asc_code[KeyValue];
LcdWriteData(asc_code[KeyValue]);
}
else if(asc_code[KeyValue]=='=')
case '+':a=a+b; break;
case '-':a=a-b;break;
case '*':a=a*b;break;
case '/':a=a/b;break;
LcdWriteData(asc_code[shi]);
LcdWriteData(asc_code[ge]);
}
void main(void)
{
unsigned char sign=0,flag,i,j;
int a,b;
LcdInit();
KeyState=0;
{
sign=0;
LcdWriteCom(0xcc);
LcdWriteData(asc_code[KeyValue]);
switch(flag)
{
void Delay10ms(void) //误差 0us
{
unsigned char a,b,c;

51单片机实现LCD1602显示定时计数器(自己整理的)

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]);}}。

基于51单片机的lcd1602液晶显示的计算器

基于51单片机的lcd1602液晶显示的计算器

基于51单片机的lcd 1602液晶显示的计算器/**************************************************************** 阿斌独家制作:计算器,1602液晶显示可计算10以下数加减乘除可连续运算,最大显示结果数值65536*****************************************************************/ 键盘设置:液晶初始显示:运算显示:主程序:#include<reg52.h>#include <intrins.h> #define uint unsigned int #define uchar unsigned char sbit lcden=P2^2;sbit lcdrw=P2^1;sbit lcdrs=P2^0;uchar num,temp,jia=0,jian=0,cheng=0,chu=0,qing=0;uint key,key1,shu;uchar fuhao,flag1,flag=0; uchar table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x0}; void delay(uint z) {uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }bit lcd_bz(){bit result;lcdrs=0;lcdrw=1;lcden=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result; }void write_com(uchar com){while(lcd_bz());lcdrs=0;lcden=0;lcdrw=0;P0=com;delay(5);lcden=1;delay(5);lcden=0; }void write_date(uchar date) {while(lcd_bz());lcdrs=1;lcden=0;lcdrw=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void lcd_init() {lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01); }void keyscan() {P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xee:key=1;num=0;break; case 0xde:key=2;num=0;break; case 0xbe:key=3;num=0;break; case 0x7e:num=1;break; //加号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xed:key=4;num=0;break; case 0xdd:key=5;num=0;break; case 0xbd:key=6;num=0;break; case 0x7d:num=2;break; //减号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xeb:key=7;num=0;break; case 0xdb:key=8;num=0;break; case 0xbb:key=9;num=0;break; case 0x7b:num=3;break; //乘号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xe7:key=0;num=0;break; case 0xd7:num=6;break; //清除case 0xb7:num=5;break; //等于号case 0x77:num=4;break; //除号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}}void display0(uint shu) { uint ge;ge=shu;write_date(0x30+ge); } void display1(uint shu) { uint shi,ge;shi=shu/10;ge=shu%10;write_date(0x30+shi); write_date(0x30+ge); } void display2(uint shu) { uint bai,shi,ge;bai=shu/100;shi=shu%100/10;ge=shu%10;write_date(0x30+bai); write_date(0x30+shi); write_date(0x30+ge); } void display3(uint shu) {uint qian,bai,shi,ge;qian=shu/1000;bai=shu%1000/100;shi=shu%100/10;ge=shu%10;write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge); }void display4(uint shu) {uint wan,qian,bai,shi,ge;wan=shu/10000;qian=shu%10000/1000;bai=shu%1000/100;shi=shu%100/10;ge=shu%10;write_date(0x30+wan);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge); }void display_key1(uint result) {if(flag1==1){write_com(0x01);flag1=0;}shu=result;write_com(0x80);if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000) display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result);}void dis_key(result){if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000)display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result);}void display_key(uint result) { if(shu<10){write_com(0x80+2);dis_key(result);}if(shu>=10&&shu<100){write_com(0x80+3);dis_key(result);}if(shu>=100&&shu<1000){write_com(0x80+4);dis_key(result);}if(shu>=1000&&shu<10000){write_com(0x80+5);dis_key(result);}if(shu>=10000){write_com(0x80+6);dis_key(result);}}void display_fuhao(){switch(fuhao){case 1: write_date(0x2b);break; case 2: write_date(0x2d);break; case 3: write_date(0x2a);break; case 4: write_date(0x2f);break; }fuhao=0;}void fuhao_pan(){if(flag1==1){flag1=0;write_com(0x01);write_com(0x80+1); display_fuhao();}if(shu<10)write_com(0x80+1);if(shu>=10&&shu<100) write_com(0x80+2);if(shu>=100&&shu<1000) write_com(0x80+3);if(shu>=1000&&shu<10000) write_com(0x80+4);if(shu>=10000)write_com(0x80+5); display_fuhao();flag=1;}void fuhao_deng(){write_com(0x80+0x40); write_date(0x3d);flag1=1;flag=0;}void display_result(uint result) {write_com(0x80+0x40+1);if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000) display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result); }void jia1(){jia=1;jian=cheng=chu=qing=0;key1=key;fuhao=1;fuhao_pan();}void jian1(){jian=1;jia=cheng=chu=qing=0; key1=key;fuhao=2;fuhao_pan(); }void cheng1() {cheng=1;jia=jian=chu=qing=0; key1=key;fuhao=3;fuhao_pan(); }void chu1() {chu=1;jia=jian=cheng=qing=0; key1=key;fuhao=4;fuhao_pan();}void qing1() {qing=1;jia=jian=cheng=chu=0; key1=key=0; }void deng1() {if(jia)key=key1+key;if(jian)key=key1-key;if(cheng)key=key1*key;if(chu)key=key1/key;fuhao_deng();display_result(key);jia=jian=cheng=chu=qing=0;}void deal(){switch(num){case 0:{switch(flag){case 0: display_key1(key);break; case 1: display_key(key);break; }} break;case 1: jia1();break;case 2: jian1();break; case 3: cheng1();break; case 4: chu1();break; case 5: deng1();break; case 6: qing1();break; }}void main(){lcd_init();while(1){keyscan();deal();}}。

STC51单片机开发板计算器LCD1602显示浮点计算设计报告

STC51单片机开发板计算器LCD1602显示浮点计算设计报告

嵌入式系统原理及应用课程设计报告姓名:学号:指导老师:目录引言 (3)第一章硬件介绍 (4)1.1单片机介绍 (4)1.2 设计所用开发板的介绍 (5)1.3 LCD1602的原理及其应用 (7)1.3.1开发板硬件连接关系 (7)1.3.2液晶屏LCD1602的功能及应用 (8)1.3.31602LCD的指令说明及时序 (9)1.3.4 1602LCD的RAM地址映射及标准字库表 (11)1.4开发板矩阵键盘原理及应用 (12)第二章设计思路、仿真及调试 (15)2.1 设计方法 (15)2.2 硬件简介 (15)2.3 软件设计 (15)2.3.1 矩阵键盘 (15)2.3.2 LCD1602 (22)第三章设计结果 (24)第四章设计总结 (27)附录 (28)引言目前单片机渗透到我们生活的各个领域.几乎很难找到哪个领域没有单片机的踪迹。

导弹的导航装置.飞机上各种仪表的控制.计算机的网络通讯与数据传输.工业自动化过程的实时控制和数据处理.广泛使用的各种智能IC卡.民用豪华轿车的安全保障系统.录像机、摄像机、全自动洗衣机的控制.以及程控玩具、电子宠物等等.这些都离不开单片机。

更不用说自动控制领域的机器人、智能仪表、医疗器械了。

因此.单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。

单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域.大致可分如下几个范畴:(1)在智能仪器仪表上的应用(2)在工业控制中的应用(3)在家用电器中的应用(4)在计算机网络和通信领域中的应用(5)单片机在医用设备领域中的应用(6)在各种大型电器中的模块化应用(7)单片机在汽车设备领域中的应用此外.单片机在工商.金融.科研、教育.国防航空航天等领域都有着十分广泛的用途。

随着智能化的逐步提高.单片机在我们生活中得到了越来越广泛的应用.其是一种集成在电路芯片.是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。

STM32F103C8T6控制1602液晶显示

STM32F103C8T6控制1602液晶显示
Delay(20000);
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;

51单片机控制LCD液晶1602源代码

51单片机控制LCD液晶1602源代码
void Lcd1602_Clear_Line(unsigned char line);
void Lcd1602_Clear_All(void);
void Lcd1602_Demo1(void);
void Lcd1602_Demo2(void);
void Delay_ms(unsigned char second);
if(++row==3)
return;
else
{
switch(row)//这种结构保持以后升级到多行显示液晶
_nop_();
LCD_EN=HIGH ;
_nop_();
LCD_EN=LOW;
LCD_DATA_PORT=0xFF; //prevent port is 0.
}
//===========================
case 2:Lcd1602_Write_Command(0x80+0x40);break; //将数据地址指针定位到第二行
default: break;
}
}
//==================================================
{
while(1)
{
Lcd1602_Demo1();
// Lcd1602_Demo2();
}
}
void Lcd1602_Ini(void)
{
Delay_ms(20);
Lcd1602_Write_Command_Nocheck(0x38);//设定LCD为16*2显示,5*7点阵,8位数据接口
{
Lcd1602_Write_String(row,column," ");

Lcd1602简易计算器

Lcd1602简易计算器

Lcd1602显示实现千位数加减乘除用4*4矩阵按键输入0~9 +,-,*,/,=,和清除建#include<reg51.h>#define temp P3sbit RS=P0^0;sbit RW=P0^1;sbit E =P0^2;unsigned char key_num;unsigned char lcd_tab3[16]=" ";unsigned char code lcd_tab4[]="0123456789+-*/=";unsigned char lcd_tab5[16]=" ";unsigned char lcd_tab6[]=" ";unsigned char lcd_tab7[]=".";int a,b,c,d,m,i;void decide();long int key_cnt=0,key_number,key_number1;unsigned char flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;long int result, result1, result2, result3, result4,result5, result6, result7, result8;int decimal0,decimal1;delay_nms(unsigned int i){unsigned int j;for(;i!=0;i--){for(j=0;j<61;j++);}}key_scan(void){unsigned char a;temp=0xf0;if(temp!=0xf0){delay_nms(10);{if(temp!=0xf0)switch(temp){case 0xe0 :key_num= 0; break;case 0xd0 :key_num= 1; break;case 0xb0 :key_num= 2; break;case 0x70 :key_num= 3; break;}temp=0x0f;switch(temp){case 0x0e :key_num=key_num; break;case 0x0d :key_num= key_num+4; break;case 0x0b :key_num= key_num+8; break;case 0x07 : key_num=key_num+12; break;default :break;}while((a<50)&&( temp!=0x0f)){delay_nms(1);a++;}temp=0xf0;}}return (key_num);}void write_com(char cod){E=0;RS=0;RW=0;E=1;delay_nms(1);P2=cod;E=0;delay_nms(1);}void write_data(char pat){E=0;RS=1;RW=0;E=1;delay_nms(1);P2=pat;E=0;delay_nms(1);}void write_clean(){write_com(0x38);write_com(0x01);write_com(0x06);write_com(0x0c);}void input(){unsigned char i,x;write_com(0x80);for(i=0;i<16;i++){write_data(lcd_tab3[i]);delay_nms(1);}write_com(0xc0);{for(x=0;x<16;x++){write_data(lcd_tab5[x]);delay_nms(1);}}}void display(){if(flag5==0){lcd_tab5[0]=lcd_tab4[key_num];lcd_tab5[2]=lcd_tab4[result7];lcd_tab5[3]=lcd_tab4[result6];lcd_tab5[4]=lcd_tab4[result5];lcd_tab5[5]=lcd_tab4[result4];lcd_tab5[6]=lcd_tab4[result3];lcd_tab5[7]=lcd_tab4[result2];lcd_tab5[8]=lcd_tab4[result1];if((decimal0!=0)||(decimal1!=0)){lcd_tab5[9]=lcd_tab7[0];lcd_tab5[10]=lcd_tab4[decimal1];lcd_tab5[11]=lcd_tab4[decimal0];}i=0;decide();}else{lcd_tab5[0]=lcd_tab4[key_num];lcd_tab5[1]=lcd_tab4[11];lcd_tab5[2]=lcd_tab4[result8];lcd_tab5[3]=lcd_tab4[result7];lcd_tab5[4]=lcd_tab4[result6];lcd_tab5[5]=lcd_tab4[result5];lcd_tab5[6]=lcd_tab4[result4];lcd_tab5[7]=lcd_tab4[result3];lcd_tab5[8]=lcd_tab4[result2];lcd_tab5[9]=lcd_tab4[result1];i=1;decide();}}void decide(){if(lcd_tab5[1+i]==lcd_tab4[0]){lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab5[10];lcd_tab5[10]=lcd_tab5[11];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab5[10];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]){lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab6[0];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab6[0];lcd_tab5[6+i]=lcd_tab6[0];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];}}}}}}}}}void lcd_shiftl(void){lcd_tab3[0]=lcd_tab3[1];lcd_tab3[1]=lcd_tab3[2];lcd_tab3[2]=lcd_tab3[3];lcd_tab3[3]=lcd_tab3[4];lcd_tab3[4]=lcd_tab3[5];lcd_tab3[5]=lcd_tab3[6];lcd_tab3[6]=lcd_tab3[7];lcd_tab3[7]=lcd_tab3[8];lcd_tab3[8]=lcd_tab3[9];lcd_tab3[9]=lcd_tab3[10];lcd_tab3[10]=lcd_tab3[11];lcd_tab3[11]=lcd_tab3[12];lcd_tab3[12]=lcd_tab3[13];lcd_tab3[13]=lcd_tab3[14];lcd_tab3[14]=lcd_tab3[15];lcd_tab3[15]=lcd_tab4[key_num];}void displasis(){int i;for(i=0;i<16;i++){lcd_tab3[i]=lcd_tab6[0];}for(i=0;i<16;i++){lcd_tab5[i]=lcd_tab6[0];}key_cnt=key_number=key_number1=0;a=b=c=d=0;result=result1=result2=result3=result4=result5=result6=result7=result8=0;flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;decimal0=0;decimal1=0;}void main(){while(1){write_clean();input();m=1;while(m){P3=0xf0;if(P3!=0xf0){m=0;}}P3=0xf0;if(P3!=0xf0){key_scan();if(key_num<=9){if(key_cnt<4){switch(key_cnt){case 0: a=key_num ; break;case 1: a=a*10 ;b=key_num; a=a+b; break;case 2: a=a*10 ;c=key_num; a=a+c; break;case 3: a=a*10 ;d=key_num; a=a+d; break;}lcd_shiftl();key_cnt++;}while(P3!=0xf0){;}}if(key_num==10)//加法{flag1=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==11)//减法{flag2=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==12)//乘法{flag3=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==13)//除法{flag4=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==14){while(P3!=0xf0){;}key_number1=a;a=b=c=d=0;key_cnt=0;if((flag1==1)&&(key_number1!=0)){result=key_number+key_number1;//加法运算result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag2==1)&&(key_number1!=0))//减法运算{result=key_number-key_number1;if(result<0){result=key_number1-key_number;flag5=1;}result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag3==1)&&(key_number1!=0)){result=key_number*key_number1;//乘法运算result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag4==1)&&(key_number1!=0))//除法运算{result=key_number/key_number1;decimal0=((key_number*100)/key_number1)%10;//小数各位decimal1=((key_number*100)/key_number1)/10%10;//小数十位result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}}if(key_num==15){while(P3!=0xf0){;}displasis();}}}}。

(完整word版)1602液晶时钟程序(51单片机)

(完整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代码根目录下。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_IO P2
sbit 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--;
}
}
}。

相关文档
最新文档