微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 新手写的一个51程序遇到点问题

新手写的一个51程序遇到点问题

时间:10-02 整理:3721RD 点击:

  1. #include<reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;
  7. typedef bit BOOL;           //此声明一个布尔型变量即真或假
  8. uchar data_byte;
  9. uchar RH,RL,TH,TL;
  10. uchar b;
  11. void delay(uchar ms);
  12. sbit led1=P1^0;             //手动模式灯
  13. sbit led2=P1^1;             //开窗灯
  14. sbit led3=P1^2;             //关窗灯
  15. sbit jb=P1^3;                                //蜂鸣器
  16. sbit k1=P1^4;               //手动模式
  17. sbit k2=P1^5;               //M1正转
  18. sbit k3=P1^6;               //M1反转
  19. sbit io=P2^0;               //dht11data端接单片机的P2^0口
  20. sbit in1=P2^1;              //M1
  21. sbit in2=P2^2;              //M1
  22. sbit yw=P2^3;               //烟雾
  23. sbit rs=P2^4;               //以下三行是设置lcd1602的使能端
  24. sbit rw=P2^5;
  25. sbit ep=P2^6;
  26. sbit xw1=P0^0;              //限位开关
  27. sbit xw2=P0^1;
  28. /*----------------------延时程序------------------------- */

  29. void delay(uchar ms)
  30. {
  31.         uchar i;
  32.         while(ms--)                 
  33.          for(i=0;i<100;i++);
  34. }
  35. void delay1()            //一个for循环大概需要8个多机器周期,一个机器周期为1us,晶振为12MHz,本函数延时8us多
  36. {                                                  //DHT11模块需要比较精确的延迟
  37.         uchar i;
  38.         for(i=0;i<1;i++);
  39. }

  40. /*----------------------开窗---------------------- */
  41. void open(void)
  42. {in1=1;in2=0;}
  43. /*----------------------关窗---------------------- */
  44. void close(void)
  45. {in1=0;in2=1;}
  46. /*----------------------停止---------------------- */
  47. void stop(void)
  48. {in1=1;in2=1;}
  49. ///*----------------------防盗---------------------- */
  50. //void fangdao(void)
  51. //{
  52. //        if(fd==0)
  53. //        {led1=0;
  54. //               
  55. //        }
  56. //        if(fd==1){led1=1;}
  57. //}

  58. /*----------------------烟雾---------------------- */
  59. void yanwu(void)
  60. {
  61.         if(yw==0)  //检测到甲烷等有害气体
  62.         {
  63.                 delay(25);
  64.                 if(yw==0) //确认检测到
  65.                 {
  66.                         jb=0;
  67.                         close();
  68.                         if(xw1==0){stop();}
  69.                 }       
  70.         }
  71.         else
  72.         {stop();jb=1;}
  73. }

  74. /*----------------------lcd模块-----------------------*/
  75. BOOL lcd_bz()                    //测试lcd忙碌状态返回值为布尔型数值真或假'1'.'0'  
  76. {
  77.         BOOL result;
  78.         rs=0;                        // 读忙信号
  79.         rw=1;
  80.         ep=1;
  81.         _nop_();
  82.         _nop_();
  83.         _nop_();
  84.         _nop_();
  85.         result = (BOOL)(P3&0x80);
  86.         ep=0;
  87.         result ;
  88. }     

  89. void write_cmd(uchar cmd)       //写指令
  90. {
  91.         while (lcd_bz());
  92.         rs=0;
  93.         rw=0;
  94.         ep=0;
  95.         _nop_();
  96.         _nop_();
  97.         P3=cmd ;
  98.         _nop_();
  99.         _nop_();
  100.         _nop_();
  101.         _nop_();
  102.         ep=1;
  103.         _nop_();
  104.         _nop_();
  105.         _nop_();
  106.         _nop_();
  107.         ep=0;
  108. }

  109. void write_addr(uchar addr)        //写地址
  110. {
  111.         write_cmd(addr|0x80);          //LCD第一行的首地址为0x80,第二行的首地址为0x80+0x40=0xc0
  112. }

  113. void write_byte(uchar dat)         //写字节
  114. {
  115.         while (lcd_bz());
  116.         rs=1;
  117.         rw=0;
  118.         ep=0;
  119.         _nop_();
  120.         _nop_();
  121.         P3=dat ;
  122.         _nop_();
  123.         _nop_();
  124.         _nop_();
  125.         _nop_();
  126.         ep=1;
  127.         _nop_();
  128.         _nop_();
  129.         _nop_();
  130.         _nop_();
  131.         ep=0;
  132. }

  133. void lcd_init()         //lcd初始化
  134. {
  135.         write_cmd(0x38);    //设置LCD两行显示一个数据由5*7点阵表示,数据由8跟线传输
  136.         delay(1);
  137.         write_cmd(0x0c);    //清除屏幕显示
  138.         delay(1);
  139.         write_cmd(0x06);    //设定输入方式增量不移位
  140.         delay(1);
  141.         write_cmd(0x01);    //开整体显示关光标不闪烁
  142.         delay(1);
  143. }

  144. void display(uchar addr,uchar q)   //在某一地址上显示内容,adder表示的是地址偏移量,q表示显示的字符或数字
  145. {
  146.         delay(10);   write_addr(addr);
  147.         write_byte(q);
  148.         delay(1);                     //修改此时间可以改变LCD上数值跳变的数度
  149. }



  150. /*----------------------dht11模块**************************/

  151. void start()          //开始信号
  152. {
  153.         io=1;
  154.         delay1();
  155.         io=0;
  156.         delay(25);          // 主机把总线拉低必须大于18ms保证DHT11能检测到起始信号
  157.         io=1;               //发送开始信号结束后拉高电平延时20-40us
  158.         delay1();          //以下三个延时函数差不多为24us符合要求
  159.         delay1();
  160.         delay1();
  161. }

  162. uchar receive_byte()         //接收一个字节
  163. {
  164.         uchar i,temp;
  165.         for(i=0;i<8;i++)         //接收8bit的数据
  166.         {
  167.                 while(!io);          //等待50us的低电平开始信号结束
  168.                 delay1();            //开始信号结束之后延时26us-28us以下三个延时函数
  169.                 delay1();
  170.                 delay1();
  171.                 temp=0;              //时间为26us-28us表示接收的为数据'0'
  172.                 if(io==1)
  173.                 temp=1;              //如果26us-28us之后还为高电平则表示接收的数据为'1'
  174.                 while(io);           //等待数据信号高电平'0'为26us-28us'1'为70us
  175.                 data_byte<<=1;       //接收的数据为高位在前右移
  176.                 data_byte|=temp;
  177.         }
  178.         return data_byte;
  179. }

  180.    

  181. void receive()                               //接收数据
  182. {
  183.         uchar T_H,T_L,R_H,R_L,check,num_check,i;
  184.         start();                                //开始信号
  185.         io=1;                                   //主机设为输入,判断从机,DHT11,响应信号
  186.         if(!io)                                 //判断从机是否有低电平响应信号
  187.         {  
  188.                 while(!io);                         //判断从机发出 80us 的低电平响应信号是否结束
  189.                 while(io);                          //判断从机发出 80us 的高电平是否结束如结束则主机进入数据接收状态
  190.                 R_H=receive_byte();                 //湿度高位
  191.                 R_L=receive_byte();                 //湿度低位
  192.                 T_H=receive_byte();                 //温度高位
  193.                 T_L=receive_byte();                 //温度低位
  194.                 check=receive_byte();               //校验位
  195.                 io=0;                               //当最后一bit数据接完毕后从机拉低电平50us
  196.                 for(i=0;i<7;i++)                    //差不多50us的延时
  197.                 delay1();
  198.                 io=1;                               //总线由上拉电阻拉高进入空闲状态
  199.                 num_check=R_H+R_L+T_H+T_L;
  200.                 if(num_check==check)                //判断读到的四个数据之和是否与校验位相同
  201.                 {
  202.                         RH=R_H;
  203.                         RL=R_L;
  204.                         TH=T_H;
  205.                         TL=T_L;
  206.                         check=num_check;
  207.                 }
  208.         }
  209. }
  210. /*----------------------1602显示-----------------------*/
  211. void xs(void)
  212. {
  213.         lcd_init();                         //初始化LCD
  214.         while(1)
  215.         {
  216.                 receive();                     //接收数据
  217.                 display(0x05,'H');             //LCD的第一行显示
  218.                 display(0x06,'R');
  219.                 display(0x07,':');
  220.                 display(0x08,RH/10+0x30);      //0x30表示带字库的LCD1602中0x30的位置放有数字0,RH/10+0x30即表示湿度的十位数字在字库RH/10+0x30的位置处放着
  221.                 display(0x09,RH%10+0x30);      //RH%10+0x30即表示湿度的个位数字在字库RH%10+0x30的位置处放着
  222.                 display(0X0a,'%');
  223.                 display(0x45,'T');             //LCD的第二行显示
  224.                 display(0x46,':');
  225.                 display(0x47,TH/10+0x30);
  226.                 display(0x48,TH%10+0x30);
  227.                 display(0x49,0xdf);           //以下两个是温度单位的处理
  228.                 display(0x4a,0x43);
  229.                 if(RH>=65)
  230.                 {
  231.                         delay(25);
  232.                         if(RH>=65)
  233.                         {
  234.                                 close();
  235.                                
  236.                                 if(xw1==0){stop();        }
  237.                         }
  238.                 }
  239.                 else
  240.                 stop();
  241.         }
  242. }

  243. void main()
  244. {
  245. bit a;

  246. while(1)
  247. {
  248.         xs();
  249.         if(!k1)
  250.         {
  251.                 delay(25);
  252.                 a=~a;
  253.                 while(!k1);
  254.                 delay(10);
  255.         }
  256.         if(a==1)           //开启手动模式
  257.         {
  258.                 led1=0;
  259.                 if(k2==0)  //开窗
  260.                 {        led2=0;
  261.                         open();
  262.                         if(xw1==0){led2=1;stop();}

  263.                 }
  264.                 if(k3==0)  //关窗
  265.                 {        led3=0;
  266.                         close();
  267.                         if(xw1==0){led3=1;stop();}
  268.                 }
  269.                 if(k2==1&k3==1)        //停止
  270.                 {        led2=1;
  271.                         led3=1;
  272.                         stop();
  273.                        
  274.                 }
  275.         }
  276.         if(a==0)          //关闭手动模式
  277.         {
  278.                 led1=1;
  279.                 led2=1;
  280.                 led3=1;
  281.                 yanwu();
  282.                
  283.         }
  284. }
  285. }

复制代码

只要在主函数里加XS();就不能运行其他模块了,屏蔽了其他模块都是好的。该怎么改呢?

哥,XC()中你用了一个大循环

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top