STM32H743+CubeMX-定时器TIM输出PWM(PWM Generation模式)+ 中断

一、前言


STM32H743+CubeMX-定时器TIM输出PWM(PWM Generation模式)
上一次完成了使用定时器TIM的PWM Generation模式输出PWM波,没有产生中断。在实际项目上,有时候需要计算一共发了多少个PWM(相当于脉冲)给步进电机,从而计算步进电机的步距角,有时候也需要计算电平翻转的次数。

  1. 计算PWM的个数需要使用定时器溢出中断(CNT寄存器的值 = ARR寄存器的值)
  2. 计算电平翻转次数的总数,需要同时使用定时器溢出中断(CNT寄存器的值 = ARR寄存器的值)与OC中断(CNT计数器的值 = CCR寄存器的值)
    在这里插入图片描述

二、CubeMX


2.1、Mode and Parameter Settings

TIM8的时钟频率是240M,当Prescaler = 239时,TIM8的时钟频率 = 240M / (239 + 1) = 1MHz。

Counter Period设置49999时,定时器溢出中断的频率 = 1M / (49999 + 1) = 20Hz,周期T = 1 / 20 = 0.05s = 50ms

Pulse设置24999时,OC中断的频率 = 1M / (24999 + 1) = 40Hz ,周期T = 1 / 40 = 0.025s = 25ms

根据示波器的波形,可以证明以上的计算是正确的。
在这里插入图片描述

2.2、NVIC Settings

TIM8 update interrupt : 更新:计数器上溢/下溢,计数器初始化(通过软件或内部/外部触发)

TIM8 capture compare interrupt : 输出比较
在这里插入图片描述
在这里插入图片描述

2.3、生成代码

在这里插入图片描述

三、代码


3.1、tim.c

首先,在函数void MX_TIM8_Init(void)添加用户代码。目的是打开定时器溢出中断与OC中断。
在这里插入图片描述
然后,添加OC中断回调函数。值得注意的是,经过实验证明:HAL_TIM_OC_DelayElapsedCallback与HAL_TIM_PWM_PulseFinishedCallback效果是一样的,都是当CNT寄存器的值 = CCR比较寄存器的值时就会进入函数一次。所以,任意挑一个来使用即可。
在这里插入图片描述

3.2、main.c

还需要添加另外一个中断回调函数HAL_TIM_PeriodElapsedCallback(),当CNT寄存器的值 = ARR寄存器的值时,进入一次回调函数。

HAL_TIM_PeriodElapsedCallback()也可以放到tim.c里面,这个都可以的。
在这里插入图片描述

四、DEBUG


4.1、OC中断回调函数的验证

HAL_TIM_OC_DelayElapsedCallback()与HAL_TIM_PWM_PulseFinishedCallback()都会获取当前CNT寄存器的值。目的是知道产生OC中断时,CNT寄存器当前的值时多少,从而判断究竟是OC中断还是溢出中断。
在这里插入图片描述
从Monitor的监控看来,Curr_CNT与OC_CNT一直都是24999,24999是CCR比较寄存器的值。并且从OC_Value与PWM_Value始终相等看来,这两个回调函数进入的次数是一样的。

所以,HAL_TIM_OC_DelayElapsedCallback与HAL_TIM_PWM_PulseFinishedCallback都是当CNT的值24999等于CCR寄存器的值24999时进入一次。
在这里插入图片描述

4.2、定时器溢出中断

从Monitor监控看来,main_Value一直在递增,main_CNT保持0,证明每一次定时器溢出时,都会进入此中断。

main_CNT保持0的原因是溢出后会马上复位CNT的值,然后才启动溢出中断。
在这里插入图片描述
在这里插入图片描述

五、细节补充


  1. 不要被函数HAL_TIM_PWM_PulseFinishedCallback的名字欺骗了,一开始我以为进入这个中断回调函数时是PWM波结束(相当于PWM开始)的那个时刻(CNT = ARR),测试的结果表明并不是这样的。反而是PWM中间的位置(CNT = CCR),占空比设置50%时)。函数HAL_TIM_PWM_PulseFinishedCallback与函数HAL_TIM_OC_DelayElapsedCallback效果一样。
    在这里插入图片描述
    在这里插入图片描述
  2. 计算PWM(脉冲)的数量需要在函数HAL_TIM_PeriodElapsedCallback。有一个细节需要注意,使用HAL_TIM_PeriodElapsedCallback计算PWM波数量时,会比实际的数量多1。原因是当计数初始化时也会进入一次HAL_TIM_PeriodElapsedCallback函数,这个细节需要注意一下。有一个不错的方法可以解决这个问题,这一次实验使用main_Value来计算PWM波的数量,main_Value的变量大小是uint32_t,所以声明main_Value时,可以让main_Value = 4294967295,相当于main_Value = -1,这样就能解决PWM波多1的问题。
    在这里插入图片描述
    在这里插入图片描述
  3. 需要弄明白以下寄存器的意义,比如CubeMX上的Counter Period相当于TIMx_ARR寄存器,Pulse相当于TIMx_CCR寄存器等。
    在这里插入图片描述
  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
1. 打开STM32CubeMX软件,创建一个新工程。 2. 选择你的芯片型号,点击“新建工程”。 3. 在左侧的“Pinout & Configuration”选项卡中,选择“TIM8定时器。 4. 在右侧的“TIM8”选项卡中,选择“PWM Generation CH1”选项。 5. 配置PWM频率和占空比。可以选择“Frequency (Hz)”选项,输入所需的频率。然后选择“Duty Cycle (%)”选项,输入所需的占空比。 6. 在“TIM8”选项卡下面的“NVIC Settings”中,启用“TIM8 Global Interrupt”。 7. 保存并生成代码。在生成代码之前,要确保已经选择了正确的MCU和工具链。 8. 在生成的代码中,找到“void MX_TIM8_Init(void)”函数,在其中添加以下代码: ``` TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim8.Instance = TIM8; htim8.Init.Prescaler = 0; htim8.Init.CounterMode = TIM_COUNTERMODE_UP; htim8.Init.Period = 65535; htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim8.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_Init(&htim8) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 32767; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim8); ``` 9. 在“main.c”文件中添加以下代码,以设置PWM占空比: ``` HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1); HAL_TIM_PWM_Stop(&htim8, TIM_CHANNEL_1); ``` 10. 编译和下载程序。在运行程序之前,确保你已经连接了定时器8的PWM输出引脚到外部设备上。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wallace Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值