> 文档中心 > STM32PWM--基于HAL库(第十三届蓝桥杯嵌入式模拟题)

STM32PWM--基于HAL库(第十三届蓝桥杯嵌入式模拟题)

文章目录

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

前言

相关说明:

开发板:CT117E-M4(STM32G431RB 蓝桥杯嵌入式比赛板)
开发环境: CubeMX+Keil5
涉及题目:第十三届蓝桥杯嵌入式模拟题
题目难点:相对较易,主要需掌握调节PWM输出占空比及频率、ADC获取、以及定时器配置


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

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

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

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

3.GPIO:

在这里插入图片描述

4.ADC(检测R37电压值):在这里插入图片描述

5.TIM3(PWM):在这里插入图片描述

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

7.NVIC:在这里插入图片描述

二、代码相关定义、声明

1.函数声明

main.cvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);//定时器回调函数void D_change(void);//D改变规则void LCD_InitShow(void);//LCD初始化显示void LCD_Refresh(void);//LCD显示更新void LED_change(void);//LED2状态改变gpio.hvoid KEY_Scan(void);//按键扫描void LED_AllClose(uint8_t *LED_Close);//LED更新显示adc.hdouble ADC_GetValue(void);//获取R37电压值time.hvoid PWN_OutPut(uint16_t Period,uint16_t Pulse);//配置PWM输出参数

2.宏定义

#define LED_GPIO_PORT GPIOC#define LED1_GPIO_PIN GPIO_PIN_8#define LED2_GPIO_PIN GPIO_PIN_9#define LED3_GPIO_PIN GPIO_PIN_10#define LED4_GPIO_PIN GPIO_PIN_11#define LED5_GPIO_PIN GPIO_PIN_12#define LED6_GPIO_PIN GPIO_PIN_13#define LED7_GPIO_PIN GPIO_PIN_14#define LED8_GPIO_PIN GPIO_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#define KEY1_GPIO_PIN  GPIO_PIN_0#define KEY2_GPIO_PORT GPIOB#define KEY2_GPIO_PIN  GPIO_PIN_1#define KEY3_GPIO_PORT GPIOB#define KEY3_GPIO_PIN  GPIO_PIN_2#define KEY4_GPIO_PORT GPIOA#define KEY4_GPIO_PIN  GPIO_PIN_0

3.变量定义

main.cdouble v_value;//R37电压值uint8_t D;//占空比uint16_t F=1000;//PWM输出频率uint16_t F_step=1000;//F每次改变值uint16_t F_max=10000;//F上限uint16_t F_min=1000;//F下限char str[30];//用于组合字符串uint8_t LCD_RefreshFlag=0;//LCD更新标志位uint8_t LED_Close[3]={1,1,0};//LED关闭字符串(保存LED状态,值为1,则下标对应LED关闭)uint8_t LED2_flag=0;//LED2状态标志位 R37电压>1V时置1uint32_t TIM_Clock=1000000;//定时器6工作频率tim.cTIM_OC_InitTypeDef sConfigOC = {0};//配置该结构体为全局变量,MX配置后删除生成函数中的这句代码

三、主要函数

1.按键扫描

按键按下后的操作封装为函数,可降低函数耦合。

void KEY_Scan(){static uint8_t clock=0;if(HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN)==GPIO_PIN_RESET && !clock)//++{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);Dat_change(add);LCD_Refresh();}}else if(HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN)==GPIO_PIN_RESET && !clock)//--{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);Dat_change(sub);LCD_Refresh();}}else if(HAL_GPIO_ReadPin(KEY3_GPIO_PORT,KEY3_GPIO_PIN)==GPIO_PIN_RESET){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);clock=!clock;LED_Close[1]=!LED_Close[1];LED_AllClose(LED_Close);}}}

2.LED更新显示

将LED灯状态为灭还是亮,保存在LED_Close数组里,LCD就影响不了了,如果数组中值为1,则下标对应LED关闭,否则为开启,理解了逻辑很好写。具体可参考STM32LED–基于HAL库(第七届蓝桥杯嵌入式省赛)。

void LED_AllClose(uint8_t *LED_Close)//LED更新显示{uint8_ti;LED1(ON);LED2(ON);for(i=1;i<3;i++){if(LED_Close[i]){switch(i){case 1:LED1(OFF);break;case 2:LED2(OFF);break;}}}LED3(OFF);LED4(OFF);LED5(OFF);LED6(OFF);LED7(OFF);LED8(OFF);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}

3.PWM输出参数配置

PWM频率=定时器工作频率/重装载值
占空比=Pulse/重装载值*100%

void PWN_OutPut(uint16_t Period,uint16_t Pulse)//第一个参数为频率,第二个参数为占空比{htim3.Init.Period = Period;//频率配置 PWM频率=定时器工作频率/重装载值sConfigOC.Pulse = Pulse;//占空比配置占空比=Pulse/重装载值*100%HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//更改配置后需要重新Start才能生效}

4.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_TIM6_Init();  /* USER CODE BEGIN 2 */LCD_Init();//LCD初始化v_value=ADC_GetValue();//获取R37电压值D_change();//D值初始化LCD_InitShow();//LCD初始化显示LED_change();//LED状态改变TIM6->SR=0;//关闭定时器6中断标志位TIM6->CNT=0;//定时器6计数器清零HAL_TIM_Base_Start_IT(&htim6);//以中断方式开启定时器6HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//开启PWM  /* USER CODE END 2 */  /* Infinite loop */  /* USER CODE BEGIN WHILE */  while (1)  {    /* USER CODE END WHILE */    /* USER CODE BEGIN 3 */KEY_Scan();//按键扫描if(LCD_RefreshFlag>4)//每0.5s更新一次LCD以及PWM(更新频率可调节){LCD_RefreshFlag=0;//LCD更新标志位清零v_value=ADC_GetValue();//重新获取R37电压值D_change();//D值更新LCD_Refresh();//LCD更新显示LED_change();//LED状态更新PWN_OutPut((TIM_Clock/F)-1,(D*1.0/100*TIM_Clock/F)-1);//PWM更新输出}LED_AllClose(LED_Close);//LED更新  }  /* USER CODE END 3 */}

四、实验结果

1.初始状态

R37电压调节为1.5,对应D值为1.5/2*80=60;PWM初始频率1Khz
请添加图片描述

2.输出PWM

在这里插入图片描述

3.调节输出频率

在这里插入图片描述

4.输出PWM

在这里插入图片描述

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

STM32PWM--基于HAL库(第十三届蓝桥杯嵌入式模拟题)


总结

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