找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2058|回复: 0
收起左侧

单片机问题,1602显示按键模块程序逻辑问题

[复制链接]
回帖奖励 15 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次(中奖概率 80%)
ID:725056 发表于 2020-4-28 11:12 | 显示全部楼层 |阅读模式

原理图

原理图


这是完整代码,帮我看看RHTke'y那部分,主程序我按下去1602显示屏数值不会改变,是为什么,那里错了?
这个没有程序错误,我觉得是逻辑写错了,搞不来,求大神指导一下.。。

单片机源程序如下:
  1. #include <stdio.h>
  2. #include <reg52.h>
  3. #include <intrins.h>
  4. #include <string.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #define ulongint unsigned long int

  8. uint code tab[2][11]={0,10,20,30,40,50,60,70,80,90,100,7351,7224,7100,6976,6853,6728,6600,6468,6330,6186,6033};//湿敏电容表格
  9. ulongint F=0;
  10. ulongint T0_count=0,T1_count=0;
  11. bit flag=0;//flag的取值只能是0或1
  12. ulongint RH=0;
  13. ulongint u=50;//湿度上限值
  14. ulongint j=25;//湿度下限值
  15. int h=25;//温度上限值
  16. int g=10;//温度下限值
  17. void delay1ms()//(3j+2)*i,延时1ms
  18.   {
  19.      unsigned char i,j;
  20.      for(i=0;i<10;i++)
  21.      for(j=0;j<33;j++);
  22.   }
  23. void delaynms(unsigned char n)//延时若干毫秒
  24. {
  25.     unsigned char i;
  26.     for(i=0;i<n;i++)
  27.     delay1ms();
  28. }
  29. sbit fmq=P3^3;//蜂鸣器
  30. sbit k1=P2^4;//加
  31. sbit k2=P2^3;//减
  32. sbit k3=P2^2;//湿度上下限调节
  33. sbit k4=P2^1;//温度上下限调节
  34. void delay500us()//500us基准延时
  35.   {
  36.      unsigned char j;
  37.      for(j=0;j<57;j++);
  38.   }
  39. void beep()//产生1KHZ频率声音
  40. {
  41.      unsigned int t;
  42.      for(t=0;t<1000;t++)
  43.       {
  44.           fmq=~fmq;
  45.           delay500us();
  46.       }
  47.    fmq=1;
  48.    delaynms(1000);
  49. }
  50. //对lcd1602操作
  51. sbit lcdrs = P2^5;//寄存器选择位,将rs位定义为P2.5引脚
  52. sbit lcdrw = P2^6;//读写选择位,将rw位定义为P2.6引脚
  53. sbit lcden = P2^7;//使能信号位,将e位定义为P2.7引脚
  54. sbit lcdBF = P0^7;//忙碌标志位,14号引脚
  55. bit BusyTest(void)//判断1602忙碌状态,1忙碌,0不忙
  56. {
  57.          bit result;
  58.          lcdrs=0;//rs为低电平,rw为高电平时,可以读状态
  59.          lcdrw=1;
  60.          lcden=1;//e=1,才允许读写
  61.         _nop_();//空操作
  62.        _nop_();
  63.        _nop_();
  64.        _nop_();//空操作4个周期,给硬件反应时间
  65.       result=lcdBF;//将忙碌标志位给result
  66.       lcden=0;//将e恢复低电平
  67.       return result;
  68. }
  69. void LcdWriteCommand(unsigned char dictate)//将显示地址写入1602
  70. {
  71.        while(BusyTest()==1);//如果忙就等待
  72.        lcdrs=0;
  73.         lcdrw=0;//rs和rw同时为低电平,可以写入指令
  74.         lcden=0;//e给低电平,让e从0到1发生正跳变,所以先置0
  75.         _nop_();
  76.         _nop_();
  77.         P0=dictate;//将数据送入P0口,即写入指令或地址
  78.         _nop_();
  79.         _nop_();
  80.         _nop_();
  81.         _nop_();
  82.         lcden=1;//给高电平
  83.         _nop_();
  84.         _nop_();
  85.         _nop_();
  86.          _nop_();
  87.         lcden=0;//当e由高电平跳变成低电平时,液晶模块开始执行命令
  88. }
  89. void LcdWriteData(unsigned char y)//将数据写入液晶模块
  90. {
  91.       while(BusyTest()==1);//如果忙就等待
  92.       lcdrs=1;
  93.       lcdrw=0;//rs和rw同时为低电平,可以写入指令
  94.       lcden=0;//e给低电平,让e从0到1发生正跳变,所以先置0
  95.       P0=y;//将数据送入P0口,即将数据写入液晶模块
  96.       _nop_();
  97.       _nop_();
  98.       _nop_();
  99.        _nop_();
  100.          lcden=1;//给高电平
  101.       _nop_();
  102.       _nop_();
  103.         _nop_();
  104.       _nop_();
  105.        lcden=0;//当e由高电平跳变成低电平时,液晶模块开始执行命令
  106. }
  107. void LcdInitiate(void)//对LCD的显示模式进行初始化设置
  108. {
  109.       delaynms(15);//延时15ms
  110.       LcdWriteCommand(0x38);//显示模式设置:16×2显示,5×7点阵,8位数据接口
  111.       delaynms(5);//延时5ms
  112.         LcdWriteCommand(0x38);
  113.          delaynms(5);//延时5ms
  114.        LcdWriteCommand(0x38);//连续三次,确保初始化成功
  115.       delaynms(5);
  116.          LcdWriteCommand(0x08);//显示关闭
  117.          delaynms(5);
  118.         LcdWriteCommand(0x0c);//显示模式设置:显示开,有光标,光标闪烁
  119.      delaynms(5);
  120.        LcdWriteCommand(0x06);//显示模式设置:光标右移,字符不移
  121.       delaynms(5);
  122.        LcdWriteCommand(0x01);//清屏幕指令,将以前的显示内容清除
  123.       delaynms(5);
  124. }
  125. void Disp1Char(unsigned char x,unsigned char y,unsigned char N)//在某个位置显示一个字符。x-列坐标,y-行坐标,N-显示的字符数据
  126. {
  127.      if(y==0)
  128.        {
  129.             LcdWriteCommand(0x80 + x);//第一行显示
  130.        }
  131.    else
  132.     {
  133.         LcdWriteCommand(0xC0 + x);//第二行显示
  134.     }
  135.         LcdWriteData(N);
  136. }
  137. void DispNChar(uchar x,uchar y,uchar n,uchar *ptr)//让液晶屏从某个位置连续显示N个字符。n-字符个数,ptr-指向字符存放位置的指针
  138. {
  139.         uchar i;
  140.         for(i=0;i<n;i++)
  141.           {
  142.                Disp1Char(x++,y,ptr[i]);
  143.               if(x==0x0f)
  144.                 {
  145.                     x=0;
  146.                    y^=1;
  147.                 }
  148.           }
  149. }
  150. void DispStr(uchar x,uchar y,uchar *ptr)//让液晶从某个位置连续显示一个字符串。ptr-指向字符串存放位置的指针
  151. {
  152.          uchar *temp;
  153.          uchar i,n=0;
  154.          temp = ptr;
  155.            while(*ptr++ != '\0')
  156.           n++;//计算字符串有效字符的个数
  157.            for(i=0;i<n;i++)
  158.               {
  159.                    Disp1Char(x++,y,temp[i]);
  160.                   if(x==0x0f)
  161.                      {
  162.                          x=0;
  163.                          y^=1;
  164.                      }
  165.              }
  166. }
  167. void Welcome()//欢迎界面
  168. {
  169.        DispStr(0,0,"Welcome");
  170.       DispStr(0,1,"WaiT");
  171. }
  172. void Disp_RH(ulongint f_data)//显示最终结果RH
  173. {
  174.          unsigned char lcd_table[3];
  175.             ulongint aa;
  176.            aa=f_data;
  177.            lcd_table[0]=aa/100;//百位
  178.          lcd_table[1]=aa%100/10;//十位
  179.          lcd_table[2]=aa%100%10;//个位
  180.          DispStr(0,0,"RH=");
  181.             Disp1Char(3,0,(lcd_table[0]+0x30));
  182.           Disp1Char(4,0,(lcd_table[1]+0x30));
  183.          Disp1Char(5,0,(lcd_table[2]+0x30));//加上0x30以便直接得到相应ASCII码去显示
  184.         Disp1Char(6,0,('%'));
  185. }
  186. void Disp_u(ulongint u_data,ulongint d_data)//显示初始设定湿度数值
  187. {
  188.           Disp1Char(5,1,(u_data/100+0x30));
  189.            Disp1Char(6,1,(u_data%100/10+0x30));
  190.           Disp1Char(7,1,(u_data%100%10+0x30));
  191.          Disp1Char(8,1,(d_data%100/10+0x30));
  192.         Disp1Char(9,1,(d_data%100%10+0x30));
  193. }
  194. void Disp_t(int u_data,int d_data)//显示初始设定温度数值
  195. {
  196.          Disp1Char(11,1,(u_data%100/10+0x30));
  197.          Disp1Char(12,1,(u_data%100%10+0x30));
  198.         Disp1Char(14,1,(d_data%100/10+0x30));
  199.         Disp1Char(15,1,(d_data%100%10+0x30));
  200. }
  201. void Disp_F(ulongint f_data)//显示频率
  202. {
  203.          unsigned char lcd_table[4];
  204.          ulongint aa;
  205.         aa=f_data;
  206.            lcd_table[0]=aa/1000;
  207.          lcd_table[1]=aa%1000/100;
  208.            lcd_table[2]=aa%100/10;
  209.            lcd_table[3]=aa%10;
  210.            DispStr(0,0,"F=");
  211.         Disp1Char(2,0,(lcd_table[0]+0x30));
  212.             Disp1Char(3,0,(lcd_table[1]+0x30));
  213.                Disp1Char(4,0,(lcd_table[2]+0x30));
  214.          Disp1Char(5,0,(lcd_table[3]+0x30));
  215.            Disp1Char(6,0,('H'));
  216.            Disp1Char(7,0,('Z'));
  217. }
  218. void Timer_Iint()//定时器T0,T1初始化
  219. {
  220.     TMOD=0x51;//T1计数,T0定时,方式1:16位计数
  221.      TH0=(65536-50000)/256;//定时器T0的高8位赋初值
  222.       TL0=(65536-50000)%256;//定时器T0的低8位赋初值
  223.       TH1=0x00;//计数初值,0
  224.       TL1=0x00;
  225.        EA=1;//开总中断
  226.         ET0=1;//定时器T0终端允许
  227.          ET1=1;//计数器T1中断允许
  228.        TR0=1;
  229.       TR1=1;//开始计数
  230. }
  231. void RHTkey()
  232. {
  233.      uchar k3n=0;
  234.      uchar k4n=0;
  235.      if(k3==0)
  236.        {
  237.           delaynms(10);
  238.          if(k3==0)
  239.            {
  240.                 while(!k3)
  241.                 k3n++;
  242.                 if(k3n==3)
  243.                   k3n=0;
  244.                switch(k3n)
  245.                   {
  246.                           case 1:break;//按一下
  247.                           case 2:break;//按两下
  248.                          case 0:break;//按三下返回
  249.                    }
  250.           }
  251.        }
  252.              if(k4==0)
  253.                {
  254.                   delaynms(10);
  255.                   if(k4==0)
  256.                      {
  257.                            while(!k4)
  258.                            k4n++;
  259.                           if(k4n==3)
  260.                           k4n=0;
  261.                           switch(k4n)
  262.                              {
  263.                                        case 1:break;//按一下
  264.                                       case 2:break;//按两下
  265.                                     case 0:break;//按三下
  266.                              }
  267.                       }
  268.                }
  269.            if(k3n!=0)//如果按k3,不按k4调节湿度上下限
  270.             {
  271.                     if(k1==0)//加
  272.                        {
  273.                              delaynms(10);
  274.                             if(k1==0)
  275.                                {
  276.                                    while(!k1);
  277.                                    switch(k3n)
  278.                                        {
  279.                                               case 1:
  280.                                                 u++;
  281.                                               if(u==100)/湿度/上线
  282.                                                   {
  283.                                                       u=99;
  284.                                                    }
  285.                                               break;
  286.                                               case 2:
  287.                                                   j++;
  288.                                               if(j==u)//温度下限
  289.                                                   {
  290.                                                       j=u-1;
  291.                                                   }
  292.                                              break;
  293.                                       }
  294.                               }
  295.                                  Disp_u(u,j);
  296.                         }
  297.                if(k2==0)//减
  298.                    {
  299.                         delaynms(10);
  300.                         if(k2==0)
  301.                            {
  302.                                while(!k2);
  303.                                switch(k3n)
  304.                                    {
  305.                                          case 1:
  306.                                          u--;
  307.                                          if(u==j)//湿度上线
  308.                                             {
  309.                                                  u=j+1;
  310.                                              }
  311.                                             break;
  312.                                         case 2:
  313.                                          j--;
  314.                                        if(j==0)//?
  315.                                           {
  316.                                                  j=1;
  317.                                           }
  318.                                           break;
  319.                                    }
  320.                            }
  321.               Disp_u(u,j);
  322.                   }
  323.    
  324.           }
  325.          if(k3n==0)//如果按k4,不按k3调节温度上下限
  326.            {
  327.                            if(k1==0)//加
  328.                               {
  329.                                   delaynms(10);
  330.                                   if(k1==0)
  331.                                      {
  332.                                           while(!k1);
  333.                                           switch(k4n)
  334.                                               {
  335.                                                       case 1:
  336.                                                       h++;
  337.                                                       if(h==50)//温度上线
  338.                                                           {
  339.                                                                  h=49;
  340.                                                           }
  341.                                                       if(h<0)
  342.                                                       Disp1Char(10,1,('-'));
  343.                                                       break;
  344.                                                       case 2:
  345.                                                       g++;
  346.                                                       if(g==h)//温度下限
  347.                                                            {
  348.                                                                  g=h-1;
  349.                                                             }
  350.                                                       if(g<0)
  351.                                                       Disp1Char(13,1,('-'));
  352.                                                       break;
  353.                                                }
  354.                                     }
  355.                                                 Disp_t(h,g);
  356.                              }
  357.                            if(k2==0)//减
  358.                                  {
  359.                                         delaynms(10);
  360.                                         if(k2==0)
  361.                                              {
  362.                                                   while(!k2);
  363.                                                   switch(k4n)
  364.                                                        {
  365.                                                              case 1:
  366.                                                              h--;
  367.                                                             if(h==g)//温度上限
  368.                                                                 {
  369.                                                                       h=g+1;
  370.                                                                 }
  371.                                                             if(h<0)
  372.                                                            Disp1Char(10,1,('-'));
  373.                                                            break;
  374.                                                             case 2:
  375.                                                             g--;
  376.                                                            if(g==-30)//温度下限
  377.                                                                {
  378.                                                                      g=-29;
  379.                                                                }
  380.       
  381.                                                            if(g<0)
  382.                                                           Disp1Char(13,1,('-'));
  383.                                                           break;
  384.                                                        }
  385.                                               }
  386.                                                        Disp_t(h,g);
  387.                                 }
  388.    
  389.           }
  390. }

  391. void HS1101()//查表等差法F-RH转换
  392. {
  393.          //unsigned char i;//没用可删除
  394.            if(flag==1)
  395.                {
  396.                    flag=0;
  397.                   F=T1_count*65536+TH1*256+TL1;//存储频率值
  398.                  //LcdWriteCommand(0x01);//清屏幕指令
  399.                 //Disp_F(F);//不显示可删除

  400.                 if(F<=7351&&F>=6033)
  401.                      {
  402.                            if(F>7224)
  403.                           RH=((7351-F)/12.7);//去掉+0.5了
  404.                          else if(F>6600)
  405.                         RH=(10+(7224-F)/12.4);
  406.                         else if(F>6186)
  407.                        RH=(60+(6600-F)/13.8);
  408.                          else
  409.                        RH=(90+(6186-F)/15.3);
  410.                     }
  411.               Disp_RH(RH);
  412.               if(RH>u)
  413.                 {
  414.                     beep();
  415.                    DispStr(0,1,"RHh");
  416.                    delaynms(20);
  417.                 }
  418.          if(RH<j)//当湿度大于30时,蜂鸣器响
  419.               {
  420.                    beep();
  421.                    DispStr(0,1,"RHl");
  422.                    delaynms(20);
  423.               }
  424.        T0_count=0;
  425.          TH0=(65536-50000)/256;//定时器T0的高8位赋初值
  426.          TL0=(65536-50000)%256;//定时器T0的低8位赋初值
  427.         T1_count=0;
  428.         TH1=0x00;
  429.         TL1=0x00;
  430.          TR0=1;
  431.         TR1=1;//开始计数
  432.             }
  433. }
  434. void main()
  435. {
  436.        Timer_Iint();//初始化
  437.         LcdInitiate();
  438.          Welcome();
  439.         while(1)
  440.             {
  441.                 Disp_u(u,j);//显示湿度
  442.                 Disp_t(h,g);//显示温度
  443.                 HS1101();
  444.                RHTkey();
  445.             }

  446. }

  447. void Time1(void)interrupt 3//定时器2中断。这是计数器1
  448. {
  449.           TH1=0x00;
  450.            TL1=0x00;//重装初值,0
  451.              T1_count++;
  452. }
  453. void Time0(void)interrupt 1//定时器1中断,其后的0为定时器T0的中断编号
  454. {
  455.             TH0=(65536-50000)/256;//定时器T0的高8位赋初值
  456.           TL0=(65536-50000)%256;//定时器T0的低8位赋初值
  457.            T0_count++;
  458.           if(T0_count==20)
  459.                {
  460.                    flag=1;
  461.                    TR1=0;
  462.                    TR0=0;
  463.                  T0_count=0;
  464.                }
  465. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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