找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3582|回复: 6
收起左侧

单片机智能风扇程序出了点问题,欢迎大佬们来解答

[复制链接]
ID:362355 发表于 2018-7-8 19:53 | 显示全部楼层 |阅读模式
要求设计一个智能风扇的控制电路,可以控制风扇的转速、工作时间等
用5V电源供电,设计四个按钮K1为全速,K2为停止,K3为半速,K4为自然风(刚开始每4S的时间内有1S在转动,并过8S后每4S的时间内有2S在转动,再过8S后每4S的时间内有3S在转动,再过8S后全速转动,再过8S后4S中又只有1S在转动,如此循环复始)。并分别用四个指导灯指示这四种状态,要用LED指示风扇的转速(每秒)。//现在出现的问题是,K1到K3的功能可以随意切换,到了K4就必须等24秒才可以和其他功能按键切换。。。。。我想任意切换功能的。。。
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define led_wx P2
  5. #define led_dx P0
  6. /*-------------定义数码管的字型码与字位码----------------------*/
  7. uchar code no[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};    //数字0~9
  8. uchar code wex[]={0x01,0x02,0x04,0x08};    //字位码
  9. /*-------------定义变量------------------*/
  10. uchar ledplay[4];
  11. uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai;
  12. /*-------------定义端口-----------------*/
  13. sbit K1=P1^0;                                                //占空比为100(全速)
  14. sbit K2=P1^1;                                                                   //占空比为0(停止)
  15. sbit K3=P1^2;                                                                                           //占空比为50(半速)
  16. sbit K4=P1^3;
  17. sbit D8=P1^4;//指示灯
  18. sbit D7=P1^5;
  19. sbit D6=P1^6;
  20. sbit D5=P1^7;                                                                                                         //自然风
  21. sbit out=P3^4;                                                                                       
  22. sbit out1=P3^7;
  23. /*----------------延时1ms函数-------------------*/
  24. void delay(uint z)
  25. {

  26. uint x,y;
  27. for(x=0;x<z;x++)
  28.      for(y=0;y<110;y++);
  29. }



  30. /*------------自然风模式----------------*/
  31. void naturemode()
  32. {         
  33.      m=100;
  34.          delay(1000);
  35.          m=0;
  36.          delay(3000);
  37.          m=100;
  38.          delay(1000);
  39.          m=0;
  40.          delay(3000); //前8秒
  41.          m=100;
  42.          delay(2000);
  43.          m=0;
  44.          delay(2000);
  45.          m=100;
  46.          delay(2000);
  47.          m=0;
  48.          delay(2000);        //又8秒
  49.          m=100;
  50.          delay(3000);
  51.          m=0;
  52.          delay(1000);
  53.          m=100;
  54.          delay(3000);  
  55.          m=0;
  56.          delay(1000);   //又8秒
  57.          m=100;
  58.          delay(8000);  
  59. }
  60. /*----------初始化函数-------------------*/
  61. void init()
  62. {
  63.   TMOD=0x01;               //定时器方式1           
  64.   TH0=0xd8;
  65.   TL0=0xf0;               //定时器0装入初值(10ms)
  66.   EA=1;                     //开总中断
  67.   ET0=1;                     //定时器0中断允许
  68.   TR0=1;                                       //
  69.   EX1=1;                                       //外部中断1允许
  70.   IT1=1;                     //外部中断1下降沿触发  
  71. TH1=0xff;
  72.   TL1=0x9c;                //定时100us
  73.   ET1=1;                   //定时器1开中断
  74.   TR1=1;                                   //定时器1启动
  75. }
  76. /*----------键盘扫描函数----------------*/
  77. void keyscan()  
  78. {  
  79.   if(K1==0)     
  80.   {
  81.     delay(5);      //消除抖动
  82.          if(K1==0)
  83.          {         D8=0;
  84.                  D7=1;
  85.                  D6=1;
  86.                  D5=1;
  87.                   m=100;
  88.                  
  89.      }
  90.   }
  91.   if(K2==0)
  92.   {
  93.     delay(5);
  94.          if(K2==0)
  95.          {         D8=1;
  96.                  D7=0;
  97.                  D6=1;
  98.                  D5=1;
  99.                  m=0;
  100.          }
  101.   }
  102.     if(K3==0)
  103.   {
  104.     delay(5);
  105.          if(K3==0)
  106.          {        D8=1;
  107.                 D7=1;
  108.                 D6=0;
  109.                 D5=1;
  110.             m=50;
  111.                
  112.          }
  113.   }
  114.   if(K4==0)
  115.   {
  116.     delay(5);
  117.          if(K4==0)
  118.          {        D8=1;
  119.                 D7=1;
  120.                 D6=1;
  121.                 D5=0;
  122.                 while(K1&&K2&&K3==1)
  123.          {        naturemode();} //自然风模式
  124.                
  125.         
  126.                     
  127.          }
  128.   }   
  129. }

  130. /*-----------数码管显示函数--------------*/

  131. void putin() //向led缓冲区填充数据
  132. {zhuansu=zhuansu*20;
  133. ledplay[0]=no[zhuansu/1000];         //千位
  134.   ledplay[1]=no[zhuansu/100%10];//百位
  135.   ledplay[2]=no[zhuansu/10%10];//十位
  136.   ledplay[3]=no[zhuansu%10];//个位
  137.   }
  138. void display()        //将缓冲区的数据显示到数码管上
  139. {
  140.   uchar i;
  141.   putin();
  142.   for(i=0;i<4;i++)
  143.   {
  144.   led_wx=wex[i];
  145.   led_dx=ledplay[i];
  146.   delay(2);
  147. }
  148. }

  149. void main()
  150. {
  151.     flag_1=0;
  152.          m=0;                                                         //占空比为100
  153.         zhuansu=0;                                           //转速初值0
  154.         flag=0;
  155.         zheng=1;                                  //初始化电机正转动
  156.         fan=0;

  157.     init();              //初始化

  158.         while(1)
  159.         {
  160.         keyscan();                                //键盘扫描程序
  161.         
  162.                   
  163.         }
  164. }
  165. void int1()interrupt 2                                //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
  166. {
  167.   zhuansu++;
  168. }
  169. void int2()interrupt 1                                  //定时器0显示转速
  170. {

  171.   TH0=0xd8;
  172.   TL0=0xf0;//定时10ms
  173.   flag++;
  174.          
  175.   if(flag==5)                                   //计时到达0.05s
  176.     {
  177.         display();                                        //显示转速
  178.         zhuansu=0;                                          //转速置0
  179.         flag=0;
  180.         }
  181. }
  182. void int3()interrupt 3                                         //定时器1产生PWM
  183. {
  184.   
  185.   TH1=0xff;
  186.   TL1=0x9c;//定时100us
  187.           flag_1++;

  188.     if(flag_1>99)
  189.         flag_1=1;
  190.         if(flag_1<m)                                          //小于占空比m输出PWM=0输出电压为1
  191.        {out=0;
  192.          out1=1;
  193.           }
  194.          else                                                  //大于占空比输出电压为0
  195.            {
  196.            out=1;
  197.            out1=1;
  198.            }
  199.           }
复制代码
回复

使用道具 举报

ID:367314 发表于 2018-7-9 09:12 | 显示全部楼层
你好,请问能发下仿真图吗
回复

使用道具 举报

ID:335709 发表于 2018-7-9 09:21 | 显示全部楼层
问题出在:你的自然风模式控制方式,是用 delay 实现“一根筋”式控制。
需要改成:
1. 抛弃 delay 函数,
2. 开一个毫秒级定时器,
3. 设置一个工作模式变量,和一组状态变量,详细当前的工作状态、阶段等,
4. 在主循环中,检查模式、状态变量,结合经过的时间值,在恰当的时候,切换输出、并更新相应变量
这,才是“智能控制”该有的样子
回复

使用道具 举报

ID:367855 发表于 2018-7-9 12:32 | 显示全部楼层
中断中不能使用主函数或子函数中用过的延时,如果你用了,很有可能跳不出中断,我建议再加一个一模一样的延时子函数,然后再调用
回复

使用道具 举报

ID:155507 发表于 2018-7-9 16:28 | 显示全部楼层
用到delay 阻塞延时实现, 方法效率很低, 让芯片在那儿空运行几百毫秒,什么也不做,真是莫大的浪费,尤其在芯片频率较高,任务又很多时,这样做就像在平坦宽阔的高速公路上挖了一大坑,出现事故可想而知。

需调用非阻塞延时程序
回复

使用道具 举报

ID:659573 发表于 2019-12-10 12:35 | 显示全部楼层
请问您这个还有程序和原理图吗?
回复

使用道具 举报

ID:1000345 发表于 2022-1-7 08:39 来自手机 | 显示全部楼层
还有这就是他的仿真图吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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