文章目录
- 一、功能简介
- 二、软件设计
- 三、实验现象
- 联系作者
一、功能简介
本项目使用STM32F103C8T6单片机控制器,使用按键、IIC OLED模块、DS18B20温度传感器、直流电机、红外遥控等。
主要功能:
初始化后进入温度显示界面,系统初始状态为手动模式,关闭定时功能。工作在手动模式下,屏幕右上角会显示手图标,自动模式则不显示;
在手动模式下,可通过按键K1调节风扇档位,系统支持0-3档,0为停止;按下K2键停止,按下K3键切换自动/手动模式,按下K4键进入温度阈值及定时时间设置界面;
按下K4键进入设置功能界面,可通过K3键切换不同功能设置,K1和K2用于调节;比如温度阈值设置为26.5C,开启定时,定时时间设置为0.5小时;设置好后,可按下K4键退出,
此时界面上方会显示一个闹铃图标,当定时时间到达,风扇则关闭,需按下K3键后再按下K4键重新进入定时功能;
在系统运行中,可通过红外遥控器上的K1-K4位置键操作对应功能;
二、软件设计
/*
作者:嗨小易(QQ:3443792007)
*/
//系统数据显示
void sys_data_show(void)
{
u8 buf[6];
u8 settime=0;
reflash_window_show();//刷新固定窗口显示内容
while(1)
{
//未进入设置模式
if(sys_ctrl.set==0)
{
//显示温度
buf[0]=sys_ctrl.temp/100+0x30;
buf[1]=sys_ctrl.temp%100/10+0x30;
buf[2]='.';
buf[3]=sys_ctrl.temp%100%10+0x30;
buf[4]='C';
buf[5]='\0';
u8g2_SetFont(&u8g2,u8g_font_ncenB24);
u8g2_DrawStr(&u8g2,25,50,(char *)buf);
//显示档位
buf[0]=sys_ctrl.lev%10+0x30;
buf[1]='\0';
u8g2_SetFont(&u8g2,u8g2_font_helvB12_tf);
u8g2_DrawStr(&u8g2,20,12,(char *)buf);
}
//进入设置模式显示
else
{
//箭头指向位置
u8g2_SetFont(&u8g2,u8g2_font_helvB12_tf);
u8g2_DrawStr(&u8g2,0,12+sys_ctrl.mode*23,"->");
//显示温度阈值
buf[0]=sys_ctrl.templ/100+0x30;
buf[1]=sys_ctrl.templ%100/10+0x30;
buf[2]='.';
buf[3]=sys_ctrl.templ%100%10+0x30;
buf[4]='C';
buf[5]='\0';
u8g2_DrawStr(&u8g2,20+5*10,12,(char *)buf);
//显示定时状态
if(sys_ctrl.timeflag==0)
u8g2_DrawStr(&u8g2,20+7*10,35,"OFF");
else u8g2_DrawStr(&u8g2,20+7*10,35,"ON ");
//显示定时时间
settime=((float)sys_ctrl.settime/60)*10;
buf[0]=settime/10+0x30;
buf[1]='.';
buf[2]=settime%10+0x30;
buf[3]='H';
buf[4]='\0';
u8g2_DrawStr(&u8g2,20+5*10,58,(char *)buf);
}
u8g2_SendBuffer(&u8g2);
break;
}
}
//系统功能控制
void sys_fun_ctrl(void)
{
//自动模式
if(sys_ctrl.handflag==1 && sys_ctrl.time_over==0)
{
//如果温度低于下限,停止
if(sys_ctrl.temp<sys_ctrl.templ)
sys_ctrl.lev=0;
//随着温度升高(26.5-28.0),档位1
else if(sys_ctrl.temp>=sys_ctrl.templ && sys_ctrl.temp<(sys_ctrl.templ+15))
sys_ctrl.lev=1;
//随着温度升高(28.0-29.5),档位2
else if(sys_ctrl.temp>=(sys_ctrl.templ+15) && sys_ctrl.temp<(sys_ctrl.templ+30))
sys_ctrl.lev=2;
//随着温度升高(29.5以上),档位3
else if(sys_ctrl.temp>=(sys_ctrl.templ+30))
sys_ctrl.lev=3;
}
//开启定时
if(sys_ctrl.timeflag==1)
{
//如果时间到达
if(sys_ctrl.min>=sys_ctrl.settime)
{
sys_ctrl.min=0;
sys_ctrl.lev=0;
TIM_Cmd(TIM3,DISABLE); //关闭定时器
sys_ctrl.timeflag=0;
sys_ctrl.time_over=1;
}
}
//设置占空比
TIM_SetCompare3(TIM4,sys_ctrl.lev*166);
}
/*******************************************************************************
* 函 数 名 : TIM3_IRQHandler
* 函数功能 : TIM3中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void TIM3_IRQHandler(void)
{
static u8 i=0;
static u8 sec=0;
if(TIM_GetITStatus(TIM3,TIM_IT_Update))
{
LED0=!LED0;
i++;
if(i>=2)//1S
{
i=0;sec++;
if(sec>=60)
{
sec=0;sys_ctrl.min++;
}
}
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
//应用控制系统
void sys_app_ctrl(void)
{
u8 i=10;
USART1_Init(115200);
LED_Init();
OLED_Init();
//u8g2初始化
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_stm32_gpio_and_delay); // init u8g2 structure u8g2结构
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,发送init序列到显示器,显示器在此之后处于睡眠模式,
u8g2_SetPowerSave(&u8g2, 0); //开启显示
sys_open_logo_show();//系统开机LOGO显示
DS18B20_Init();
//等待温度数据稳定
while(i--)
{
sys_ctrl.temp=DS18B20_GetTemperture()*10;//保留一位小数
delay_ms(100);
}
KEY_Init();
Hwjs_Init();
TIM3_Init(1000,36000-1); //定时500ms
TIM4_CH3_PWM_Init(500,72-1);//频率是2Kh
TIM_SetCompare3(TIM4,0);
sys_parm_init();//系统参数初始化
while(1)
{
sys_data_get();//系统数据获取
sys_data_show();//系统数据显示
sys_data_set();//系统数据设置
sys_fun_ctrl();//系统功能控制
}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619
联系作者
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。