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

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

文章目录

  • 前言
  • 一、CubeMX配置(第十三届模拟题完整版)
  • 二、代码相关定义、声明
    • 1.函数声明
    • 2.宏定义
    • 3.变量定义
  • 三、主要函数
    • 1.按键扫描
    • 2.配置模式
    • 3.LCD显示
    • 4.频率检测(TIM2输入捕获中断函数)
    • 5.PWM输出(TIM3)
    • 6.Main函数
  • 四、实验结果
    • 1.输入频率检测
    • 2.R值
    • 3.输出频率
  • 五、源码(转载请注明出处)
  • 总结

前言

相关说明:

开发板:CT117E-M4(STM32G431RB 蓝桥杯嵌入式比赛板)
开发环境: CubeMX+Keil5
涉及题目:第十三届蓝桥杯嵌入式模拟题
题目难点:根据输入的PWM,实时更新输出PWM


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

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

1.使能外部高速时钟:
在这里插入图片描述
2.配置时钟树:
在这里插入图片描述
3.GPIO:

在这里插入图片描述
4.ADC(默认配置即可):在这里插入图片描述
5.TIM2(输入捕获,检测输入信号的频率):在这里插入图片描述
6.TIM3(PWM输出):在这里插入图片描述
7.NVIC(输入捕获中断配置):在这里插入图片描述

二、代码相关定义、声明

1.函数声明

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);//输入捕获回调函数void Get_Adc(void); //获取ADC的值void Function_Mode_Change(void);//模式改变void Setting_Mode(void);//配置模式void KEY_Scan(void);//按键扫描void LCD_Show(void);//LCD显示void LED_CloseAll(void);//关闭所有LEDvoid LED_Mode_Change(vod);//LED禁用改变void LED_Show(void);//LED状态改变void PWM_Output(void);//PWM输出配置

2.宏定义

#define LED_GPIO_PORTGPIOC#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 OFF GPIO_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 KEY1_GPIO_PORTGPIOB#define KEY1_GPIO_PINGPIO_PIN_0#define KEY2_GPIO_PORTGPIOB#define KEY2_GPIO_PINGPIO_PIN_1#define KEY3_GPIO_PORTGPIOB#define KEY3_GPIO_PINGPIO_PIN_2#define KEY4_GPIO_PORTGPIOA#define KEY4_GPIO_PINGPIO_PIN_0

3.变量定义

uint8_t LCD_show=0;//决定为数据显示(0)还是参数设置(1) 控制LCD显示uint8_t LED_change=0;//LCD_show标志位改变则为1 控制LED状态转变uint8_t R=4;//参数Ruint8_t R_step=2;//R每次改变值uint8_t R_min=2;//R值下限uint8_t R_max=10;//R值上限uint8_t R_change=1;//R更改标志位double R37_v;//R37的电压值double V_max=3.3;//电压上限值uint32_t Tim_clock=1000000;//Tim时钟频率 1MHzuint32_t In_Hz;//输入信号频率uint32_t In_Hz_old;//上一次输入信号频率uint32_t Out_Hz;//PWM输出信号频率TIM_OC_InitTypeDef sConfigOC={0};//用于配置Pulseuint8_t LED_ban=0;//LED禁用标志位char str[33]; //用于sprintf组合字符串

三、主要函数

1.按键扫描

void KEY_Scan(){//KEY1 Press 界面切换(数据显示参数设置)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);Function_Mode_Change();//模式改变LCD_Show();//LCD更新LED_change=1;//改变标志位置1LED_Show();//LED更新Setting_Mode();//进入配置模式}}//KEY4 Press LED(控制是否禁用LED)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);LED_Mode_Change();//禁用/启用 LEDLED_change=1;//改变标志位置1LED_Show();//更新显示}}}

2.配置模式

void Setting_Mode(){while(1){//KEY1 Press 界面切换(数据显示参数设置)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);Function_Mode_Change();//模式改变R_change=1;//默认为更改LCD_Show();//LCD更新LED_change=1;//改变标志位置1LED_Show();//LED更新break;//退出配置模式}}//KEY2 Press ++(每次按下R参数增加2)else if(HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN)==GPIO_PIN_RESET){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);R+=R_step;//R增加if(R>R_max)R=R_max;//范围为2~10R_change=1;//R更改标志位置1LCD_Show();//更新显示}}//KEY3 Press --(每次按下R参数减少2)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);R-=R_step;//R减小if(R<R_min)R=R_min;//范围为2~10R_change=1;//R更改标志位置1LCD_Show();//更新显示}}//KEY4 Press LED(控制是否禁用LED)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);LED_Mode_Change();//禁用/启用 LEDLED_change=1;//改变标志位置1LED_Show();//更新显示}}}//while}

3.LCD显示

void LCD_Show(){if(LCD_show==0){LCD_DisplayStringLine(Line1,(unsigned char *)"Data  ");sprintf(str,"   FRQ:%dHz  ",In_Hz);LCD_DisplayStringLine(Line3,(unsigned char *)str);//FRQPWM_Output();//根据输入频率以及R值动态输出PWMIn_Hz=0;Get_Adc();//获取ADC的值sprintf(str,"   R37:%.2fV ",R37_v);LCD_DisplayStringLine(Line5,(unsigned char *)str);//R37LED_change=1;//受到LCD干扰 LED更新显示LED_Show();HAL_Delay(50);}else if(LCD_show==1 && R_change){R_change=0;LCD_DisplayStringLine(Line1,(unsigned char *)"Para  ");sprintf(str,"      R:%d   ",R);LCD_DisplayStringLine(Line3,(unsigned char *)str);//RLCD_DisplayStringLine(Line5,(unsigned char *)"      ");HAL_Delay(50);}}

4.频率检测(TIM2输入捕获中断函数)

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//测量频率{uint32_t count;count=__HAL_TIM_GET_COUNTER(&htim2);;//获取定时器计数值In_Hz=Tim_clock/count;//外部输入信号频率TIM2->CNT=0;//PWM_Output();}

5.PWM输出(TIM3)

void PWM_Output(){HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);//关闭PWM/* 配置PWM输出频率 */ Out_Hz=In_Hz/R;//In_Hz的值为输入频率 分频则将该频率再/Rhtim3.Init.Prescaler = 80-1;//分频值htim3.Init.Period = Tim_clock/Out_Hz-1;//计数值配置/* 配置PWM占空比 *///R37_v=((int)(R37_v*100))*0.01;//过滤(保留小数点后两位,避免电流干扰)sConfigOC.Pulse = R37_v/3.3*Tim_clock/Out_Hz-1;//测得电压值/3.3*计数值HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);HAL_TIM_PWM_Init(&htim3);//重新初始化HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);//开启PWM}

6.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_TIM2_Init();  MX_TIM3_Init();  /* USER CODE BEGIN 2 */LCD_Init();//LCD初始化HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);//输入捕获准备工作HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);//PWM参数配置sConfigOC.OCMode = TIM_OCMODE_PWM1;  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) ;HAL_TIM_PWM_Init(&htim3);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);//启动PWM  /* USER CODE END 2 */  /* Infinite loop */  /* USER CODE BEGIN WHILE */LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);LCD_DisplayStringLine(Line0,(unsigned char *)"      ");LCD_DisplayStringLine(Line2,(unsigned char *)"      ");LCD_DisplayStringLine(Line4,(unsigned char *)"      ");LCD_DisplayStringLine(Line6,(unsigned char *)"      ");LCD_DisplayStringLine(Line7,(unsigned char *)"      ");LCD_DisplayStringLine(Line8,(unsigned char *)"      ");LCD_DisplayStringLine(Line9,(unsigned char *)"      ");  while (1)  {    /* USER CODE END WHILE */    /* USER CODE BEGIN 3 */KEY_Scan();//按键扫描LCD_Show();//LCD更新信息LED_Show();//LED状态改变  }  /* USER CODE END 3 */}

四、实验结果

1.输入频率检测

此处用的是另一块开发板为该板提供信号,频率为1KHz;并调节R37使其电压为1.65V,预期占空比为1.65/3.3=50%。
在这里插入图片描述

2.R值

默认R值为4,作用为将输入信号进行分频处理;预期输出频率为1K/4=250Hz。
在这里插入图片描述

3.输出频率

这里直接用示波器检测输出PWM,频率为250Hz,占空比为50%,符合预期。在这里插入图片描述

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

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


总结

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