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
五、源码(转载请注明出处)
总结
以上就是全部内容,如有错误请批评指正。