|
在lcd1602中显示不出来,连初始化的0都显示不出来 不知道是程序有问题还是仿真图有问题,各位大神帮帮忙看看 困扰好久 没人指导 很难受 睡不着
- #include<reg52.h>
- sbit key0_in = P3^4;
- sbit key1_in = P3^5;
- sbit key2_in = P3^6;
- sbit key3_in = P3^7;
- sbit key0_out = P3^0;
- sbit key1_out = P3^1;
- sbit key2_out = P3^2;
- sbit key3_out = P3^3;
- unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
- { '1', '2', '3', 0x26 }, //数字键1、数字键2、数字键3、向上键
- { '4', '5', '6', 0x25 }, //数字键4、数字键5、数字键6、向左键
- { '7', '8', '9', 0x28 }, //数字键7、数字键8、数字键9、向下键
- { '0', 0x1B, 0x0D, 0x27 } //数字键0、ESC键、 回车键、 向右键
- };
- unsigned char pdata KeySta[4][4] = { //全部矩阵按键的当前状态
- {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
- };
- extern unsigned char zfc_date(unsigned char *zfc,signed long date);
- extern void numkeyaction(unsigned char n);
- extern void operkeyaction(unsigned char type);
- extern void reset();
- extern void getresult();
- extern void lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc);
- void keyaction(unsigned char keycode) //加减乘除函数
- {
- if((keycode >= '0') && (keycode <= '9'))
- {
- numkeyaction(keycode -'0');
- }
- if(keycode == 0x26)
- {
- operkeyaction(0);
- }
- else if(keycode == 0x28)
- {
- operkeyaction(1);
- }
- else if(keycode == 0x25)
- {
- operkeyaction(2);
- }
- else if(keycode == 0x27)
- {
- operkeyaction(3);
- }
- else if(keycode == 0x0D)
- {
- getresult();
- }
- else if(keycode == 0x1B)
- {
- reset();
- lcdshowdate(15,1,"0");
- }
- }
- void keydriver() //按键扫描
- {
- unsigned char i;
- unsigned char j;
- static unsigned char backup[4][4]=
- {
- {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
- };
- for(i=0;i<4;i++)
- {
- for(j=0;j<4;j++)
- {
- if(backup[i][j]!= KeySta[i][j])
- {
- if(KeySta[i][j]!= 0)
- {
- keyaction(KeyCodeMap[i][j]);
- }
- backup[i][j] = KeySta[i][j];
- }
-
- }
- }
- }
- void keyscanf()
- {
- unsigned char i;
- static unsigned char keyout=0;
- static unsigned char keybuf[4][4]={
- {0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}
- };
- keybuf[keyout][0]= (keybuf[keyout][0])<< 1 | key0_in;
- keybuf[keyout][1]= (keybuf[keyout][1])<< 1 | key1_in;
- keybuf[keyout][2]= (keybuf[keyout][2])<< 1 | key2_in;
- keybuf[keyout][3]= (keybuf[keyout][3])<< 1 | key3_in;
- for(i=0;i<4;i++)
- {
- if((keybuf[keyout][i] & 0x0f )==0x00)
- {
- KeySta[keyout][i] = 0;
- }
- else if ((keybuf[keyout][i] & 0x0f) == 0x0f)
- {
- KeySta[keyout][i] = 1;
- }
-
- }
- keyout++;
- keyout &= 0x03;
- switch (keyout)
- {
- case 0: key3_out =1; key0_out =0; break;
- case 1: key0_out =1; key1_out =0; break;
- case 2: key1_out =1; key2_out =0; break;
- case 3: key2_out =1; key3_out =0; break;
- default: break;
- }
- }
- /****************************************************lcd配置*******************************************************//
- #include<reg52.h>
- #define lcddb P0
- sbit rw=P2^1;
- sbit rs=P2^0;
- sbit en=P2^2;
- void delay(unsigned int z)
- {
- unsigned int x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void lcdwriteready() //检测是否忙状态
- {
- unsigned char zfc;
- lcddb=0xff;
- rw=1;
- rs=0;
- do
- {
- en=1;
- zfc=lcddb;
- en=0;
- }
- while(zfc & 0x80);
- }
- void lcdwritecom(unsigned char com) //写指令
- {
- lcdwriteready();
- rs=0;
- rw=0;
- lcddb=com;
- delay(10);
- en=1;
- delay(10);
- en=0;
- delay(10);
- }
- void lcdwritedate(unsigned char date) //写数据
- {
- lcdwriteready();
- rs=1;
- rw=0;
- lcddb=date;
- delay(10);
- en=1;
- delay(10);
- en=0;
- delay(10);
- }
- void lcdInit() //初始化lcd
- {
- lcdwritecom(0x01);
- lcdwritecom(0x38);
- lcdwritecom(0x0C);
- lcdwritecom(0x06);
- }
- void lcd_add(unsigned char x,unsigned char y) //设置lcd输入起始地址
- {
- unsigned char add;
- if(y==0)
- add = 0x00 + x;
- else
- add = 0x40 + x;
- lcdwritecom(add|0x80);
- }
- void lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc) //将转换的字符指针传入lcd
- {
- lcd_add(x,y);
- while(*zfc != '\0')
- {
- lcdwritedate(*zfc++);
- }
- }
- void lcdareaclear(unsigned char x,unsigned char y,unsigned char changdu) //局部清除
- {
- lcd_add(x,y);
- while(changdu--)
- {
- lcdwritedate(' ');
- }
- }
- void lcdallclear() //全屏清除
- {
- lcdwritecom(0x01);
- }
- /*************************************************main.c函数***********************************************************/
- #include<reg52.h>
- unsigned char num1=0;
- unsigned char num2=0;
- unsigned char step=0;
- unsigned char oper = 0;
- unsigned char T0RH=0;
- unsigned char T0RL=0;
- unsigned char result=0;
- void ConfigTimer0(unsigned int ms);
- extern void lcdInit();
- extern void lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc); //将转换的字符指针传入lcd
- extern void lcdareaclear(unsigned char x,unsigned char y,unsigned char changdu); //局部清除
- extern void lcdallclear(); //全屏清除
- extern void keyaction(unsigned char keycode);
- extern void keydriver();
- extern void keyscanf();
- void main()
- {
- EA = 1; //开总中断
- ConfigTimer0(1); //配置T0定时1ms
- lcdInit(); //初始化液晶
- lcdshowdate(15, 1, "0"); //初始显示一个数字0
- while (1)
- {
- keydriver(); //调用按键驱动
- }
- }
- unsigned char zfc_date(unsigned char *zfc,signed long date) //数字转字符串
- {
- signed long i = 0;
- unsigned char changdu = 0;
- unsigned char buf[12];
- if(date < 0)
- {
- date = -date;
- *zfc++ = '-';
- changdu++;
- }
- do
- {
- buf[i++]= date %10;
- date /= 10;
- }
- while(date > 0);
- changdu += i;
- while(i-- > 0)
- {
- *zfc++ = buf[i] + '0';
- }
- *zfc = '\0';
-
- return changdu;
- }
- void showoper(unsigned char y, unsigned char type) //加减乘除函数
- {
- switch(type)
- {
- case 0: lcdshowdate( 0 , y , "+");
- case 1: lcdshowdate( 0 , y , "-");
- case 2: lcdshowdate( 0 , y , "*");
- case 3: lcdshowdate( 0 , y , "/");
- default: break; //
- }
- }
- void reset() //清除
- {
- num1 = 0;
- num2 = 0;
- step = 0;
- lcdallclear();
- }
- void numkeyaction(unsigned char n) //输入
- {
- unsigned char changdu = 0;
- unsigned char zfc[12];
- if(step > 1)
- {
- reset();
- }
- if(step == 0)
- {
- num1 = num1*10 + n;
- changdu = zfc_date(zfc,num1); //
- lcdshowdate(16-changdu,1,zfc);
- }
- else
- {
- num2 = num2*10 + n;
- changdu = zfc_date(zfc,num2); //
- lcdshowdate(16-changdu,1,zfc);
- }
- }
- void operkeyaction(unsigned char type) //输入
- {
- unsigned char changdu;
- unsigned char zfc[12];
- if(step == 0)
- {
- changdu = zfc_date(zfc,num1);
- lcdareaclear(0,0,16-changdu);
- lcdshowdate(16-changdu,0,zfc);
- showoper(1,type);
- lcdareaclear(1,1,14);
- lcdshowdate(15,1,"0"); //
- oper = type; //
- step = 1;
- }
- }
- void getresult() //结果
- {
- unsigned char changdu;
- unsigned char zfc[12];
- if(step == 1)
- {
- step = 2;
- switch(oper)
- {
- case 0: result = num1 + num2; break;
- case 1: result = num1 - num2; break;
- case 2: result = num1 * num2; break;
- case 3: result = num1 / num2; break;
- default: break;
- }
- changdu = zfc_date(zfc,num2);
- showoper(0,oper);
- lcdareaclear(1,0,16-changdu-1);
- lcdshowdate(16-changdu,0,zfc);
- changdu = zfc_date(zfc,result);
- lcdshowdate(0,1,"=");
- lcdareaclear(1,1,16-changdu-1);
- lcdshowdate(16-changdu,1,zfc);
- }
- }
- /* 配置并启动T0,ms-T0定时时间 */
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp; //临时变量
- tmp = 11059200 / 12; //定时器计数频率
- tmp = (tmp * ms) / 1000; //计算所需的计数值
- tmp = 65536 - tmp; //计算定时器重载值
- tmp = tmp + 12; //补偿中断响应延时造成的误差
- T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
- T0RL = (unsigned char)tmp;
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x01; //配置T0为模式1
- TH0 = T0RH; //加载T0重载值
- TL0 = T0RL;
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- }
- /* T0中断服务函数,执行按键扫描 */
- void InterruptTimer0() interrupt 1
- {
- TH0 = T0RH; //重新加载重载值
- TL0 = T0RL;
- keyscanf(); //按键扫描
- }
复制代码 |
|