STM32可视化风扇控制器(按键、电机、LED灯、OLED屏)

一、简介

本文主要介绍了运用STM32实现可视化风扇的过程。由于使用HAL库编程,其中需要用到的软件有STM32CubeMX和Keil5。本项目的实现需要中断系统和定时器的相关知识基础,并应用外部中断及PWM输出功能。同时本文也涉及到字模软件Pctolcd2002的简单使用,可借此进一步了解OLED屏作为显示模块的实际工作原理。


二、项目要求描述

设计一款可视风扇,要求如下:

  1. 按下按键1,风扇转速为低速,同时,LED灯出现流水效果1,OLED屏幕显示“风速:低速(及对应占空比)”;
  2. 按下按键2,风扇转速为中速,同时,LED灯出现流水效果2,OLED屏幕显示“风速:中速(及对应占空比)”;
  3. 按下按键3,风扇转速为低速,同时,LED灯出现流水效果3,OLED屏幕显示“风速:高速(及对应占空比)”。

三、 外设设置

1、引脚分配

本项目所包含的电子元件:STM32F103ZET6,L9110S(直流电机),板载LED灯,OLED屏。

开关 K1 PE2
  K2 PE3
  K3 PE4
  K4 PA0
电机 VCC 5V
  GND GND
  A PA15
  B PC13
LED灯 LD1 PC0
  LD2 PC1
  LD3 PC2
  LD4 PC3
OLED屏 VCC 3.3V
  GND GND
  SCL PB10
  SDA PB11

2、按键开关

1)GPIO:将四个按键K1——K4引脚模式设置为外部中断EXTI,均为上升沿触发。K4初始引脚拉低,其余中断引脚拉高,在CubeMX中相应引脚的配置如图所示。

a4124a635e5a420a9e72256c72ccf90a.png

5b553b535a2a4507aa28c62b23136f74.png


2)NVIC:将四个按键的中断使能全部勾选。不设置中断优先级,而是使用默认的中断优先级。

f6fff92129b9459d9719d4bb7769973c.png

3、风扇电机

1)GPIO:启用定时器2的CH1通道,可给PA0或PA15配置PWM输出功能。由于PA0用作按键K4的输出引脚,故将PA15配置位复用推挽输出引脚,输出PWM波。PC13配置为通用推挽,置低电平。

1e49718efa6343bd8e8ae7f5a6024b17.png

c57dd8afe86543e1a4d9f7b482a57967.png


2)PWM信号周期及占空比的计算公式:

T=(PSC+1)*(ARR+1)/TIMx_CLK ···式一

Duty=CCR/(ARR+1)*100% ··········式二

定时器2的定时时钟TIM2_CLK为72MHZ,若设PWM信号的周期为10ms,根据式一可以设置预分频系数PSC为7199,自动重载值为99。同时,根据式二,将占空比Duty设为0,即写入捕获/比较寄存器CCR的初值为0,方便在程序编写中使用__HAL_TIM_SET_COMPARE()修改占空比的值,从而实现风扇档位的切换。

d3ae8faf417349c09eaa6f768271302a.png

14fd36ef87474f08a642829c3ec5af7b.png

4、板载LED灯

GPIO:将四个LED灯LD1——LD4的引脚模式设为推挽输出,初始电平置高。

27ec864da8584a91bc76848ca8a60963.png

5、OLED屏

1)GPIO:将I2C2通道打开,可知PB10为对应通道SCL引脚,PB11为对应通道SDA引脚,硬件对应接线即可。

38df0fccb6b14936aa59f16bb8cca7cf.png

8d7c04c0b1634ca989f05dbf5e3641cc.png


2)字模提取:在PCtoLCD2002完美版的字符模式中单击选项,打开字模选项,选择C51格式,点击确定。把项目要求中在oled屏上需要显示的汉字打在输入框中,点击生成字模。

4184635a539f46a6aa290bf919ca007b.png

18eca42ecca644aa87478b4195ce7968.png


3)MDK工程:将生成的字模复制,并粘贴替换在Keil中oledfont.h里汉字库数组里的内容。

90abba9ba7c0416483251402daa43ff9.png


四、程序编写

1、编写思路

1)按键开关:设置外部中断,运用三个按键实现切换风扇的不同档位,一个按键留作复位(关闭),符合日常风扇的工作运转。

2)风扇电机:初始和复位状态下,A引脚PWM占空比为0,B引脚置低电平,双LOW状态实现了风扇的停止;在实际代码编写中,通过改变占空比的值,不同程度地给A引脚置高电平,从而实现了正转调速。

3)板载LED灯:通过按键消除标志位的方法,实现了切换不同流水灯的效果。

4)OLED屏:作为显示模块,将项目要求中相应的汉字及字符串分别通过不同按键实现,达到可视化的效果。

2、程序代码

生成MDK工程后,进行应用程序的编写。由于篇幅有限,这里重点把用户添加或修改的代码列举出来。具体代码如下图程序清单所示。

/* Includes ------------------------------------------------------------------*/
#include "main.h" //引入库函数
#include "i2c.h"
#include "tim.h"
#include "gpio.h"
#include "oled.h"

/* USER CODE BEGIN PV */
volatile unsigned char ET=0; //设立标志位,初值置0
/* USER CODE END PV */

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_I2C2_Init();
  OLED_Init();
  OLED_Clear();

  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); //将定时器2的通道一打开
	HAL_GPIO_WritePin(GPIOC,B_Pin,GPIO_PIN_RESET); //将电机的B引脚置低电平
	    OLED_ShowCHinese(0,2,6); //初始状态下,oled屏上显示“Duty=0% 小朱可视风扇”
		OLED_ShowCHinese(16,2,7);
		OLED_ShowCHinese(32,2,8);
		OLED_ShowCHinese(48,2,9);
		OLED_ShowCHinese(64,2,0);
		OLED_ShowCHinese(80,2,10);
		OLED_ShowString(0,0,"Duty:0%",sizeof("Duty:0%")); 
  /* USER CODE END 2 */

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1) //主函数
  {
    /* USER CODE END WHILE */
		
    /* USER CODE BEGIN 3 */
		if(ET==0) //如果标志位置0,所有灯均为熄灭状态
		{
		HAL_GPIO_WritePin(GPIOC,LD1_Pin|LD2_Pin|LD3_Pin|LD4_Pin,GPIO_PIN_SET);
		}

		else if(ET==1) //如果标志位置1,前两灯为流水灯状态
		{
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD2_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin|LD2_Pin);
		HAL_Delay(500);
		}
		
		else if(ET==2) //如果标志位置2,前三灯为流水灯状态
		{
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD2_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD3_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin|LD2_Pin|LD3_Pin);
		HAL_Delay(500);
		}
		
		else if(ET==3) //如果标志位置3,前四灯为流水灯状态
		{
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD2_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD3_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD4_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOC,LD1_Pin|LD2_Pin|LD3_Pin|LD4_Pin);
		HAL_Delay(500);
		}
  }
  /* USER CODE END 3 */

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //中断函数
{
	switch(GPIO_Pin)
	{
		case K1_Pin: //按下按键1,oled屏显示“Duty:30% 风速:低速”
		OLED_Clear();
		OLED_ShowCHinese(0,2,0);
		OLED_ShowCHinese(16,2,1);
		OLED_ShowCHinese(32,2,2);
		OLED_ShowCHinese(48,2,3);
		OLED_ShowCHinese(64,2,1);
		OLED_ShowString(0,0,"Duty:30%",sizeof("Duty:30%"));
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,30); //修改电机占空比为30%
		ET=1; //标志位置1
		break;
		
		case K2_Pin: //按下按键2,oled屏显示“Duty:60% 风速:中速”
		OLED_Clear();
		OLED_ShowCHinese(0,2,0);
		OLED_ShowCHinese(16,2,1);
		OLED_ShowCHinese(32,2,2);
		OLED_ShowCHinese(48,2,4);
		OLED_ShowCHinese(64,2,1);
		OLED_ShowString(0,0,"Duty:60%",sizeof("Duty:60%")); 
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,60); //修改电机占空比为60%
		ET=2; //标志位置2
		break;
		
		case K3_Pin: //按下按键3,oled屏显示“Duty:90% 风速:高速”
		OLED_Clear();	
		OLED_ShowCHinese(0,2,0);
		OLED_ShowCHinese(16,2,1);
		OLED_ShowCHinese(32,2,2);
		OLED_ShowCHinese(48,2,5);
		OLED_ShowCHinese(64,2,1);
		OLED_ShowString(0,0,"Duty:90%",sizeof("Duty:90%")); 
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,90); //修改电机占空比为90%
		ET=3; //标志位置3
		break;
		
		case K4_Pin: //按下按键4,oled屏显示“Duty:0% 小朱可视风扇”
		OLED_Clear();	
		OLED_ShowCHinese(0,2,6);
		OLED_ShowCHinese(16,2,7);
		OLED_ShowCHinese(32,2,8);
		OLED_ShowCHinese(48,2,9);
		OLED_ShowCHinese(64,2,0);
		OLED_ShowCHinese(80,2,10);
		OLED_ShowString(0,0,"Duty:0%",sizeof("Duty:0%"));
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,0); //修改电机占空比为0%
		ET=0; //标志位置0
		break;
	}
}
/* USER CODE END 4 */

 

 

 

 

 

 

 

作者:小朱在长旅

物联沃分享整理
物联沃-IOTWORD物联网 » STM32可视化风扇控制器(按键、电机、LED灯、OLED屏)

发表评论