手把手教你写stm32f103智能风扇 您所在的位置:网站首页 电风扇在电路图中用什么表示出来 手把手教你写stm32f103智能风扇

手把手教你写stm32f103智能风扇

2024-07-04 04:21| 来源: 网络整理| 查看: 265

目录: 1.系统实现目标2.硬件选型和软件准备2.1.硬件选型2.2.软件准备 3.硬件的连接电路4.各个模块的驱动程序4.1.红外传感器的驱动程序4.2.DHT11温湿度传感器的驱动程序4.3.OLED显示模块4.4.舵机的驱动4.5.电机的驱动 5.不同的工作模式5.1.选择模式5.2.手动模式5.3.自动模式 6.总结

1.系统实现目标

本系统可以分为两个模式来进行运行,分别为手动模式和自动模式,同时,在上电进入系统后,还会有一个模式选择的界面产生。

模式选择:在此界面中,可以通过按键K1来控制模式选择,两个模式分别为手动模式和自动模式;通过按键K2可以进入模式。手动模式:在手动模式中,可以通过K1来进行速度调整,分为低速、中速和高速,可以通过K3来控制是否为摇头状态。自动模式:在自动模式下,可以通过红外传感器来检测周围是否有人,通过温湿度传感器来测试周围环境温度和湿度,若达到条件就会触发风扇进行运转,风速也有低速模式、中速模式、高速模式。 所有没写出的代码都太长,所以都在链接里面,可以自己下载,积分都设置为0了. 2.硬件选型和软件准备 2.1.硬件选型

1.最小系统板 这次项目使用的板子是stm32f103c8t6最小系统板,这个板子在tb上都能够买到,随便一个最小系统板都可以。 在这里插入图片描述 2.显示模块 显示模块是使用的0.96英寸的OLED屏幕,注意是使用的IIC通信协议的OLED屏幕,不是使用SPI总线协议的。买的时候要看清楚。 在这里插入图片描述 3.温度传感器 温湿度传感器使用的是DHT11温湿度传感器,用来采集环境的温湿度,最主要是用来采集温度。 在这里插入图片描述 4.红外模块 红外模块是用来检测风扇前是否有人的。 在这里插入图片描述 5.电机驱动模块 本次实验用的电机驱动模块是使用的大功率MOS管。 在这里插入图片描述 6.舵机 舵机这个元器件主要是用来实现风扇摆头这个功能。 在这里插入图片描述 7.电机 这次的电机是使用的空心杯这个电机,转速快,功率小。 在这里插入图片描述 以上的元件就是这次项目用到的主要元器件。

2.2.软件准备

当我们把所有的硬件都准备完活以后,就要开始编写软件代码,编写软件代码之前,需要进行软件环境的准备,如果没有软件环境,我把软件环境放在了以下连接中: https://download.csdn.net/download/nbbskk/87239099

3.硬件的连接电路

在这里插入图片描述 硬件的连接电路如上 其中大功率MOS管需要注意,需要外接电源,不能使用单片机提供的5V引脚,因为如果这个mos管直接连接单片机中的5V引脚的话,就会造成程序的崩溃。

4.各个模块的驱动程序 4.1.红外传感器的驱动程序

红外传感器模块主要是用来检测前方是否有人存在,主要是用在自动模式下的。 .c文件

#include "stm32f10x.h" // Device header void Infrared_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); // GPIO_ResetBits(GPIOA,GPIO_Pin_1); } //PB10口来检测红外避障模块的功能,如果检测到障碍物返回1,未检测到障碍物返回2 uint16_t Get_Sign(void) { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0) { return 1; } else { return 2; } }

.h文件

#ifndef __INFRARED_H #define __INFRARED_H void Infrared_Init(void); uint16_t Get_Sign(void); #endif 4.2.DHT11温湿度传感器的驱动程序

DHT11温湿度传感器主要是用来检测环境温度的。 .c文件

#include "stm32f10x.h" // Device header #include "dht11.h" #include "oled.h" #include "delay.h" extern uint8_t dat[5]; void dht11_package_show(void)//DHT11显示模式打包 { //显示温度和湿度字符 OLED_ShowChinese(10,0,9,16,1); OLED_ShowChinese(26,0,8,16,1); OLED_ShowString(42,0,":",16,1); OLED_ShowChinese(10,16,10,16,1); OLED_ShowChinese(26,16,8,16,1); OLED_ShowString(42,16,":",16,1); OLED_Refresh(); if(DHT_Read()) { //显示湿度 OLED_ShowNum(52,16,dat[0],2,16,1); OLED_ShowString(70,16,"%",16,1); // OLED_ShowNum(50,0,dat[1],5,16,1); //显示温度 OLED_ShowNum(52,0,dat[2],2,16,1); OLED_DrawPoint(70,12,1); OLED_ShowNum(74,0,dat[3],1,16,1); OLED_Refresh(); delay_ms(10); } }

.h文件

#ifndef __DHT11_PACKAGE_H #define __DHT11_PACKAGE_H void dht11_package_show(void); #endif 4.3.OLED显示模块

OLED显示模块主要是用来显示和调试用的

OLED显示程序包括字库程序太大,放到以下连接中去下载。 https://download.csdn.net/download/nbbskk/87238933

4.4.舵机的驱动

舵机主要是用在切换风扇扫风和不扫风模式的 .c文件

#include "stm32f10x.h" // Device header void SG90_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitTypeDefStrucutre; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 ; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); TIM_InternalClockConfig(TIM3);//选择内部时钟 //时基单元配置 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period=20000-1; //ARR自动装载值 TIM_TimeBaseInitStructure.TIM_Prescaler=72-1; //PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //输出比较器初始化 TIM_OCInitTypeDefStrucutre.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitTypeDefStrucutre.TIM_OCPolarity= TIM_OCPolarity_High; TIM_OCInitTypeDefStrucutre.TIM_OutputState= TIM_OutputState_Enable ; TIM_OCInitTypeDefStrucutre.TIM_Pulse=0; //CCR TIM_OC1Init(TIM3, &TIM_OCInitTypeDefStrucutre); TIM_Cmd(TIM3,ENABLE); } void setccr(uint16_t crrnum) { TIM_SetCompare1(TIM3,crrnum);//设置舵机的旋转,舵机旋转的crrnum最大为2500,最小为500 }

.h文件

#ifndef __SG90_H #define __SG90_H void SG90_Init(void); void setccr(uint16_t crrnum); #endif 4.5.电机的驱动

电机用来充当风扇

.c文件

#include "stm32f10x.h" // Device header void key_PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitTypeDefStrucutre; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 ; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//你 GPIO_Init(GPIOB,&GPIO_InitStructure); TIM_InternalClockConfig(TIM3);//选择内部时钟 //时基单元配置 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period=20000-1; //ARR自动装载值 TIM_TimeBaseInitStructure.TIM_Prescaler=72-1; //PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //输出比较器初始化 TIM_OCInitTypeDefStrucutre.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitTypeDefStrucutre.TIM_OCPolarity= TIM_OCPolarity_High; TIM_OCInitTypeDefStrucutre.TIM_OutputState= TIM_OutputState_Enable ; TIM_OCInitTypeDefStrucutre.TIM_Pulse=0; //CCR TIM_OC3Init(TIM3, &TIM_OCInitTypeDefStrucutre); TIM_Cmd(TIM3,ENABLE); } void setccr3(uint16_t crrnum3) { TIM_SetCompare3(TIM3,crrnum3);//设置风扇的转速 }

.h文件

#ifndef __KEY_PWM_H #define __KEY_PWM_H void key_PWM_Init(void); void setccr3(uint16_t crrnum3); #endif 5.不同的工作模式 5.1.选择模式

当各个模块的驱动程序写好以后,就可以进行模式的选择了,通过对手动模式和自动模式的选择来进入到不同的模式当中。 模式选择功能的实现主要是通过按键和标志位来进行实现的,这个项目是通过四个按钮来进行控制的。 其中,当在模式选择界面的时候,需要两个按钮,分别接到GPIOA_2和GPIOA_3上,一端接低电平,另一端接IO口。 选择模式是通过以下的代码来实现的

show_words3();//显示选择界面 option();//进行模式选择 if(flago==0)//显示手动模式 { OLED_ShowChinese(50,30,4,16,1); OLED_ShowChinese(66,30,5,16,1); OLED_Refresh(); } else if(flago==1)//显示自动模式 { OLED_ShowChinese(50,30,6,16,1); OLED_ShowChinese(66,30,5,16,1); OLED_Refresh(); } action();//接收进入模式信息 if(flago==0&&go==1)//进入手动模式 { manual_mode_Init();//手动模式初始化 while(1) { // manual_go(); if(flag_go2==0) //进入循环后,未按下按键跳回选择界面 { manual_go();//进入手动模式 } else if(flag_go2==1)//跳出循环界面 { OLED_Clear(); flago=0; go=0; flag_go2=0; break; } } } else if(flago==1&&go==1)//进入自动模式 { auto_mode_Init();//自动模式初始化 while(1) { // auto_go(); if(flag_go2==0) { auto_go(); } else if(flag_go2==1) { OLED_Clear(); flag_go2=0; flago=1; go=0; break; } } }

其中单片机上电以后就会进入模式选择界面,通过option函数来实现手动模式和自动模式的选择,此时液晶屏上会显示是手动模式还是自动模式。 option函数通过以下代码来实现的

//给PA2输入低电平进行模式的选择 void option(void) { if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==0) { delay_ms(30); if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==0) { delay_ms(30); u++; flago=u%2; } } // return flago; }

option函数主要是通过连接到PA2口的按钮来实现的。

当选择到合适的模式的时候,那么就通过action函数来进入这个模式。 action函数是由以下程序来实现的

//给PA3输入低电平,进入此模式 void action(void) { if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)==0) { delay_ms(30); if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)==0) { delay_ms(30); go=1; } } // return go; }

主要是通过PA3口来控制进入。

5.2.手动模式

进入手动模式以后,主要就是通过按钮来实现风扇是否扫风、风扇转速控制主要是通过PA2口的按钮和PB11口的按钮来实现。

当PA2口的按钮按下后,可以实现停止->低速->中速->高速->停止的切换,如此可以进行循环,这一步并没有加上减速的操作,是为了降低按钮的使用量。当PB11口的按钮按下以后,可以实现扫风和不扫风的切换。同时如果按下PA8口的按键的话,程序就会跳回选择模式的界面。

手动模式是由以下程序来实现的

uint16_t mo=0; uint16_t deg=0; uint8_t flags_it=0; void manual_mode_Init(void) { key_PWM_Init(); add_init(); delay_init(); OLED_Init(); key_it_Init(); SG90_Init(); setccr(1500); //显示风速两个字 OLED_ShowChinese(20,0,12,16,1); OLED_ShowChinese(36,0,7,16,1); OLED_ShowString(51,0,":",16,1); OLED_Refresh(); } void manual_go(void) { uint16_t i=0; flags_it=Get_key_it_flag();//得到是否让风扇转动信号 // mo=add_sub1 (); // OLED_ShowNum(40,0,flags_it,2,16,1); if(flags_it==1)//进入扫风的模式 { //如果扫风,显示扫风模式四个字 OLED_ShowChinese(22,25,11,16,1); OLED_ShowChinese(38,25,12,16,1); OLED_ShowChinese(54,25,0,16,1); OLED_ShowChinese(70,25,1,16,1); OLED_Refresh(); //正向扫风 for(i=500;i break; } mo=add_sub1 ();//控制风扇的转速 deg=mo*830; setccr3(deg);//设置风扇转速 setccr(i); delay_ms(100); mo=add_sub1 (); if(mo==0) { //显示停止两个字 OLED_ShowChinese(58,0,16,16,1); OLED_ShowChinese(74,0,17,16,1); OLED_Refresh(); } else if(mo==4) { //显示低速两个字 OLED_ShowChinese(58,0,13,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==8) { //显示中速两个字 OLED_ShowChinese(58,0,14,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==12) { //显示高速两个字 OLED_ShowChinese(58,0,15,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } // OLED_ShowNum(0,0,mo,2,16,1); // OLED_ShowNum(20,0,i,2,16,1); // OLED_ShowNum(0,16,deg,6,16,1); // OLED_Refresh(); } //反向扫风 for(i=2500;i>500;i-=100) { mo=add_sub1 (); flags_it=Get_key_it_flag(); if(flags_it==0) { break; } mo=add_sub1 (); deg=mo*830; setccr3(deg); setccr(i); delay_ms(100); mo=add_sub1 (); if(mo==0) { OLED_ShowChinese(58,0,16,16,1); OLED_ShowChinese(74,0,17,16,1); OLED_Refresh(); } else if(mo==4) { OLED_ShowChinese(58,0,13,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==8) { OLED_ShowChinese(58,0,14,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==12) { OLED_ShowChinese(58,0,15,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } // OLED_ShowNum(0,0,mo,2,16,1); // OLED_ShowNum(20,0,i,2,16,1); // OLED_ShowNum(0,16,deg,6,16,1); // OLED_Refresh(); } } else if(flags_it==0)//风扇不扫风 { OLED_ShowString(22,25," ",16,1); OLED_Refresh(); mo=add_sub1 (); deg=mo*830; setccr3(deg); if(mo==0) { OLED_ShowChinese(58,0,16,16,1); OLED_ShowChinese(74,0,17,16,1); OLED_Refresh(); } else if(mo==4) { OLED_ShowChinese(58,0,13,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==8) { OLED_ShowChinese(58,0,14,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } else if(mo==12) { OLED_ShowChinese(58,0,15,16,1); OLED_ShowChinese(74,0,7,16,1); OLED_Refresh(); } // OLED_ShowNum(0,32,mo,6,16,1); // OLED_ShowNum(0,48,deg,6,16,1); // OLED_Refresh(); } } 5.3.自动模式

自动模式我设计的比较复杂。

首先会检测左前是否有人,如果左前有人,就只会在左半边进行扫风;如果检测到左前没人,会检测右前是否有人,如果右前有人,只会在右半边进行扫风;如果左前和右前都有人,才会180度扫风;如果左前和右前都没人,那就不会扫风。 同时,也会进行环境温度的检测如果环境温度>27度,那么就会进入低速模式;如果环境温度>29度,那么就会进入中速模式;如果环境温度>31度,那么就会进入高速模式;

同时,每隔10分钟就会检测一次周围是否有人,进行扫风模式的刷新。 同样,如果按下PA8口的按键,程序会跳回选择模式。 其中自动模式是由以下程序实现的

void auto_mode_Init(void) { speed_control_Init(); //显示速度两个字 OLED_ShowChinese(10,32,7,16,1); OLED_ShowChinese(26,32,8,16,1); OLED_ShowString(42,32,":",16,1); OLED_Refresh(); setccr(1500); } void auto_go(void) { dht11_package_show();//温湿度的获取和显示 if(dat[2]>=27&&dat[2] medium_speed(); } if(dat[2]>=31)//温度大于31度,进入高转速模式 { high_speed(); } }

其中low_speed()、medium_speed()、high_speed()就是我具体实现的自动转速实现的代码。 这些代码太大,放到以下连接中去下载。

https://download.csdn.net/download/nbbskk/87238938

6.总结

智能风扇系统的代码和设计思路就如上所示,如果想获得软件设计流程,可以参考我账号中的另一篇博客。 如果想要完整的源码,可以私信我。

注: 其中的汉字显示的代码都在oled.c、oled.h和oledfont.h中,如果想要显示自己想要的汉字,需要在字体生成软件中进行生成,字体生成软件我放在下面的连接中了。 https://download.csdn.net/download/nbbskk/87239085

其中的使用方法如下: 在这里插入图片描述 然后将生成的代码插入到oledfont.h中 在这里插入图片描述 格式和上面的代码保持一致即可



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有