基于STM32G431嵌入式学习笔记——八、PWM脉冲输出(基于第12届蓝桥杯节选PA7作引脚)

本文详细介绍了STM32G4系列微控制器中如何配置PWM输出,以满足特定的脉冲信号需求。从PWM工作原理、时钟信号关联到CubeMX中的配置步骤,以及在实际编程中的应用,作者通过一个蓝桥杯竞赛题目为例,展示了如何在特定条件下实现2KHz、20%占空比的PWM输出。同时,文章还讨论了两种PWM模式的区别,并提供了两种不同的PWM控制函数实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、真题引入

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

简言之,关于脉冲输出的题目要求如下:
①默认低电平
②按下key4,切换低电平/脉冲信号
③输出脉冲器件LED2点亮,否则熄灭。

二、基础知识
1.PWM工作原理

在这里插入图片描述

2.与时钟信号的关联

具体可以查阅STM32G4系列微控制器参考手册
在这里插入图片描述28-31章均为时钟timer相关资料,我们可以向右方一样查找该类型定时器是否支持PWM,从而判断该定时器是否能调用引脚实现脉冲输出。【实际上只有第31章的定时器不支持PWM输出功能】
对于我们用户来说,各种输出都是来自于引脚,因此PWM的配置本质依旧是引脚配置

3.生活中的PWM

我们的可变亮度的台灯本质是利用了PWM输出,通过调节占空比,实现不同占空比下不同平均电压的输出,从而有了灭->暗->亮->晃眼睛。

三、PWM在CubeXM中的配置

该部分是第12届蓝桥杯最后一部分的题目内容,因此我们可以基于第六节的环境进行修改。

如何在CubeMX中判断哪些定时器支持PWM?
如图所示,众多的定时器channel中可以选择功能,仅需检查是否有PWM选项
在这里插入图片描述
但是本题对引脚做出了限制
在这里插入图片描述
因此选择PA7进行配置

在这里插入图片描述

实际上PWM是多路输出的,因此在定时器中会有许多通道,而我们仅需要选择其中一个channel即可,且实际上上面四个通道任选其一均可
如果题目没有指定某引脚,我们平时练习可以只固定一个熟练的引脚一直使用(我固定使用PA7的通道2)

①记得在该通道选定PWM generation
②配置时钟源(internal clock内部时钟)
在这里插入图片描述

操作实现了2K的输出频率
具体计算如下:
时钟频率:80MHz=8∗107Hz80MHz=8*10^7Hz80MHz=8107Hz
预分频器分频:8∗107Hz/80=106Hz8*10^7Hz/80=10^6Hz8107Hz/80=106Hz
利用计数周期分频:106Hz/500=2∗103Hz=2KHz10^6Hz/500=2*10^3Hz=2KHz106Hz/500=2103Hz=2KHz

Prescaler:预分频器
Counter Period:计数周期,指计数多少次发生一次中断

在这里插入图片描述操作实现占空比20%
上述Counter Period为一个周期计数500,那么占空比20%
说明要计数500∗20%=100500*20\%=10050020%=100即100脉冲
在这里插入图片描述
在这里还有一个关于Mode的知识点,PWM的两种模式代表不同情况
在这里插入图片描述

在进行PWM信号输出时,有两种PWM模式:PWM1模式和PWM2模式。
这两种PWM模式和输出有效电平的极性共同决定了PWM信号的波形。
PWM1模式
递增计数时,当TIMx_CNT(计数值)< TIMx_CCR(捕获/比较值)时,输出为有效电平,否则为无效电平。递减计数模式则刚好相反。
PWM2模式
递增计数时,当TIMx_CNT(计数值)< TIMx_CCR(捕获/比较值)时,输出为无效电平,否则为有效电平。递减计数模式则刚好相反。

下面我们详细分析一下两种PWM模式的区别:
假设定时器设置为递增计数模式,输出有效电平的极性为高电平。
PWM1模式下的CCR用于控制高电平持续的时间;
PWM2模式下的CCR用于控制低电平持续的时间,两种模式下的PWM信号互为互补输出。 在这里插入图片描述
环境配置完毕

四、代码书写
1.将代码对比恢复至第六节最后的内容

(1)头文件补充
(2)全局变量有没有遗漏
(3)函数声明
(4)主函数

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_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  LCD_Init();
  control_led(LEDALL,OFF);
	ParkingInit();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)usart_rx,RxLen);
  LCD_Clear(Black);
  while (1)
  {
    /* USER CODE END WHILE */
    lcd_proc();
    key_proc();
    led_proc();
    busi_proc();
    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}
2.更新全局变量

在这里插入图片描述

3.更新按键函数
void key_proc(void)
{
  char value = key_scan();
  switch(value)
  {
    case 1:
      /*切换LCD显示屏界面的操作*/
      lcd_flag = (lcd_flag == 1 ? 0 : 1);
      lcd_update_flag=1;
      break;
    case 2:
      /*CNBR、VNBR费率增加0.5�??*/
      cnbr += 0.5f;
      vnbr += 0.5f;
      lcd_update_flag=1;
      break;
    case 3:
      /*CNBR、VNBR费率减少0.5�??*/
      cnbr -= 0.5f;
      vnbr -= 0.5f;
      lcd_update_flag=1;
      break;
    case 4:
      /*两种频率输出状态*/
      pwm_flag = (lcd_flag == 1 ? 0 : 1);
      break;
  }
}
4.书写pwm函数
void pwm_proc(void)
{
  if(pwm_flag)//低电平
  {
    HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2);
    HAL_Delay(5);
  }
  else//高电平
  {
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
    HAL_Delay(5);
  }
}

记得在整个文件开头进行函数声明:
在这里插入图片描述
代码中有两个函数,分别代表停止/开始PWM输出
开始输出的时候就是20%占空比2KHz,停止输出后便为低电平
在这里插入图片描述
两个函数位于如下图所示的位置
在这里插入图片描述
拓展:该函数的另一种实现方式

void pwm_proc(void)
{
  if(pwm_flag)//低电平
  {
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
    __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);//占空比0
    HAL_Delay(5);
  }
  else//高电平
  {
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
    __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,100);//占空比100/500=20%
    HAL_Delay(5);
  }
}

__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,100) 是专门用来设置占空比的函数
最后一个参数的含义为我们的计数周期中有多少计数是脉冲
我们曾在CubeMX中设置计数周期为500,则500*0.2=100

在这里插入图片描述
对于这两种方式,我们都需要记住!!第二种方法尤为重要,通过这个甚至可以设计出我们生活中的可调亮度台灯

5.重写led函数
void led_proc(void)
{
  if(idle>0)
  {
    control_led(LED1,ON);//LED1�??
  }
  else
  {
    control_led(LED1,OFF);
  }
	if(pwm_flag==1)
		control_led(LED2,ON);
	else
		control_led(LED2,OFF);
}
6.书写主函数

实际上仅需在while循环中新增一行pwm_proc()即可
在这里插入图片描述

保存,编译,下载,观察不同按键下的板子状态。
至此第12届蓝桥杯省赛题目所有任务均完成,后续会更新一期完整的第12届蓝桥杯题目整体思路和流程

具体操要求如下: 以给定频率输出脉冲脉冲数无限制 以给定频率f、输出n个脉冲 相对定位 相对定位+绝对定位 脉冲输出PORTA.0 方向信号输出PORTB.5 模仿PLC定位指令 可以为简易运动控制器控制伺服电机 发脉冲两种目的 1)速度控制 2)位置控制 速度控制目的和模拟量一样,没有什么需要关注的地方 发送脉冲方式为PWM,速率稳定而且资源占用少 stm32位置控制需要获得发送的脉冲数,有下面4种手段 1)每发送一个脉冲,做一次中断计数 2)根据发送的频率×发送的时间,获得脉冲数量,对于变速的脉冲,可以累计积分的方法来获得总脉冲 3)一个定时器为主发送脉冲,另外一个定时器为从,对发送的脉冲计数 4)使用DMA方式,例如共发送1000个脉冲,那么定义u16 per[1001],每发送一个脉冲,dma会从数组中更新下一个占空比字,数组最后一个字为0,表示停发脉冲 上面4种方法的用途和特点 1)对于低速率脉冲比较好,可以说低速发脉冲的首选,例如10Khz以下的,否则中断占用太多的cpu,这种方法要注意将中断优先级提高,否则会丢计数, 2)用定时的计时精确高,可以允许有脉冲计数丢失的情况 3)主从方式,需额外的定时器来计数,例如tim1发脉冲 tim2计数,最方便的方式,无论高速低速即可,同时占用cpu最低,只是要占用多一个定时器 4)DMA方式也算是一个很确定的方式,不会丢失脉冲,但是高速的时候,会较多的占用内部总线同时会使用一个多余的DMA控制器,而且有个缺点,就是使用起来比较复杂,没有达到KISS原则 个人推荐方式,低速时中断方式,如果不知高速还是低速,则使用主从方式。具体的方式需要根据资源和需求来确定。 stm32定时器算是比较复杂的器件,而且用户要较多的介入底层,希望将来st公司能够能够简化器件的使用。
<think>我们正在配置RH850U2A芯片的PWM通道,使用DAVINCI Configurator PB.BRE Classic工具。需要配置三个部分:Port(引脚初始模式)、PWM(定时器选择)以及Port与PWM的关联配置。 根据AUTOSAR标准,配置步骤如下: 1. **Port配置**: - 首先,我们需要配置用于PWM输出引脚。在Port模块中,找到对应的引脚(例如,P14.0PWM输出引脚)。 - 配置该引脚的初始模式(Pin Initial Mode)为`DIO_MODE_ALT`(替代模式),因为PWM功能通常使用引脚的替代功能。 - 同时,设置方向为输出(Output)。 2. **PWM模块配置**: - 在PWM模块中,我们需要配置一个PWM通道(PwmChannel)。首先,选择定时器(Timer Selection)。RH850U2A的PWM模块通常与特定的定时器单元关联(例如,TPU模块)。根据硬件手册,选择与所选引脚对应的定时器通道。 - 例如,如果P14.0对应TPU0.T0,那么定时器选择为TPU0,通道选择为0。 - 配置PWM的周期(Period)、占空比(Duty Cycle)等参数。 3. **关联Port与PWM**: - 在AUTOSAR中,Port和PWM的关联通常通过Mcu模块进行时钟配置,但直接关联是通过配置PWM通道使用的引脚。在PWM通道配置中,有一个选项可以指定输出引脚PwmChannelOutput),这里需要选择我们在Port模块中配置的引脚。 具体步骤: ### 1. 配置Port引脚 - 打开Port模块配置。 - 找到要使用的引脚(例如P14.0)。 - 设置: - `PortPinDirection`:`PORT_PIN_OUT` - `PortPinInitialMode`:`PORT_PIN_MODE_ALT`(替代模式) - `PortPinMode`:设置为PWM对应的替代模式,具体替代模式号需要参考芯片手册。例如,对于RH850U2A,P14.0PWM输出时,可能需要设置`PortPinMode`为`ALT6`(具体数值需查手册)。 ### 2. 配置PWM通道 - 打开PWM模块配置。 - 添加一个PwmChannel。 - 配置该通道: - `PwmChannelId`:通道ID(例如0)。 - `PwmChannelClass`:`PWM_VARIABLE_PERIOD`(可变周期)或`PWM_FIXED_PERIOD`(固定周期),根据需求选择。 - `PwmTimerSelection`:选择定时器单元和通道。例如,选择`TPU0`和通道`0`(对应P14.0)。 - 配置周期(`PwmPeriod`)和占空比(`PwmDutyCycle`)等参数。 ### 3. 关联配置 - 在PWM通道配置中,找到`PwmChannelOutput`(或类似名称)的设置项,选择我们之前配置的引脚(P14.0)。这样,PWM通道就知道使用哪个引脚输出。 ### 注意事项: - 时钟配置:确保在Mcu模块中配置了PWM模块所需的时钟(例如,TPU时钟)。 - 引脚复用:确保在Port模块中正确配置了替代功能模式,并且替代模式号(ALTx)与PWM功能对应。 参考引用[3]中提到,修改配置后需要正确替换源文件,避免编译错误。因此,配置完成后生成代码时,要注意替换文件的步骤。 总结步骤: 1. Port模块:配置引脚为替代模式,并选择正确的替代模式号。 2. PWM模块:配置PWM通道,选择对应的定时器和通道,设置周期和占空比。 3. 在PWM通道配置中指定输出引脚。 这样,PWM信号就可以通过指定的引脚输出了。 §§相关问题§§ 1. 如何配置RH850U2A的Port模块以支持其他外设(如CAN、SPI)? 2. PWM模块的周期和占空比如何计算? 3. 在DAVINCI Configurator中,如何验证Port和PWM的配置是否正确关联?</think>### DAVINCI Configurator PB.BRE Classic 中 RH850U2A PWM 通道配置指南 #### 1. **Port 引脚初始模式配置** - **步骤**: 1. 打开 `Port` 模块配置界面。 2. 选择 PWM 输出对应的物理引脚(如 `P14.0`)。 3. 在 `Pin Initial Mode` 中选择 **`DIO_MODE_ALT`**(替代功能模式)。 - *原因*:PWM 输出需使用引脚的复用功能(Alternative Function),而非通用 I/O 模式[^1]。 4. 设置 `PortPinMode` 为 PWM 对应的替代模式编号(如 `ALT6`),具体编号需查阅 RH850U2A 数据手册的引脚复用表。 5. 配置方向为输出(`Output`),并关闭内部上拉/下拉电阻(根据硬件设计需求)。 ```c /* 示例配置(自动生成的代码片段) */ Port_ConfigType PortPin_P14_0 = { .PortPinDirection = PORT_PIN_OUT, // 输出方向 .PortPinInitialMode = DIO_MODE_ALT, // 替代模式 .PortPinMode = 6, // ALT6 对应 PWM .PortPinLevelValue = PORT_PIN_LEVEL_LOW // 初始电平 }; ``` --- #### 2. **PWM 定时器选择与通道配置** - **定时器选择(Timer Selection)**: 1. 打开 `Pwm` 模块配置。 2. 创建 `PwmChannel`(如 `PwmChannel_0`)。 3. 在 `Timer Selection` 中选择 **TPU(Timer Pulse Unit)**: - RH850U2A 的 PWM 由 TPU 模块驱动,需选择与引脚匹配的 TPU 通道(如 `TPU0.T0` 对应 `P14.0`)[^1]。 4. 配置关键参数: - `PwmPeriod`:PWM 周期(单位:纳秒或时钟周期)。 - `PwmDutyCycle`:初始占空比(0~100%)。 - `PwmIdleState`:空闲状态电平(通常为 `LOW`)。 - **时钟源配置**: - 在 `Mcu` 模块中启用 TPU 时钟(如 `TPU0_CLK`),并设置频率(需与 `Port` 模块的时钟一致)[^3]。 --- #### 3. **Port 与 PWM 关联配置** - **关键步骤**: 1. 在 `PwmChannel` 配置中定位 `Output Pin` 选项。 2. 绑定已配置的 Port 引脚(如 `P14.0`)。 - *注意*:需确保引脚在 `Port` 和 `Pwm` 中的复用模式(ALTx)一致。 3. 验证信号路径: ```mermaid graph LR TPU0[TPU0 定时器] -->|生成 PWM 波形| PwmChannel_0 PwmChannel_0 -->|输出到| P14_0[引脚 P14.0] ``` --- #### 4. **配置验证与代码生成** - **验证方法**: 1. 使用 `Davinci Configurator` 的 **一致性检查(Consistency Check)** 功能。 2. 生成代码后,检查 `Pwm_Cfg.h` 和 `Port_Cfg.h`: - 确认 `PwmChannel` 的 `OutputPin` 指向正确的引脚宏(如 `PORT_PIN_P14_0`)。 - **代码替换注意事项**: - 修改配置后,需**先删除 IDE 中的旧源文件**,再替换新文件,最后重新添加路径,避免编译错误[^3]。 > **总结**:PWM 配置的核心是确保三点: > ① Port 引脚设为 `DIO_MODE_ALT` + 正确复用模式号; > ② PWM 通道绑定匹配的 TPU 定时器; > ③ 通过 `Output Pin` 选项关联 Port 引脚。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值