文章目录
- 一、风量控制器
- 1.题目要求
- 2.思路
- 3.仿真图
- 4.仿真程序
- 4.1 程序说明
- 4.2 主函数
- 4.2 OLED显示函数
- 4.3 按键函数
- 三、总结
一、风量控制器
1.题目要求
设计一个可以风量控制器进行通信的控制板,该控制板由1块OLED显示屏和8个物理按键组成,其中显示屏用来显示当前变风量控制器运行状况及风速。
其中物理按键分别的功能是灯照明开关,风量增大设置,风量减少设置,风机开关,报警开关,节能模块开关,电源开关,静音开关。
2.思路
首先,要有一个OLED显示屏,刚好Proteus里面有IIC的OLED显示屏。显示屏主要用来显示风量的大小,这里我暂定等级大小为0-15级。
然后接8个按键上去进去控制,按键识别为按下引脚识别为低电平,这里注意按键和按键间有一定的逻辑。只有当电源开关开启的时候,其他按键按下才能执行任务;只有当风机开关开启的时候,风量才能增大或者减小。静音模式和报警是相对的,只有当静音模式的时候才能按下报警按键,也只有当报警模式的时候才能按下静音模式按键。
3.仿真图
引脚说明:
主控芯片:STM32F103C8
测试Led:PC13
Uart1:9600(PA9:tx1,PA10:rx1)
OLED显示屏:SCL(PB8),SDA(PB9)
KEY按键:
KEY1(PA0)
KEY2(PA1)
KEY3(PA2)
KEY4(PA3)
KEY5(PA4)
KEY6(PA5)
KEY7(PA6)
KEY8(PA7)
下面是仿真视频演示:
Air volume controller
4.仿真程序
4.1 程序说明
主控芯片:STM32F103C8
HICK:64MHZ
Systick: 1ms
测试Led:PC13
Uart1:9600(PA9:tx1,PA10:rx1)
OLED显示屏:SCL(PB8),SDA(PB9)
KEY按键:
KEY1(PA0)
KEY2(PA1)
KEY3(PA2)
KEY4(PA3)
KEY5(PA4)
KEY6(PA5)
KEY7(PA6)
KEY8(PA7)
模拟RS485的串口协议如下:
灯照明开关 *KEY1H,H为0:关闭灯照明,H为1:打开灯照明
风量增大设置 *KEY21,风量增大一级,最大15级
风量减少设置 *KEY31,风量减少一级,最小0级
风机开关 *KEY4H,H为0:关闭风机,H为1:打开风机
报警开关 *KEY51,开启报警
节能模式开关 *KEY6H,H为0:关闭节能模式,H为1:开启节能模式
电源开关 *KEY7H,H为0:关闭电源,H为1:开启电源
静音开关 *KEY81,关闭报警,开启静音
注意事项:
默认电源开关和风机开关打开,只有当电源开关开启的时候,其他按键按下才能执行任务;只有当风机开关开启的时候,风量才能增大或者减小。
默认静音模式,非报警,只有当静音模式的时候才能按下报警按键,也只有当报警模式的时候才能按下静音模式按键
4.2 主函数
/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
UserSystemInit();//用户配置初始化
while (1)
{
if (stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
{
stSysTime.flg._10ms = Time_millis();
Key_Scan();//按键扫描
OLED_Handel();//OLED显示
}
if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
{
stSysTime.flg._50ms = Time_millis();
}
if (stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
{
stSysTime.flg._100ms = Time_millis();
Receive_data_Handel();//数据接收判断
IWDG_ReloadCounter();//清开门狗
}
if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
{
stSysTime.flg._1s = Time_millis();
Led_Flicker();//灯光闪烁
}
}
}
4.2 OLED显示函数
/*******************************************************************************
* 函数名:OLED_Handel
* 描述 :OLED显示
* 输入 :void
* 输出 :void
* 调用 :初始化
* 备注 :10ms
*******************************************************************************/
void OLED_Handel(void)
{
OLED_ShowString(1, 1, "Air_volume");
OLED_ShowNum(2,12,Air_volume,2);
}
/**
* @brief OLED显示字符串
* @param Line 起始行位置,范围:1~4
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串,范围:ASCII可见字符
* @retval 无
*/
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i++)
{
OLED_ShowChar(Line, Column + i, String[i]);
}
}
/**
* @brief OLED显示数字(十进制,正数)
* @param Line 起始行位置,范围:1~4
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~4294967295
* @param Length 要显示数字的长度,范围:1~10
* @retval 无
*/
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i++)
{
OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
}
}
4.3 按键函数
/*******************************************************************************
* 函数名:Key_Scan
* 描述 :按键扫描
* 输入 :void
* 输出 :void
* 调用 :10ms
* 备注 :
*******************************************************************************/
void Key_Scan(void)
{
if(Key7_IN_Read() == 0)//电源开关
{
if(!KeyState.Press7)
{
if(KeyState.Key7flag)
{
KeyState.Key7flag = 0;
power_en = 0;
printf("\r\n关闭电源");
}
else
{
KeyState.Key7flag = 1;
power_en = 1;
printf("\r\n开启电源");
}
}
KeyState.Press7 = 1;
}
else
{
KeyState.Press7 = 0;
}
if(power_en)
{
if(Key1_IN_Read() == 0)//灯照明开关
{
if(!KeyState.Press1)
{
if(KeyState.Key1flag)
{
KeyState.Key1flag = 0;
printf("\r\n关闭灯照明");
}
else
{
KeyState.Key1flag = 1;
printf("\r\n打开灯照明");
}
}
KeyState.Press1 = 1;
}
else
{
KeyState.Press1 = 0;
}
if(Air_blower_en)
{
if(Key2_IN_Read() == 0)//风量增大设置
{
if(!KeyState.Press2)
{
Air_volume++;
if(Air_volume>15)
{
Air_volume = 15;
}
printf("Air_volume = %d\r\n",Air_volume);
printf("\r\n风量增大一级");
}
KeyState.Press2 = 1;
}
else
{
KeyState.Press2 = 0;
}
if(Key3_IN_Read() == 0)//风量减少设置
{
if(!KeyState.Press3)
{
if(Air_volume == 0)
{
}
else
{
Air_volume--;
}
printf("Air_volume = %d\r\n",Air_volume);
printf("\r\n风量减小一级");
}
KeyState.Press3 = 1;
}
else
{
KeyState.Press3 = 0;
}
}
if(Key4_IN_Read() == 0)//风机开关
{
if(!KeyState.Press4)
{
if(KeyState.Key4flag)
{
KeyState.Key4flag = 0;
Air_blower_en = 0;
printf("\r\n关闭风机");
}
else
{
KeyState.Key4flag = 1;
Air_blower_en = 1;
printf("\r\n打开风机");
}
}
KeyState.Press4 = 1;
}
else
{
KeyState.Press4 = 0;
}
if(Give_an_alarm == 0)
{
if(Key5_IN_Read() == 0)//报警开关
{
if(!KeyState.Press5)
{
Give_an_alarm = 1;
printf("\r\n开启报警");
}
KeyState.Press5 = 1;
}
else
{
KeyState.Press5 = 0;
}
}
if(Key6_IN_Read() == 0)//节能模式开关
{
if(!KeyState.Press6)
{
if(KeyState.Key6flag)
{
KeyState.Key6flag = 0;
printf("\r\n关闭节能模式");
}
else
{
KeyState.Key6flag = 1;
printf("\r\n开启节能模式");
}
}
KeyState.Press6 = 1;
}
else
{
KeyState.Press6 = 0;
}
if(Give_an_alarm == 1)
{
if(Key8_IN_Read() == 0)//静音开关
{
if(!KeyState.Press8)
{
Give_an_alarm = 0;
printf("\r\n关闭报警,开启静音");
}
KeyState.Press8 = 1;
}
else
{
KeyState.Press8 = 0;
}
}
}
}
三、总结
今天主要讲了基于STM32的风量控制器的Proteus仿真。
感谢你的观看!