找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2505|回复: 2
收起左侧

51单片机计算器无法仿真成功 求各位大神指导

[复制链接]
ID:169921 发表于 2017-3-11 18:05 | 显示全部楼层 |阅读模式

仿真图

仿真图


在lcd1602中显示不出来,连初始化的0都显示不出来  不知道是程序有问题还是仿真图有问题,各位大神帮帮忙看看  困扰好久  没人指导  很难受  睡不着

  1. #include<reg52.h>

  2. sbit key0_in = P3^4;
  3. sbit key1_in = P3^5;
  4. sbit key2_in = P3^6;
  5. sbit key3_in = P3^7;

  6. sbit key0_out = P3^0;
  7. sbit key1_out = P3^1;
  8. sbit key2_out = P3^2;
  9. sbit key3_out = P3^3;
  10. unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
  11.     { '1',  '2',  '3', 0x26 }, //数字键1、数字键2、数字键3、向上键
  12.     { '4',  '5',  '6', 0x25 }, //数字键4、数字键5、数字键6、向左键
  13.     { '7',  '8',  '9', 0x28 }, //数字键7、数字键8、数字键9、向下键
  14.     { '0', 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键
  15. };
  16. unsigned char pdata KeySta[4][4] = {  //全部矩阵按键的当前状态
  17.     {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
  18. };

  19. extern unsigned char zfc_date(unsigned char *zfc,signed long date);
  20. extern void numkeyaction(unsigned char n);
  21. extern void operkeyaction(unsigned char type);
  22. extern void reset();
  23. extern void getresult();
  24. extern void  lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc);



  25. void keyaction(unsigned char keycode)  //加减乘除函数
  26. {
  27.         if((keycode >= '0') && (keycode <= '9'))
  28.         {
  29.                 numkeyaction(keycode -'0');
  30.         }

  31.         if(keycode == 0x26)
  32.         {
  33.                 operkeyaction(0);
  34.         }
  35.         else if(keycode == 0x28)
  36.         {
  37.                 operkeyaction(1);
  38.         }
  39.         else if(keycode == 0x25)
  40.         {
  41.                 operkeyaction(2);
  42.         }
  43.         else if(keycode == 0x27)
  44.         {
  45.                 operkeyaction(3);
  46.         }
  47.         else if(keycode == 0x0D)
  48.         {
  49.                 getresult();        
  50.         }
  51.         else if(keycode == 0x1B)
  52.         {
  53.                 reset();
  54.                 lcdshowdate(15,1,"0");
  55.         }
  56. }


  57. void keydriver()                           //按键扫描
  58. {
  59.         unsigned char i;
  60.         unsigned char j;
  61.         static unsigned char  backup[4][4]=
  62. {
  63.         {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
  64. };

  65.         for(i=0;i<4;i++)
  66.         {
  67.                 for(j=0;j<4;j++)
  68.                 {
  69.                         if(backup[i][j]!= KeySta[i][j])
  70.                         {
  71.                                 if(KeySta[i][j]!= 0)
  72.                                 {
  73.                                         keyaction(KeyCodeMap[i][j]);
  74.                                 }
  75.                                   backup[i][j] = KeySta[i][j];
  76.                         }        
  77.                
  78.                 }
  79.         }

  80. }

  81. void keyscanf()
  82. {
  83.         unsigned char i;
  84.         static unsigned char keyout=0;
  85.         static unsigned char keybuf[4][4]={
  86.         {0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}
  87.         };

  88.         keybuf[keyout][0]= (keybuf[keyout][0])<< 1 | key0_in;
  89.         keybuf[keyout][1]= (keybuf[keyout][1])<< 1 | key1_in;
  90.         keybuf[keyout][2]= (keybuf[keyout][2])<< 1 | key2_in;
  91.         keybuf[keyout][3]= (keybuf[keyout][3])<< 1 | key3_in;

  92.         for(i=0;i<4;i++)
  93.         {
  94.                 if((keybuf[keyout][i] & 0x0f )==0x00)
  95.                 {
  96.                         KeySta[keyout][i] = 0;
  97.                 }
  98.                 else if        ((keybuf[keyout][i] & 0x0f) == 0x0f)
  99.                 {
  100.                         KeySta[keyout][i] =        1;
  101.                 }
  102.                                 
  103.         }
  104.         keyout++;
  105.         keyout &= 0x03;
  106.         switch (keyout)
  107.         {
  108.                 case 0:        key3_out =1; key0_out =0; break;
  109.                 case 1:        key0_out =1; key1_out =0; break;
  110.                 case 2:        key1_out =1; key2_out =0; break;
  111.                 case 3:        key2_out =1; key3_out =0; break;
  112.                 default: break;
  113.         }
  114. }
  115. /****************************************************lcd配置*******************************************************//
  116. #include<reg52.h>
  117. #define  lcddb P0
  118. sbit rw=P2^1;
  119. sbit rs=P2^0;
  120. sbit en=P2^2;
  121. void delay(unsigned int z)
  122. {
  123.         unsigned int x,y;
  124.         for(x=z;x>0;x--)
  125.                 for(y=110;y>0;y--);
  126. }
  127. void lcdwriteready()         //检测是否忙状态
  128. {        
  129.         unsigned char zfc;
  130.         lcddb=0xff;
  131.         rw=1;
  132.         rs=0;
  133.         do
  134.         {
  135.                 en=1;
  136.                 zfc=lcddb;
  137.                 en=0;
  138.         }
  139.         while(zfc & 0x80);
  140. }

  141. void lcdwritecom(unsigned char com)                   //写指令
  142. {
  143.         lcdwriteready();
  144.         rs=0;
  145.         rw=0;
  146.         lcddb=com;
  147.         delay(10);
  148.         en=1;
  149.         delay(10);
  150.         en=0;
  151.         delay(10);
  152. }  

  153. void lcdwritedate(unsigned char date)           //写数据
  154. {
  155.         lcdwriteready();
  156.         rs=1;
  157.         rw=0;
  158.         lcddb=date;
  159.         delay(10);
  160.         en=1;
  161.         delay(10);
  162.         en=0;
  163.         delay(10);
  164. }

  165. void lcdInit()                                                                //初始化lcd
  166. {
  167.         lcdwritecom(0x01);
  168.         lcdwritecom(0x38);
  169.         lcdwritecom(0x0C);
  170.         lcdwritecom(0x06);
  171. }


  172. void lcd_add(unsigned char x,unsigned char y)         //设置lcd输入起始地址
  173. {
  174.         unsigned char add;
  175.         if(y==0)
  176.                 add = 0x00 + x;
  177.         else
  178.                 add = 0x40 + x;
  179.         lcdwritecom(add|0x80);
  180. }

  181. void  lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc)                //将转换的字符指针传入lcd
  182. {
  183.            lcd_add(x,y);
  184.            while(*zfc != '\0')
  185.            {
  186.                            lcdwritedate(*zfc++);        
  187.            }
  188. }

  189. void lcdareaclear(unsigned char x,unsigned char y,unsigned char changdu)                 //局部清除
  190. {
  191.         lcd_add(x,y);
  192.         while(changdu--)
  193.         {
  194.                 lcdwritedate(' ');        
  195.         }
  196. }

  197. void lcdallclear()                                //全屏清除
  198. {
  199.         lcdwritecom(0x01);

  200. }

  201. /*************************************************main.c函数***********************************************************/
  202. #include<reg52.h>
  203. unsigned char num1=0;
  204. unsigned char num2=0;
  205. unsigned char step=0;
  206. unsigned char oper = 0;
  207. unsigned char T0RH=0;
  208. unsigned char T0RL=0;
  209. unsigned char result=0;
  210. void ConfigTimer0(unsigned int ms);



  211. extern void lcdInit();

  212. extern void  lcdshowdate(unsigned char x,unsigned char y,unsigned char *zfc);                //将转换的字符指针传入lcd
  213. extern void lcdareaclear(unsigned char x,unsigned char y,unsigned char changdu);                 //局部清除
  214. extern void lcdallclear();                                //全屏清除
  215. extern void keyaction(unsigned char keycode);
  216. extern void keydriver();
  217. extern void keyscanf();


  218. void main()
  219. {
  220.     EA = 1;           //开总中断
  221.     ConfigTimer0(1);  //配置T0定时1ms
  222.         lcdInit();    //初始化液晶
  223.     lcdshowdate(15, 1, "0");  //初始显示一个数字0

  224.     while (1)
  225.     {
  226.         keydriver();  //调用按键驱动
  227.     }
  228. }

  229. unsigned char zfc_date(unsigned char *zfc,signed long date)         //数字转字符串
  230. {
  231.         signed long i = 0;
  232.         unsigned char changdu = 0;
  233.         unsigned char buf[12];

  234.         if(date < 0)
  235.         {
  236.                 date = -date;
  237.                 *zfc++ = '-';
  238.                 changdu++;
  239.         }
  240.         do
  241.         {
  242.                 buf[i++]= date %10;
  243.                 date /= 10;
  244.         }
  245.         while(date > 0);
  246.         changdu += i;                    
  247.         while(i-- > 0)
  248.         {
  249.                 *zfc++ = buf[i] + '0';

  250.         }
  251.         *zfc = '\0';
  252.          
  253.          return changdu;
  254. }

  255. void showoper(unsigned char y, unsigned char type)        //加减乘除函数
  256. {
  257.         switch(type)
  258.         {
  259.                 case 0: lcdshowdate( 0 , y , "+");
  260.                 case 1: lcdshowdate( 0 , y , "-");
  261.                 case 2: lcdshowdate( 0 , y , "*");
  262.                 case 3: lcdshowdate( 0 , y , "/");
  263.                 default: break;                 //
  264.         }
  265. }

  266. void reset()         //清除
  267. {
  268.         num1 = 0;
  269.         num2 = 0;
  270.         step = 0;
  271.         lcdallclear();                    
  272. }

  273. void numkeyaction(unsigned char n)           //输入
  274. {
  275.         unsigned char changdu = 0;
  276.         unsigned char zfc[12];
  277.         if(step > 1)
  278.         {
  279.                 reset();
  280.         }
  281.         if(step == 0)
  282.         {
  283.                 num1 = num1*10 + n;
  284.                 changdu = zfc_date(zfc,num1);         //
  285.                 lcdshowdate(16-changdu,1,zfc);
  286.         }
  287.         else
  288.         {
  289.                 num2 = num2*10 + n;
  290.                 changdu =  zfc_date(zfc,num2);                 //
  291.                 lcdshowdate(16-changdu,1,zfc);
  292.         }
  293. }

  294. void operkeyaction(unsigned char type)                //输入
  295. {        
  296.         unsigned char changdu;
  297.         unsigned char zfc[12];
  298.         if(step == 0)
  299.         {
  300.                 changdu = zfc_date(zfc,num1);
  301.                 lcdareaclear(0,0,16-changdu);
  302.                 lcdshowdate(16-changdu,0,zfc);
  303.                 showoper(1,type);
  304.                 lcdareaclear(1,1,14);
  305.                 lcdshowdate(15,1,"0");        //
  306.                 oper = type;   //
  307.                 step = 1;
  308.         }
  309. }

  310. void getresult()         //结果
  311. {
  312.         unsigned char changdu;
  313.         unsigned char zfc[12];
  314.         if(step == 1)
  315.         {
  316.                 step = 2;
  317.                 switch(oper)
  318.                 {
  319.                         case 0: result = num1 + num2; break;
  320.                         case 1: result = num1 - num2; break;
  321.                         case 2: result = num1 * num2; break;
  322.                         case 3: result = num1 / num2; break;
  323.                         default: break;
  324.                 }
  325.                 changdu = zfc_date(zfc,num2);
  326.                 showoper(0,oper);
  327.                 lcdareaclear(1,0,16-changdu-1);
  328.                 lcdshowdate(16-changdu,0,zfc);
  329.                 changdu = zfc_date(zfc,result);
  330.                 lcdshowdate(0,1,"=");
  331.                 lcdareaclear(1,1,16-changdu-1);
  332.                 lcdshowdate(16-changdu,1,zfc);
  333.         }        
  334. }



  335. /* 配置并启动T0,ms-T0定时时间 */
  336. void ConfigTimer0(unsigned int ms)
  337. {
  338.     unsigned long tmp;  //临时变量

  339.     tmp = 11059200 / 12;      //定时器计数频率
  340.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  341.     tmp = 65536 - tmp;        //计算定时器重载值
  342.     tmp = tmp + 12;           //补偿中断响应延时造成的误差
  343.     T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
  344.     T0RL = (unsigned char)tmp;
  345.     TMOD &= 0xF0;   //清零T0的控制位
  346.     TMOD |= 0x01;   //配置T0为模式1
  347.     TH0 = T0RH;     //加载T0重载值
  348.     TL0 = T0RL;
  349.     ET0 = 1;        //使能T0中断
  350.     TR0 = 1;        //启动T0
  351. }
  352. /* T0中断服务函数,执行按键扫描 */
  353. void InterruptTimer0() interrupt 1
  354. {
  355.     TH0 = T0RH;  //重新加载重载值
  356.     TL0 = T0RL;
  357.     keyscanf();   //按键扫描
  358. }


复制代码

51计算器.rar

61.5 KB, 下载次数: 6

回复

使用道具 举报

ID:169921 发表于 2017-3-11 18:06 | 显示全部楼层
无法显示,连初始化的0都显示不出来。请大神指导下我 ,困扰好难受!!!
回复

使用道具 举报

ID:149167 发表于 2017-3-11 21:43 | 显示全部楼层
先確認接線...排除...再看程序
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表