标题: 单片机智能风扇程序出了点问题,欢迎大佬们来解答 [打印本页]
作者: 我是貔貅 时间: 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秒才可以和其他功能按键切换。。。。。我想任意切换功能的。。。
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define led_wx P2
- #define led_dx P0
- /*-------------定义数码管的字型码与字位码----------------------*/
- uchar code no[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9
- uchar code wex[]={0x01,0x02,0x04,0x08}; //字位码
- /*-------------定义变量------------------*/
- uchar ledplay[4];
- uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai;
- /*-------------定义端口-----------------*/
- sbit K1=P1^0; //占空比为100(全速)
- sbit K2=P1^1; //占空比为0(停止)
- sbit K3=P1^2; //占空比为50(半速)
- sbit K4=P1^3;
- sbit D8=P1^4;//指示灯
- sbit D7=P1^5;
- sbit D6=P1^6;
- sbit D5=P1^7; //自然风
- sbit out=P3^4;
- sbit out1=P3^7;
- /*----------------延时1ms函数-------------------*/
- void delay(uint z)
- {
- uint x,y;
- for(x=0;x<z;x++)
- for(y=0;y<110;y++);
- }
- /*------------自然风模式----------------*/
- void naturemode()
- {
- m=100;
- delay(1000);
- m=0;
- delay(3000);
- m=100;
- delay(1000);
- m=0;
- delay(3000); //前8秒
- m=100;
- delay(2000);
- m=0;
- delay(2000);
- m=100;
- delay(2000);
- m=0;
- delay(2000); //又8秒
- m=100;
- delay(3000);
- m=0;
- delay(1000);
- m=100;
- delay(3000);
- m=0;
- delay(1000); //又8秒
- m=100;
- delay(8000);
- }
- /*----------初始化函数-------------------*/
- void init()
- {
- TMOD=0x01; //定时器方式1
- TH0=0xd8;
- TL0=0xf0; //定时器0装入初值(10ms)
- EA=1; //开总中断
- ET0=1; //定时器0中断允许
- TR0=1; //
- EX1=1; //外部中断1允许
- IT1=1; //外部中断1下降沿触发
- TH1=0xff;
- TL1=0x9c; //定时100us
- ET1=1; //定时器1开中断
- TR1=1; //定时器1启动
- }
- /*----------键盘扫描函数----------------*/
- void keyscan()
- {
- if(K1==0)
- {
- delay(5); //消除抖动
- if(K1==0)
- { D8=0;
- D7=1;
- D6=1;
- D5=1;
- m=100;
-
- }
- }
- if(K2==0)
- {
- delay(5);
- if(K2==0)
- { D8=1;
- D7=0;
- D6=1;
- D5=1;
- m=0;
- }
- }
- if(K3==0)
- {
- delay(5);
- if(K3==0)
- { D8=1;
- D7=1;
- D6=0;
- D5=1;
- m=50;
-
- }
- }
- if(K4==0)
- {
- delay(5);
- if(K4==0)
- { D8=1;
- D7=1;
- D6=1;
- D5=0;
- while(K1&&K2&&K3==1)
- { naturemode();} //自然风模式
-
-
-
- }
- }
- }
- /*-----------数码管显示函数--------------*/
- void putin() //向led缓冲区填充数据
- {zhuansu=zhuansu*20;
- ledplay[0]=no[zhuansu/1000]; //千位
- ledplay[1]=no[zhuansu/100%10];//百位
- ledplay[2]=no[zhuansu/10%10];//十位
- ledplay[3]=no[zhuansu%10];//个位
- }
- void display() //将缓冲区的数据显示到数码管上
- {
- uchar i;
- putin();
- for(i=0;i<4;i++)
- {
- led_wx=wex[i];
- led_dx=ledplay[i];
- delay(2);
- }
- }
- void main()
- {
- flag_1=0;
- m=0; //占空比为100
- zhuansu=0; //转速初值0
- flag=0;
- zheng=1; //初始化电机正转动
- fan=0;
- init(); //初始化
- while(1)
- {
- keyscan(); //键盘扫描程序
-
-
- }
- }
- void int1()interrupt 2 //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
- {
- zhuansu++;
- }
- void int2()interrupt 1 //定时器0显示转速
- {
-
- TH0=0xd8;
- TL0=0xf0;//定时10ms
- flag++;
-
- if(flag==5) //计时到达0.05s
- {
- display(); //显示转速
- zhuansu=0; //转速置0
- flag=0;
- }
- }
- void int3()interrupt 3 //定时器1产生PWM
- {
-
- TH1=0xff;
- TL1=0x9c;//定时100us
- flag_1++;
- if(flag_1>99)
- flag_1=1;
- if(flag_1<m) //小于占空比m输出PWM=0输出电压为1
- {out=0;
- out1=1;
- }
- else //大于占空比输出电压为0
- {
- out=1;
- out1=1;
- }
- }
复制代码
作者: ffff7777 时间: 2018-7-9 09:12
你好,请问能发下仿真图吗
作者: zyzhyue 时间: 2018-7-9 09:21
问题出在:你的自然风模式控制方式,是用 delay 实现“一根筋”式控制。
需要改成:
1. 抛弃 delay 函数,
2. 开一个毫秒级定时器,
3. 设置一个工作模式变量,和一组状态变量,详细当前的工作状态、阶段等,
4. 在主循环中,检查模式、状态变量,结合经过的时间值,在恰当的时候,切换输出、并更新相应变量
这,才是“智能控制”该有的样子
作者: 1234r 时间: 2018-7-9 12:32
中断中不能使用主函数或子函数中用过的延时,如果你用了,很有可能跳不出中断,我建议再加一个一模一样的延时子函数,然后再调用
作者: angmall 时间: 2018-7-9 16:28
用到delay 阻塞延时实现, 方法效率很低, 让芯片在那儿空运行几百毫秒,什么也不做,真是莫大的浪费,尤其在芯片频率较高,任务又很多时,这样做就像在平坦宽阔的高速公路上挖了一大坑,出现事故可想而知。
需调用非阻塞延时程序
作者: 严肃活泼.姚 时间: 2019-12-10 12:35
请问您这个还有程序和原理图吗?
作者: 喧嚣。。 时间: 2022-1-7 08:39
还有这就是他的仿真图吗
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |