> 文档中心 > STM32PWM--基于HAL库(第十一届蓝桥杯嵌入式省赛)

STM32PWM--基于HAL库(第十一届蓝桥杯嵌入式省赛)

文章目录

  • 前言
  • 一、CubeMX配置(第十三届模拟题完整版)
  • 二、代码相关定义、声明
    • 1.函数声明
    • 2.宏定义
    • 3.变量定义
  • 三、主要函数
    • 1.按键相关
    • 2.数据更改
    • 3.LCD更新显示
    • 4.模式更改
    • 5.LED状态更新
    • 6.PWM输出
    • 7.Main函数
  • 四、实验结果
  • 五、源码(转载请注明出处)
  • 总结

前言

相关说明:

开发板:CT117E-M4(STM32G431RB 蓝桥杯嵌入式比赛板)
开发环境: CubeMX+Keil5
涉及题目:第十一届蓝桥杯嵌入式省赛
题目难点:相对容易,较少难点
(本次项目编写运用了模块化编程,更有利于代码阅读与理解。)


CubeMX配置、主要函数代码及说明:

一、CubeMX配置(第十三届模拟题完整版)

1.使能外部高速时钟:在这里插入图片描述

2.配置时钟树:在这里插入图片描述

3.GPIO:

在这里插入图片描述

4.TIM3、TIM17(PWM):在这里插入图片描述
在这里插入图片描述

5.TIM6(0.5s中断):在这里插入图片描述

6.ADC(获取R37电压值):在这里插入图片描述

7.NVIC(使能TIM6中断):在这里插入图片描述

二、代码相关定义、声明

1.函数声明

main.cvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim);//定时器中断函数void LCD_Init_Show(void);//LCD初始化界面void LCD_Refresh(uint8_t page);//LCD更新函数void Data_change(uint8_t dat);//数据改变函数void LED_Refresh(void);//LED更新函数void Mode_Change(void);//模式改变函数tim.hvoid PWM_OutPut(uint16_t PA6_pulse,uint16_t PA7_pulse);//PWM输出配置gpio.hvoid KEY_Scan(void);//按键扫描void LED_AllClose(uint8_t *LED_close);//LED关闭adc.hdouble ADC_GetValue(void);//获取R37电压值

2.宏定义

gpio.h#define LED_GPIO_PORT GPIOC#define LED1_GPIO_PINGPIO_PIN_8#define LED2_GPIO_PINGPIO_PIN_9#define LED3_GPIO_PINGPIO_PIN_10#define LED4_GPIO_PINGPIO_PIN_11#define LED5_GPIO_PINGPIO_PIN_12#define LED6_GPIO_PINGPIO_PIN_13#define LED7_GPIO_PINGPIO_PIN_14#define LED8_GPIO_PINGPIO_PIN_15#define ON GPIO_PIN_RESET#define OFFGPIO_PIN_SET#define LED1(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED1_GPIO_PIN,a)#define LED2(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED2_GPIO_PIN,a)#define LED3(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED3_GPIO_PIN,a)#define LED4(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED4_GPIO_PIN,a)#define LED5(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED5_GPIO_PIN,a)#define LED6(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED6_GPIO_PIN,a)#define LED7(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED7_GPIO_PIN,a)#define LED8(a)HAL_GPIO_WritePin(LED_GPIO_PORT,LED8_GPIO_PIN,a)#define KEY1_GPIO_PORT GPIOB#defineKEY1_GPIO_PIN  GPIO_PIN_0#define KEY2_GPIO_PORT GPIOB#defineKEY2_GPIO_PIN  GPIO_PIN_1#define KEY3_GPIO_PORT GPIOB#defineKEY3_GPIO_PIN  GPIO_PIN_2#define KEY4_GPIO_PORT GPIOA#defineKEY4_GPIO_PI   GPIO_PIN_0main.h#define PA6 1#define PA7 2

3.变量定义

main.cdouble v_value;//R37的电压值char *pwm_mode="AUTO";//PWM占空比控制模式uint8_t PA6_air=10;//PA6输出PWM的占空比 (10即10%)uint8_t PA7_air=10;//PA7输出PWM的占空比uint8_t air_step=10;//占空比每次改变值uint8_t air_max=90;//最大占空比uint8_t air_min=10;//最小占空比uint8_t page_now=1;//LCD显示页(1为数据页/2为配置页)uint8_t PWM_refresh_flag=0;//PWM更新标志位(每0.5s更新一次)uint8_t LED_close[3]={0,0,0};//LED关闭数组(为1则下标对应LED关闭)char str[30];//组合字符串tim.cTIM_OC_InitTypeDef sConfigOC = {0};//重新配置后需要删除下面函数中的这个语句

三、主要函数

1.按键相关

key.c/* KEY */void Setting_Mode()//配置模式{while(1){if(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET);LCD_Refresh(1);//LCD更新显示break;//退出循环}}else if(HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN)==GPIO_PIN_RESET)//PA6++{HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN)==GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN)==GPIO_PIN_RESET);Data_change(PA6);//PA6数据改变LCD_Refresh(2);//LCD更新显示}}else if(HAL_GPIO_ReadPin(KEY3_GPIO_PORT,KEY3_GPIO_PIN)==GPIO_PIN_RESET)//PA7++{HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY3_GPIO_PORT,KEY3_GPIO_PIN)==GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY3_GPIO_PORT,KEY3_GPIO_PIN)==GPIO_PIN_RESET);Data_change(PA7);//PA7数据改变LCD_Refresh(2);//LCD更新显示}}LED_Refresh();}}void KEY_Scan()//按键扫描{if(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET);LCD_Refresh(2);Setting_Mode();}}else if(HAL_GPIO_ReadPin(KEY4_GPIO_PORT,KEY4_GPIO_PIN)==GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY4_GPIO_PORT,KEY4_GPIO_PIN)==GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(KEY4_GPIO_PORT,KEY4_GPIO_PIN)==GPIO_PIN_RESET);  Mode_Change();}}}

2.数据更改

main.cvoid Data_change(uint8_t dat)//数据更改{switch(dat){case PA6:PA6_air+=air_step;if(PA6_air>air_max)PA6_air=air_min;break;case PA7:PA7_air+=air_step;if(PA7_air>air_max)PA7_air=air_min;break;}}

3.LCD更新显示

main.cvoid LCD_Refresh(uint8_t page)//LCD更新显示{if(page==1)//数据界面{page_now=1;LED_close[2]=0;LCD_DisplayStringLine(Line0,(unsigned char*)"      Data   ");sprintf(str,"    V:%.2fV  ",v_value);LCD_DisplayStringLine(Line2,(unsigned char*)str);sprintf(str,"    Mode:%s  ",pwm_mode);LCD_DisplayStringLine(Line4,(unsigned char*)str);}else if(page==2)//参数界面{page_now=2;LED_close[2]=1;LCD_DisplayStringLine(Line0,(unsigned char*)"      Para   ");sprintf(str,"    PA6:%d%% ",PA6_air);LCD_DisplayStringLine(Line2,(unsigned char*)str);sprintf(str,"    PA7:%d%% ",PA7_air);LCD_DisplayStringLine(Line4,(unsigned char*)str);}}

4.模式更改

main.cvoid Mode_Change()//模式更改{if(strcmp(pwm_mode,"AUTO")==0){pwm_mode="MANU";LED_close[1]=1;}else {pwm_mode="AUTO";LED_close[1]=0;}}

5.LED状态更新

main.c/* LED */void LED_Refresh()//LCD状态更新{LED_AllClose(LED_close); if(strcmp(pwm_mode,"AUTO")==0){LED1(ON);}if(page_now==1){LED2(ON);}}

6.PWM输出

TIM_OC_InitTypeDef sConfigOC = {0};这个结构体在这定义为全局变量,MX重新配置后需要删除tim.c生成函数中的这个语句。

tim.cvoid PWM_OutPut(uint16_tPA6_pulse,uint16_tPA7_pulse)//PWM输出函数{sConfigOC.Pulse=PA6_pulse;HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) ;HAL_TIM_PWM_Init(&htim3);HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);sConfigOC.Pulse=PA7_pulse;HAL_TIM_PWM_ConfigChannel(&htim17, &sConfigOC, TIM_CHANNEL_1) ;HAL_TIM_PWM_Init(&htim17);HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);}

7.Main函数

int main(void){  /* USER CODE BEGIN 1 */  /* USER CODE END 1 */  /* MCU Configuration--------------------------------------------------------*/  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  HAL_Init();  /* USER CODE BEGIN Init */  /* USER CODE END Init */  /* Configure the system clock */  SystemClock_Config();  /* USER CODE BEGIN SysInit */  /* USER CODE END SysInit */  /* Initialize all configured peripherals */  MX_GPIO_Init();  MX_ADC2_Init();  MX_TIM3_Init();  MX_TIM17_Init();  MX_TIM6_Init();  /* USER CODE BEGIN 2 */LCD_Init();//LCD初始化TIM6->SR=0;//定时器更新标志位清零TIM6->CNT=0;//定时器计数值清零HAL_TIM_Base_Start_IT(&htim6);//定时器开始计时v_value=ADC_GetValue();//获取ADC的值PWM_OutPut(v_value/3.3*(9999+1),v_value/3.3*(4999+1));//初始为AUTO模式LCD_Init_Show();//LCD初始化显示  /* USER CODE END 2 */  /* Infinite loop */  /* USER CODE BEGIN WHILE */  while (1)  {    /* USER CODE END WHILE */    /* USER CODE BEGIN 3 */KEY_Scan();//按键扫描v_value=ADC_GetValue();//获取ADC的值LCD_Refresh(1);//LCD更新显示LED_Refresh();//LED更新显示if(PWM_refresh_flag==1)//每0.5S更新一次PWM{PWM_refresh_flag=0;if(strcmp(pwm_mode,"AUTO")==0)//如果为AUTO模式{PWM_OutPut(v_value/3.3*(9999+1),v_value/3.3*(4999+1));}else //如果为Menu模式{PWM_OutPut(PA6_air*1.0/100*(9999+1),PA7_air*1.0/100*(4999+1));}}HAL_Delay(50);//LCD更新延时,减少冲突  }  /* USER CODE END 3 */}

四、实验结果

五、源码(转载请注明出处)

STM32PWM--基于HAL库(第十一届蓝桥杯嵌入式省赛)


总结

以上就是全部内容,如有错误请批评指正。