功能简述
“模拟风扇控制系统”能够模拟电风扇工作,通过按键控制风扇的转动速度和定时时间,数码管实时显示风扇的工作模式,动态倒计时显示剩余的定时时间,系统主要由数码管显示、单片机最小系统、按键输入和电机控制保护电路组成,系统框图如图 1 所示:
单总线驱动程序、CT107D 单片机考试平台电路原理图以及本题所涉及到的芯片数据手册,可参考计算机上的电子文档。程序流程图及相关工程文件请以考生号命名,并保存在计算机上的考生文件夹中(文件夹名为考生准考证号,文件夹保存在监考员指定位置)。
设计任务及要求
1. 工作模式
设备具有“睡眠风”、“自然风”和“常风”三种工作模式可以通过按键切换,通过
单片机 P34 引脚输出脉宽调制信号控制电机运行状态,信号频率为 1KHz。
1.1 “睡眠风”模式下,对应 PWM 占空比为 20%;
1.2 “自然风”模式下,对应 PWM 占空比为 30%;
1.3 “常风”模式下,对应 PWM 占空比为 70%;
2. 数码管显示
数码管实时显示设备当前工作模式和剩余工作时间(倒计时),如图 2 所示。
“睡眠风”状态下,对应数码管显示数值为 1,自然风模式下,显示数值为 2,常
风模式下,显示数值为 3。
3. 按键控制
使用 S4、S5、S6、S7 四个按键完成按键控制功能。
2.1 按键 S4 定义为工作模式切换按键,每次按下 S4,设备循环切换三种工作模式。工作过程如下:
2.2 按键 S5 定义为“定时按键”每次按下 S5,定时时间增加 1 分钟,设备的剩余
工作时间重置为当前定时时间,重新开始倒计时,工作过程如下:
设备剩余工作时间为 0 时,停止 PWM 信号输出。
2.3 按键 S6 定义为“停止”按键,按下 S6 按键,立即清零剩余工作时间,PWM
信号停止输出,直到通过 S5 重新设置定时时间。
2.4 按键 S7 定义为“室温”按键,按下 S7,通过数码管显示当前室温,数码管显
示格式如图 3 所示,再次按下 S7,返回图 2 所示的工作模式和剩余工作时间显示界面,如此往复。
室温测量、显示功能不应影响设备正在执行的 PWM 信号输出、停止、模式切
换和计时等功能。
4. LED 指示灯
“睡眠风”模式下,L1 点亮,“自然风”模式下 L2 点亮,“常风”模式下 L3 点亮;
按下停止按键或倒计时结束时,LED 全部熄灭。
5. 电路原理图设计
电机过热检测及驱动电路设计:
假定设备使用的是 12V 直流电机,过热检测传感器输出为小电压信号 Vs,设计过热检测及电机驱动电路,当检测到 Vs 信号幅度大于 10mV 时,电机停止转动,简述电路的工作原理与设计思路,并绘制出电路原理图。
主函数
#include"stc15f2k60s2.h"
#include"onewire.h"
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code SMG_duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code SMG_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
sbit PWM=P3^4;
uchar mode_display[8]; //工作模式显示
uchar temp_display[8];
uchar mode=1; //风速模式
uchar temperature;
uchar work_time;
uchar temp_flag;
uchar S5_count;
bit out_flag;
bit led_flag=1;
bit count; //计时模式下
void Timer0Init();
uchar KEY_init();
void main()
{
uchar key_val;
P2=0XA0;P0=0X00;
P2=0X80;P0=0XFF;
Timer0Init();
DS18B20();
mode_display[0]=0x40; mode_display[2]=0x40; mode_display[3]=0x00;
temp_display[0]=0x40; temp_display[1]=SMG_duan[4]; temp_display[2]=0x40;
temp_display[3]=0x00; temp_display[4]=0x00; temp_display[7]=0x39;
while(1)
{
temperature=temp_get();
temp_display[5]=SMG_duan[temperature%100/10];
temp_display[6]=SMG_duan[temperature%10];
mode_display[1]=SMG_duan[mode];
mode_display[4]=SMG_duan[0];
mode_display[5]=SMG_duan[work_time/100];
mode_display[6]=SMG_duan[work_time%100/10];
mode_display[7]=SMG_duan[work_time%10];
key_val=KEY_init();
switch(key_val)
{
case 4:
led_flag=1;
mode++;
if(mode==4)
mode=1;
break;
case 5:
led_flag=1;
count=1;
S5_count++;
if(S5_count==3)
{
S5_count=0;
work_time=0;
}
if(S5_count==1)
work_time=60;
if(S5_count==2)
work_time=120;
break;
case 6:
led_flag=0;
work_time=0;
out_flag=0;
break;
case 7:
led_flag=1;
temp_flag++;
if(temp_flag==2)
temp_flag=0;
break;
}
if(work_time>0)
{
out_flag=1;
}
if(count)
{
if(work_time==0)
{
out_flag=0;
led_flag=0;
}
}
if(led_flag)
{
switch(mode)
{
case 1:
P2=0X80;P0=~0X01;P2=0X00;
break;
case 2:
P2=0X80;P0=~0X02;P2=0X00;
break;
case 3:
P2=0X80;P0=~0X04;P2=0X00;
break;
}
}
if(led_flag==0)
{
P2=0X80;P0=0xff;P2=0X00;
}
}
}
#define key_input P3
#define key_state0 0
#define key_state1 1
#define key_state2 2
uchar KEY_init()
{
static uchar key_state=0;
uchar key_press,key_return=0;
key_press=key_input&0X0F;
switch(key_state)
{
case key_state0:
if(key_press!=0x0f)
key_state=key_state1;
break;
case key_state1:
if(key_press!=0x0f)
{
if(key_press==0x0e) key_return=7;
if(key_press==0x0d) key_return=6;
if(key_press==0x0b) key_return=5;
if(key_press==0x07) key_return=4;
key_state=key_state2;
}
else
key_state=key_state0;
break;
case key_state2:
if(key_press==0x0f)
key_state=key_state0;
break;
}
return key_return;
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Timer0() interrupt 1
{
uchar i;
static uint SMG_count,PWM_count=0,work_count=0;
SMG_count++; PWM_count++; work_count++;
if(SMG_count==30)
{
SMG_count=0;
P2=0XC0;P0=0X00;P2=0X00;
P2=0XC0;P0=SMG_wei[i];P2=0X00;
if(temp_flag==1)
{
P2=0XE0;P0=~temp_display[i];P2=0X00;
}
else
{
P2=0XE0;P0=~mode_display[i];P2=0X00;
}
i++;
if(i==8)
i=0;
}
if(work_count==10000)
{
work_count=0;
if(work_time>0)
work_time--;
}
if(out_flag)
{
if(mode==1)
{
if(PWM_count==8)
PWM=1;
if(PWM_count==10)
{
PWM=0;
PWM_count=0;
}
}
if(mode==2)
{
if(PWM_count==7)
PWM=1;
if(PWM_count==10)
{
PWM=0;
PWM_count=0;
}
}
if(mode==3)
{
if(PWM_count==3)
PWM=1;
if(PWM_count==10)
{
PWM=0;
PWM_count=0;
}
}
}
}
DS18B20模块
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
void delay(unsigned char ms);
void Delay500us(); //@11.0592MHz
void Delay100us(); //@11.0592MHz
void Delay60us(); //@11.0592MHz
void Delay15us(); //@11.0592MHz
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay500us();
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay60us();
DQ = 1;
Delay15us();
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
_nop_();
_nop_();
_nop_();
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay100us();
}
return dat;
}
void DS18B20()
{
Init_DS18B20();
delay(1);
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Init_DS18B20();
delay(1);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
}
int temp_get()
{
unsigned char low,high;
unsigned char temp;
DS18B20();
low=Read_DS18B20();
high=Read_DS18B20();
temp=high<<4;
temp|=low>>4;
return temp;
}
void Delay500us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 6;
j = 93;
do
{
while (--j);
} while (--i);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void Delay60us() //@11.0592MHz
{
unsigned char i, j;
i = 1;
j = 162;
do
{
while (--j);
} while (--i);
}
void Delay15us() //@11.0592MHz
{
unsigned char i;
i = 39;
while (--i);
}
void delay(unsigned char ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=850;j>0;j--);
}
以上就是代码全部内容,欢迎交流,共同学习~