1.功能
(1)通过按键开关风扇
(2)具有普通模式可以设置高、中、低三个档位
(3)具有智能模式可以根据温度自动调节转速
(4)OLED显示,显示“普通模式”、“智能模式”、“风速”,而且不同风速会显示、“慢”、“中”、“快”;
keyA: 开关
KeyB:档位
KeyC:智能模式
KeyD: OLED开关
DHT11温湿度传感器
STM32F103开发板
PWM直流电机
OLED屏幕
Cortex-M3摒弃了冯· 诺依曼结构(普林斯顿结构),采用了将指令存储和数据存储分开的 的哈佛结构(Harvard Architecture ),这样一来Cortex-M3同时拥有了独立的32-bit指令总线和32-bit数据总线,数据访问将不再占用指令总线,同时读取指令和数据后提升了MCU运行速度
用flyMCU烧录就不用STLink的JTAG连接了
STM32F103C8T6是一款基于ARM Cortex-M3内核(ARM公司在ARM11以后改用Cortex命名,并分成A、R和M三类,M系列有M0、M0+、M3、M4、M7)的32位的微控制器,采用LQFP48封装,由意法半导体公司(ST)推出,属于STM32系列(ST公司还有SPC5X系列微控制器)。其程序存储器FLASH容量是64KB (64K x 8bit),RAM容量是20KB(20K x 8bit),2个12bit ADC合计12路通道(外部通道只有PA0到PA7、PB0到PB1,并不是18通道),37个通用I/O口(PA0-PA15、PB0-PB15、PC13-PC15、PD0-PD1),4个16bit通用定时器(TIM1(带死区插入,常用于产生PWM控制电机)、TIM2、TIM3、TIM4),2个看门狗定时器(独立看门狗、窗口看门狗)1个24bit向下计数的滴答定时器(很重要,一般delay都使用这个定时器实现),2*IIC,2*SPI,3*USART,1*CAN,工作电压2V~3.6V,工作温度为-40°C ~ 85°C,系统时钟最高可到72MHz(一般是由8MHz的外部时钟经锁相环9倍频到72MHz)。
3.2 DHT11温湿度传感器
DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。
数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。
DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号,DHT11 不主动进行温湿度采集。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。
3.5 PWM直流电机
脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
直流无刷电机调速的原理就是在驱动电机转动的基础上,将驱动电流由PWM信号来控制,改变PWM信号的脉冲宽度,即通过调节MOSFET通断的时间来调节提供给电机三相的电流大小,从而对电机进行调速控制。STM32部的普通的定时器TIM3和TIM4,每个可以产生四路PWM发生器。
本次设计低档500,中档1000,快挡1500。
另外,既然满足这个关系,那PWM波的频率是不是可以随意了,答案当然不是,频率太低会导致电机运转不畅,振动大,噪音大;频率太高会导致驱动器开关损耗较大,甚至有电机会啸叫而不转的情况。一般1k~30k的PWM频率较为普遍,几百Hz的也有,
要点:
①PWM波其实就是一种脉宽可连续调节的矩形脉冲波;
②占空比其实就是描述脉宽与脉冲周期的比值,是量化值,便于分析研究,当我们用占空比来表达时,对脉宽就不那么关心了;
③占空比调节就是脉宽调节,表达不一样,但本质是一样的;
④PWM波满足伏秒积计算:U红(幅值) × 占空比 = U蓝,作用效果与直流电压一样。
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "tim.h"
#include "touch_key.h"
#include "dht11.h"
u8 key=0,mode=0,mode_shoudong=0,speed=0;
u8 time_flag=0,set_time=0;
u8 temp_flag=0,temp_low=25,temp_high=30;
u8 set_hour=0,set_min=0,set_sec=10;
u8 temp_read=0,time_read=0;
int main (void){//主程序
u8 b[2];
delay_ms(500);
RCC_Configuration(); //时钟设置
RELAY_Init();//继电器初始化
I2C_Configuration();//I2C初始化,集成电路总线,主从架构
DHT11_Init();//温湿度传感器
OLED0561_Init(); //OLED初始化
TOUCH_KEY_Init();//按键初始化
TIM3_NVIC_Init ();//开启TIM3中断向量
TIM3_Init(9999,7199);//定时器初始化,定时1秒(9999,7199)
TIM3_PWM_Init(59999,23);//PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms)
DHT11_ReadData(b);
delay_ms(1000);//DHT11初始化后必要的延时(不得小于1秒)
while(1){
switch(key=key_scan())
{
case 1:
if(mode==0)//手动模式
{
speed++;
if(speed==4)
speed=0;
}
if(mode==1)//温控
{
temp_flag++;//温控阈值更改标志位
if(temp_flag==2)
temp_flag=0;
}
break;
case 2:
mode++;// mode=0:手动 1:温控自动
OLED_DISPLAY_CLEAR();
if(mode==2)
mode=0;
break;
case 3:
if(mode==1)
{
if(temp_flag==0)
{
if(temp_low<40)
temp_low++;
}
if(temp_flag==1)
{
if(temp_high<45)
temp_high++;
}
}
if(mode==2)
{
if(time_flag==0)
{
if(set_hour<23)
set_hour++;
}
if(time_flag==1)
{
if(set_min<59)
set_min++;
}
if(time_flag==2)
{
if(set_sec<59)
set_sec++;
}
}
break;
case 4:
if(mode==1)
{
if(temp_flag==0)
{
if(temp_low>20)
temp_low--;
}
if(temp_flag==1)
{
if(temp_high>25)
temp_high--;
}
}
if(mode==2)
{
if(time_flag==0)
{
if(set_hour>0)
set_hour--;
}
if(time_flag==1)
{
if(set_min>0)
set_min--;
}
if(time_flag==2)
{
if(set_sec>0)
set_sec--;
}
}
break;
}
if(mode==0)//手动控制
{
OLED_DISPLAY_16x16(0,0*16,0);//模
OLED_DISPLAY_16x16(0,1*16,1);//式
OLED_DISPLAY_8x16(0,5*8,58);//:
OLED_DISPLAY_16x16(0,4*16,2);//手
OLED_DISPLAY_16x16(0,5*16,3);//动
if(speed==0)
{
RELAY_1(0);//继电器关闭
TIM_SetCompare1(TIM3,0);
/*定时器(Timer)最基本的功能就是定时了,比如定时发送 USART 数据、定时采集 AD数据等 等。如果把定时器与 GPIO 结合起来使用的话可以实现非常丰富的功能,可以测量输入信号的脉冲宽度,可以生产输出波形。定时器生产 PWM 控制电机状态是工业控制普遍方法,这方面知识非常有必要深入了解。*/
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,14);//关
}
if(speed==1)
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,500);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,11);//慢
}
if(speed==2)
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,1000);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,12);//中
}
if(speed==3)
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,1500);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,13);//快
}
}
if(mode==1)//温控
{
DHT11_ReadData(b);
OLED_DISPLAY_16x16(6,0*16,4);//温
OLED_DISPLAY_16x16(6,1*16,17);//湿
OLED_DISPLAY_16x16(6,2*16,6);//度
OLED_DISPLAY_8x16(6,6*8,':');//
OLED_DISPLAY_8x16(6,7*8,b[1]/10+0x30);//显示温度值
OLED_DISPLAY_8x16(6,8*8,b[1]%10+0x30);//
OLED_DISPLAY_8x16(6,10*8,'C');//
OLED_DISPLAY_8x16(6,12*8,b[0]%10+0x30);//湿度值
OLED_DISPLAY_8x16(6,13*8,b[0]%10+0x30);//
OLED_DISPLAY_8x16(6,15*8,'%');//
OLED_DISPLAY_16x16(0,0*16,0);//模
OLED_DISPLAY_16x16(0,1*16,1);//式
OLED_DISPLAY_8x16(0,5*8,58);//:
OLED_DISPLAY_16x16(0,4*16,4);//温
OLED_DISPLAY_16x16(0,5*16,5);//控
OLED_DISPLAY_16x16(4,0*16,15);//阈
OLED_DISPLAY_16x16(4,1*16,16);//值
OLED_DISPLAY_8x16(4,5*8,58);//:
OLED_DISPLAY_8x16(4,6*8,temp_low/10+0x30);//显示温度低值
OLED_DISPLAY_8x16(4,7*8,temp_low%10+0x30);
OLED_DISPLAY_8x16(4,9*8,temp_high/10+0x30);//显示温度高值
OLED_DISPLAY_8x16(4,10*8,temp_high%10+0x30);
if(b[1]<temp_low)
{
RELAY_1(0);//继电器关闭
TIM_SetCompare1(TIM3,0);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,14);//关
}
else if(b[1]>=temp_low&b[1]<temp_high)
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,1000);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,12);//中
}
else if(b[1]>=temp_high)
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,1500);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,13);//快
}
}
if(mode==2)//定时
{
OLED_DISPLAY_16x16(0,0*16,0);//模
OLED_DISPLAY_16x16(0,1*16,1);//式
OLED_DISPLAY_8x16(0,5*8,58);//:
OLED_DISPLAY_16x16(0,4*16,7);//定
OLED_DISPLAY_16x16(0,5*16,8);//时
OLED_DISPLAY_16x16(4,0*16,15);//阈
OLED_DISPLAY_16x16(4,1*16,16);//值
OLED_DISPLAY_8x16(4,5*8,58);//:
OLED_DISPLAY_8x16(4,6*8,set_hour/10+0x30);//显示小时阈值
OLED_DISPLAY_8x16(4,7*8,set_hour%10+0x30);
OLED_DISPLAY_8x16(4,8*8,58);//:
OLED_DISPLAY_8x16(4,9*8,set_min/10+0x30);//显示分钟阈值
OLED_DISPLAY_8x16(4,10*8,set_min%10+0x30);
OLED_DISPLAY_8x16(4,11*8,58);//:
OLED_DISPLAY_8x16(4,12*8,set_sec/10+0x30);//显示秒钟阈值
OLED_DISPLAY_8x16(4,13*8,set_sec%10+0x30);
if(set_time==1){
if(set_hour==0&set_min==0&set_sec==0)
{
RELAY_1(0);//继电器关闭
TIM_SetCompare1(TIM3,0);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,14);//关
set_time=0;
}
else
{
RELAY_1(1);//继电器打开
TIM_SetCompare1(TIM3,1500);
OLED_DISPLAY_16x16(2,0*16,9);//风
OLED_DISPLAY_16x16(2,1*16,10);//速
OLED_DISPLAY_8x16(2,5*8,58);//:
OLED_DISPLAY_16x16(2,5*16,13);//快
}
}
}
}
}
#ifndef __CHS_16x16_H
#define __CHS_16x16_H
uc8 GB_16[] = { // 数据表
//"模", 0
0x10,0x10,0xD0,0xFF,0x94,0x14,0xE4,0xBF,
0xA4,0xA4,0xA4,0xBF,0xF4,0x26,0x04,0x00,
0x04,0x03,0x00,0xFF,0x08,0x89,0x8B,0x4A,
0x2A,0x1E,0x2A,0x2A,0x4B,0xC8,0x48,0x00,
//"式", 1
0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,
0xFF,0x10,0x12,0x14,0x10,0x18,0x10,0x00,
0x00,0x20,0x60,0x20,0x1F,0x10,0x10,0x08,
0x01,0x06,0x18,0x20,0x40,0x80,0x70,0x00,
//"手", 2
0x00,0x04,0x24,0x24,0x24,0x24,0x24,0xFC,
0x22,0x22,0x22,0x33,0x22,0x00,0x00,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,
0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x00,
//"动", 3
0x20,0x24,0x24,0xE4,0x26,0x34,0x20,0x10,
0x10,0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,
0x08,0x1C,0x0B,0x08,0x08,0x8A,0x4C,0x30,
0x0C,0x03,0x40,0x80,0x40,0x3F,0x00,0x00,
//"温", 4
0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92,
0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,
0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,
//"控", 5
0x10,0x10,0x10,0xFF,0x90,0x50,0x0C,0x44,
0x24,0x15,0x06,0x14,0x24,0x54,0x0C,0x00,
0x02,0x42,0x81,0x7F,0x00,0x40,0x42,0x42,
0x42,0x42,0x7E,0x42,0x43,0x62,0x40,0x00,
//"度", 6
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5,
0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00,
0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,
0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00,
//"定", 7
0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0xE6,
0x24,0x24,0x34,0x24,0x04,0x14,0x0C,0x00,
0x80,0x40,0x20,0x1F,0x20,0x40,0x40,0x7F,
0x42,0x42,0x43,0x42,0x40,0x60,0x20,0x00,
//"时", 8
0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,
0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,
0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00,
//"风", 9
0x00,0x00,0xFE,0x02,0x0A,0x12,0x62,0x82,
0x62,0x1A,0x02,0xFF,0x02,0x00,0x00,0x00,
0x80,0x40,0x3F,0x20,0x10,0x08,0x06,0x01,
0x06,0x18,0x00,0x3F,0x40,0x80,0xE0,0x00,
//"速", 10
0x40,0x42,0x44,0xCC,0x00,0xF4,0x94,0x94,
0x94,0xFF,0x94,0x94,0x94,0xF6,0x04,0x00,
0x00,0x40,0x20,0x1F,0x20,0x51,0x48,0x44,
0x42,0x7F,0x42,0x44,0x4C,0x61,0x20,0x00,
//"慢", 11
0x40,0x38,0x00,0xFF,0x08,0xD0,0x5F,0x55,
0xD5,0x55,0xD5,0x55,0x5F,0xE0,0x40,0x00,
0x00,0x00,0x00,0xFF,0x00,0x83,0x8A,0x5A,
0x2B,0x2A,0x2B,0x5A,0x4A,0x83,0x80,0x00,
//"中", 12
0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xFF,
0x08,0x08,0x08,0x08,0x08,0xFC,0x08,0x00,
0x00,0x03,0x01,0x01,0x01,0x01,0x01,0xFF,
0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,
//"快", 13
0x80,0x70,0x00,0xFF,0x10,0x20,0x10,0x10,
0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,0x00,
0x00,0x00,0x00,0xFF,0x82,0x42,0x22,0x1A,
0x07,0x0A,0x12,0x22,0x43,0xC2,0x42,0x00,
//"关", 14
0x00,0x10,0x10,0x11,0x12,0x1C,0x10,0xF0,
0x10,0x18,0x14,0x13,0x1A,0x90,0x00,0x00,
0x81,0x81,0x41,0x41,0x21,0x11,0x0D,0x03,
0x0D,0x11,0x21,0x21,0x41,0xC1,0x41,0x00,
//"阈", 15
0x00,0xFC,0x11,0xD2,0x50,0x52,0xD2,0x12,
0xFE,0x12,0x16,0x9A,0x12,0xFF,0x02,0x00,
0x00,0xFF,0x10,0x17,0x14,0x14,0x57,0x20,
0x10,0x0F,0x12,0x39,0x80,0xFF,0x00,0x00,
//"值", 16
0x80,0x40,0x20,0xF8,0x07,0x04,0xE4,0xA4,
0xA4,0xBF,0xA4,0xA4,0xF6,0x24,0x00,0x00,
0x00,0x00,0x00,0xFF,0x40,0x40,0x7F,0x4A,
0x4A,0x4A,0x4A,0x4A,0x7F,0x40,0x40,0x00,
//"湿", 17
0x10,0x22,0x64,0x0C,0x80,0xFE,0x92,0x92,
0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x04,0x04,0xFE,0x41,0x44,0x48,0x50,0x7F,
0x40,0x40,0x7F,0x50,0x48,0x64,0x40,0x00,
};