找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2119|回复: 4
打印 上一主题 下一主题
收起左侧

单片机风扇风速控制电路 求指导一下我的代码!

[复制链接]
跳转到指定楼层
楼主
ID:484259 发表于 2019-3-4 15:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
设计一个风扇风速控制电路,用三个按键控制风速、风种、启动/停止;运转状态用指示灯显示。
风速:强、中、弱对应电扇的不同转速。 风种:睡眠、自然、正常。睡眠时,电扇运转10秒,间断10秒;自然时,自然风运转5秒,间断5秒;正常时电扇连续运转。

现在代码出现的问题是:选择风种那里,停转5秒那里没问题,但是一旦进入停转10秒那里就变成转10秒,只停止3秒左右,模式3直接进入不了,一直在模式1和2之间变换。

代码如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #include<uart.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. uchar zkb,aa;
  8. uchar t=0,snum=0,s1num=0,tt=0;  //t记录中断次数,确定PWM的周期
  9. sbit IN1=P2^1;
  10. sbit IN2=P2^2;
  11. sbit ENA=P2^5;     //产生PWM波?
  12. sbit dula=P2^6;
  13. sbit wela=P2^7;
  14. sbit zs=P3^7;       //转速
  15. sbit ms=P3^6;     //模式
  16. sbit d1=P1^0;
  17. sbit d2=P1^1;
  18. sbit d3=P1^2;
  19. sbit d4=P1^3;
  20. sbit d5=P1^4;
  21. sbit lcden=P3^4;
  22. sbit rs=P3^5;


  23. void delayms(uint xms)                //延时子程序
  24. {
  25.    uint i,j;
  26.    for(i=xms;i>0;i--)
  27.     for(j=110;j>0;j--);
  28. }
  29. //液晶显示模块的读写以及控制
  30. void write_com(uchar com)                   //写命令函数
  31. {
  32.         rs=0;
  33.         lcden=0;
  34.         P0=com;
  35.         delayms(5);
  36.         lcden=1;
  37.         delayms(5);
  38.         lcden=0;      
  39. }


  40. void write_data(uchar date)                   //写数据函数
  41. {
  42.         rs=1;
  43.         lcden=0;
  44.         P0=date;
  45.         delayms(5);
  46.         lcden=1;
  47.         delayms(5);
  48.         lcden=0;      
  49. }






  50.    //函数功能:显示档数和模式
  51. void display_sym()
  52. {
  53.         write_com(0x80);
  54.         write_data('v');
  55.         write_data(':');
  56.         write_com(0x80+0x40);
  57.         write_data('m');
  58.         write_data(':');


  59. }


  60. void keyscan()
  61. {
  62.   if(zs==0)                //控制电机的四个转速
  63.    {
  64.                    delayms(5);//消抖
  65.                 if(zs==0)        //zs键确实按下
  66.                 {
  67.                        
  68.                         snum++;                 //每按一次加1
  69.                         while(!zs); //等待松开
  70.                         if(snum==3)           //当snum=5时,回到第一档
  71.                         {
  72.                            snum=0;                //0档,速度最大               
  73.                          }                  
  74.                     switch(snum)
  75.                         {
  76.                                 case 0:zkb=40;break;          //snum为0时,1档
  77.                                 case 1:zkb=60;break;                 //snum为1时,2档                 
  78.                                 case 2:zkb=90;break;                //snum为2时,3档                        
  79.                                 default: break;
  80.                         }
  81.                        
  82.                 }
  83.    }


  84. if(ms==0)                //控制电机的四个转速
  85.    {
  86.                    delayms(5);//消抖
  87.                 if(ms==0)        //zs键确实按下
  88.                 {
  89.                         while(!ms); //等待松开
  90.                         s1num++;                 //每按一次加1                  
  91.                         if(s1num==1)           //
  92.                         {
  93.                        tt=0;
  94.                                 aa=100;
  95.                                 IN1=1;           //
  96.                                 IN2=0;
  97.                         }
  98.                         if(s1num==2)            //
  99.                         {
  100.                        
  101.                                 tt=0;
  102.                                 aa=200;
  103.                                 IN1=1;                //
  104.                                 IN2=0;
  105.                         }
  106.                          if(s1num==3)           //
  107.                         {
  108.                                 s1num=0;     //清零下次计算
  109.                                 IN1=1;               
  110.                                 IN2=0;
  111.                         }
  112.                        
  113.                 }
  114.    }              
  115.             
  116. }


  117. void init()
  118. {      
  119.         dula=0;
  120.         wela=0;
  121.         lcden=1;      
  122.         IN1=1;
  123.         IN2=0;
  124.         write_com(0x38);   //设置16*2显示,5*7点阵,8位数据接口
  125.         write_com(0x0c);   //设置开显示,不显示光标
  126.         write_com(0x06);   // 写一个字符后地址指针加1
  127.         write_com(0x01);   //显示清0,数据指针清0
  128.         write_com(0x80);   //通电时,指针知道显示屏第一行首位处
  129.         TMOD=0x21;                   //
  130.         TH1=(65536-917)/256;         //定时器1赋初值100us
  131.         TL1=(65536-917)%256;
  132.         TH0=(65536-45872)/256;         //定时器0赋初值50ms
  133.         TL0=(65536-45872)%256;
  134.         ET1=1;          //         定时器1打开
  135.         ET0=1;          //         定时器0打开
  136.         TR0=1;          //         启动定时器0
  137.         TR1=1;           //           启动定时器1
  138.         EA=1;          //         打开总中断
  139. }


  140. void main()
  141. {
  142.         init();                  //初始化
  143.         display_sym();        //上电时,显示v:    m:                          
  144.         while(1)
  145.         {
  146.                 keyscan();                   //按键扫描,实现转速转向调节的功能                                         
  147.         }         
  148. }


  149. void timer0()interrupt 1                  //
  150. {
  151.         TH0=(65536-45872)/256;        //每次中断为50ms
  152.         TL0=(65536-45872)%256;
  153.          tt++;
  154.          
  155.         if(tt<aa)           
  156.                 IN1=1;
  157.         else
  158.         IN1=0;


  159.         if(tt==2*aa)
  160.                 tt=0;      
  161. }




  162. void timer1()interrupt 3                //该定时器1用于占空比调速
  163. {


  164.          
  165.            TH1=(65536-917)/256;                //重新装入初值 100us
  166.                TL1=(65536-917)%256;
  167.                  t++;                //每产生一次中断+1
  168.                 if(t<zkb)                //当占空比大于t时,输出高电平,否则输出低电平
  169.                 ENA=1;                       //在t<zkb时,使能端开启,否则使能端关闭
  170.                 else
  171.                 ENA=0;
  172.                 if(t>=100)
  173.                 t=0;
  174.                   
  175. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:484259 发表于 2019-3-4 15:38 | 只看该作者
漏说了,注释没写好,是第二个if那里出问题,对应的是定时器0那里。
回复

使用道具 举报

板凳
ID:484259 发表于 2019-3-4 18:34 | 只看该作者
现在发现好像是定时器0溢出标志位tt溢出次数太多会出错,达到某个溢出数后,tt就会自动清零
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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