STM32——高级定时器输出指定个数PWM波原理及实战

这篇具有很好参考价值的文章主要介绍了STM32——高级定时器输出指定个数PWM波原理及实战。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.高级定时器简介(TIM8、TIM1)

相比于通用定时器特性:
1)重复计数器
2)死区时间带可编程的互补输出
3)断路输入,用于将定时器的输出信号置于用户可选的安全配置中

2.高级定时器框图

STM32——高级定时器输出指定个数PWM波原理及实战,stm32,单片机,嵌入式硬件

3.重复计数器特性及输出指定个数PWM波实战

STM32——高级定时器输出指定个数PWM波原理及实战,stm32,单片机,嵌入式硬件

4.高级定时器输出指定个数PWM波原理

STM32——高级定时器输出指定个数PWM波原理及实战,stm32,单片机,嵌入式硬件

5.高级定时器输出指定个数PWM实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_PWM_Init()
2,定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()
4,设置优先级,使能中断 HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
5,使能定时器更新中断 __HAL_TIM_ENABLE_IT()
6,使能输出、主输出、计数器 HAL_TIM_PWM_Start()
7,编写中断服务函数 TIMx_IRQHandler()等  HAL_TIM_IRQHandler()
8,编写更新中断回调函数 HAL_TIM_PeriodElapsedCallback()
STM32——高级定时器输出指定个数PWM波原理及实战,stm32,单片机,嵌入式硬件

6.高级定时器输出指定个数PWM实战

1.通过定时器8通道1实现指定个数PWM输出,用于控制LED1的亮灭
2,配置输出比较模式为:PWM模式1
通道输出极性为:高电平有效
占空比:50%
代码:文章来源地址https://www.toymoban.com/news/detail-794279.html

6.1 atim.c

#include "./BSP/TIMER/atim.h"
#include "./BSP/LED/led.h"
//1.声明定时器句柄
TIM_HandleTypeDef  g_timx_npwm_chy_handler;
static uint32_t g_npwm_remain = 0;
/**
 * @brief       高级定时器TIMX 通道Y PWM输出指定个数PWM 初始化函数(使用PWM模式1)
 * @note
 *              高级定时器的时钟来自APB2,而PCLK =168Mhz,我们设置PPRE2不分频
 *              高级定时器的时钟 = 168Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft = 定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值
 * @param       psc: 预分频系数
 * @retval      无
 */
//2.配置通用定时器基本工作参数,PWM输出初始化
void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc)    /* 通用定时器 PWM初始化函数 */  
{
    //4.1定时器输出比较定时器结构体初始化
    TIM_OC_InitTypeDef tim_oc_npwm_chy = {0};
    
    //2.1通用定时器PWM输出初始化
    g_timx_npwm_chy_handler.Instance = ATIM_TIMX_NPWM;                  //定时器x
    g_timx_npwm_chy_handler.Init.Period = arr;
    g_timx_npwm_chy_handler.Init.Prescaler = psc;
    g_timx_npwm_chy_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
    g_timx_npwm_chy_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能TIMx_ARR进行缓冲 */
    g_timx_npwm_chy_handler.Init.RepetitionCounter = 0;                  /* 重复计数器初始值 */
    HAL_TIM_PWM_Init(&g_timx_npwm_chy_handler);
    
    
    //5.输出比较配置包,括PWM模式和比较值
    tim_oc_npwm_chy.OCMode = TIM_OCMODE_PWM1;          //输出比较模式 PWM1
    tim_oc_npwm_chy.Pulse = arr/2;                     //设置比较值为自动加载值的一般,则占空比为50%
    tim_oc_npwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH;   //设置输出比较的极性为高
    HAL_TIM_PWM_ConfigChannel(&g_timx_npwm_chy_handler,&tim_oc_npwm_chy,ATIM_TIMX_NPWM_CHY);
    
    //6,使能定时器更新中断
    __HAL_TIM_ENABLE_IT(&g_timx_npwm_chy_handler,TIM_IT_UPDATE);
    
    //7,开启对应PWM通道使能输出并启动计时器
    HAL_TIM_PWM_Start(&g_timx_npwm_chy_handler,ATIM_TIMX_NPWM_CHY);
 
    
}
//3.定时器PWM输出底层初始化,定时器时钟、引脚时钟使能,引脚复用配置
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef * htm)
{
    //3.1判断是否是TIM14
    if(htm->Instance ==  ATIM_TIMX_NPWM)
    {
         GPIO_InitTypeDef gpio_init_struct;
     
        //3.3使能PF引脚口时钟
        ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE();
        
        //3.4使能定时器时钟
        ATIM_TIMX_NPWM_CHY_CLK_ENABLE();
       
       
      //3.2通道y的GPIO初始化
      gpio_init_struct.Pin = ATIM_TIMX_NPWM_CHY_GPIO_PIN;      /* 通道Y GPIO口 */
      gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */
      gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
      gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */ 
      gpio_init_struct.Alternate =ATIM_TIMX_NPWM_CHY_GPIO_AF; /* 端口复用到TIM8 */ 
      HAL_GPIO_Init(ATIM_TIMX_NPWM_CHY_GPIO_PORT, &gpio_init_struct);  

      //4 设置优先级、使能中断
      HAL_NVIC_SetPriority(ATIM_TIMX_NPWM_IRQn,1,3); 
      HAL_NVIC_EnableIRQ(ATIM_TIMX_NPWM_IRQn);
    
    }
}


/* 定时器8中断服务函数 */
void ATIM_TIMX_NPWM_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_npwm_chy_handler);
}

/* 定时器更新中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

     if(htim->Instance == ATIM_TIMX_NPWM)  //如果是TIM8
     {
         if(g_npwm_remain)//如果重复计数值大于0,则需要发送PWM波
         {
             ///* 设置重复计数寄存器值为npwm-1, 即npwm个脉冲 */
             ATIM_TIMX_NPWM->RCR = g_npwm_remain - 1;
             //通过软件更新事件,将RCR值缓冲到影子寄存器里面
             HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handler, TIM_EVENTSOURCE_UPDATE);
             //使能计数器
             __HAL_TIM_ENABLE(&g_timx_npwm_chy_handler);
             //清零
            g_npwm_remain = 0;
         }
         else
         {
            //关闭计数器
             ATIM_TIMX_NPWM->CR1 &= ~(1 << 0);  /* 关闭定时器TIMX,使用HAL Disable会清除PWM通道信息,此处不用 */
         }
     }
}
/**
 * @brief       高级定时器TIMX NPWM设置PWM个数
 * @param       rcr: PWM的个数, 1~2^32次方个
 * @retval      无
 */
void atim_timx_npwm_chy_set(uint32_t npwm)
{
    if(npwm == 0) return ;
    
    g_npwm_remain = npwm;
    //通过软件更新事件,将RCR值缓冲到影子寄存器里面
    HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handler, TIM_EVENTSOURCE_UPDATE);
    //使能计数器
    __HAL_TIM_ENABLE(&g_timx_npwm_chy_handler);

}

6.2 atim.h

#ifndef __ATIM_H
#define __ATIM_H

#include "./SYSTEM/sys/sys.h"


/******************************************************************************************/
/* 高级定时器 定义 */

 /* TIMX 输出指定个数PWM 定义 
 * 这里输出的PWM通过PC6(TIM8_CH1)输出, 我们用杜邦线连接PC6和PF10, 然后在程序里面将PF10设置成浮空输入
 * 就可以 看到TIM8_CH1控制LED1(GREEN)的亮灭, 亮灭一次表示一个PWM波
 * 默认使用的是TIM8_CH1.
 * 注意: 通过修改这几个宏定义, 可以支持TIM1/TIM8定时器, 任意一个IO口输出指定个数的PWM
 */
#define ATIM_TIMX_NPWM_CHY_GPIO_PORT            GPIOC
#define ATIM_TIMX_NPWM_CHY_GPIO_PIN             GPIO_PIN_6
#define ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0) /* PC口时钟使能 */
#define ATIM_TIMX_NPWM_CHY_GPIO_AF              GPIO_AF3_TIM8

#define ATIM_TIMX_NPWM                          TIM8
#define ATIM_TIMX_NPWM_IRQn                     TIM8_UP_TIM13_IRQn
#define ATIM_TIMX_NPWM_IRQHandler               TIM8_UP_TIM13_IRQHandler
#define ATIM_TIMX_NPWM_CHY                      TIM_CHANNEL_1                               /* 通道Y,  1<= Y <=4 */
#define ATIM_TIMX_NPWM_CHY_CCRX                 TIM8->CCR1                                  /* 通道Y的输出比较寄存器 */
#define ATIM_TIMX_NPWM_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)  /* TIM8 时钟使能 */

void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc);   /* 高级定时器 输出指定个数PWM初始化函数 */
void atim_timx_npwm_chy_set(uint32_t npwm);                 /* 高级定时器 设置输出PWM的个数 */

#endif

6.3 main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/atim.h"


int main(void)
{
    uint8_t key = 0;
    uint8_t t = 0;
    GPIO_InitTypeDef gpio_init_struct;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化按键 */
    
    /* 将 LED1 引脚设置为输入模式, 避免和PC6冲突 */
    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 设置为输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速模式 */
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */
    
    atim_timx_npwm_chy_init(10000 - 1, 8400 - 1);           /* 20Khz的计数频率,2Hz的PWM频率. */

    ATIM_TIMX_NPWM_CHY_CCRX = 5000; /* 设置PWM占空比,50%,这样可以控制每一个PWM周期,LED1(GREEN)
                                     * 有一半时间是亮的,一半时间是灭的,LED1亮灭一次,表示一个PWM波
                                     */
    atim_timx_npwm_chy_set(5);      /* 输出5个PWM波(控制LED1(GREEN)闪烁5次) */
    
    while (1)
    {
       key = key_scan(0);

        if (key == KEY0_PRES)           /* KEY0按下 */
        {
            atim_timx_npwm_chy_set(5);  /* 输出5个PWM波(控制TIM8_CH1, 即PC6输出5个脉冲) */
        }

        t++;
        delay_ms(10);

        if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */
        {
            t = 0;
            LED0_TOGGLE();
        }
    }
}

到了这里,关于STM32——高级定时器输出指定个数PWM波原理及实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32TIM定时器PWM输出比较(适用于通用,高级定时器)

    在定时器中我们最常用的功能就是输出PWM,大多是用在电机控制方面,目前网络上相关资料也有很多,但是,很多不利于我们“现搜现用”我这里不是说我写的有多好,而是你搜索到此类文章时大部分是急于解决目前的问题,一段相关代码和讲解就行,当然不是学习背后的原

    2024年01月25日
    浏览(54)
  • STM32使用高级定时器输出互补pwm波

    最近做的一个项目用到stm32,网上查了很多资料,也踩了很多坑,这里记录一下配置的步骤和说明 硬件使用的是stm32h750vbt6; 软件用到了stm32cubemx和keil5; 打开Debug模式方便调试,可以忽略,不影响代码运行 在用cube配置时钟源时,有下面三个选项 Disable(禁用) BYPASS Clock Sou

    2024年02月16日
    浏览(70)
  • STM32实战-高级定时器带死区的互补PWM输出

    前言: 平时我们设计点击驱动电路时,一般会采用npn和pnp三极管,来控制电机的导通和关闭,但是三级管内部自带电容,断电后不会立马断掉,会经过很小的一段时间才会放电完毕,这时候要留有死区给电容放电,这就有了互补pwm波。   同时,当电机出现故障,如果利用软

    2024年02月08日
    浏览(47)
  • STM32学习笔记(4) 高级定时器-两路互补的PWM输出(带死区和刹车控制)

    目录 1.实验目的 2.实验效果 3.理论部分 3.1时钟源 3.2时基单元 3.3输入捕获 4.程序流程 4.1GPIO初始化结构体 4.2时基初始化结构体 4.3输出比较结构体 4.4刹车和死区结构体的初始化 5.程序源码 使用高级定时器,输出两路互补的PWM输出,需要有带死区和不带死区两种情况 图1:不带

    2024年02月13日
    浏览(40)
  • 【STM32学习】——定时器输出比较功能&PWM脉宽调制&通用/高级定时器输出比较通道&舵机/直流电机简介&PWM驱动呼吸灯/舵机/直流电机代码实操

    声明:学习笔记根据b站江科大自化协stm32入门教程编辑,仅供学习交流使用!

    2024年02月03日
    浏览(52)
  • STM32F4使用高级定时器(TIM1和TIM8)输出PWM问题

    STM32F4使用高级定时器(TIM1和TIM8)输出PWM时要使用TIM_CtrlPWMOutputs使能PWM输出,否则不会输出PWM波形,这一点是和通用定时器输出PWM不一样的地方,通用定时器是不用配置TIM_CtrlPWMOutputs函数的。、

    2024年02月15日
    浏览(40)
  • 【正点原子STM32连载】第二十三章 高级定时器互补输出带死区控制实验 摘自【正点原子】APM32F407最小系统板使用指南

    本章将介绍使用APM32F407输出带死区和刹车控制的两路互补PWM。通过本章的学习,读者将学习到高级定时器的互补输出、死区插入和刹车的功能的使用。 本章分为如下几个小节: 23.1 硬件设计 23.2 程序设计 23.3下载验证 23.1 硬件设计 23.1.1 例程功能 定时器8通道1及其互补通道输

    2024年02月09日
    浏览(61)
  • 定时器详解 -- 定时器中断、PWM输出 --stm32

    STM32F103系列芯片拥有多种定时器,包括基本定时器、通用定时器和高级定时器,每种定时器都具有一些特定的功能。 向上计数:计数器从0计数到自动重装载值(ARR),然后重新从0开始计数并且产生一个计数器溢出事件。 向下计数:计数器从自动重装载值(ARR)开始向下计数

    2024年02月11日
    浏览(59)
  • STM32 MCU 定时器详解(3)--高级定时器

    16位递增、递减、中心对齐计数器(计数值:0~65535) 16位预分频器(分频系数:1~65536) 可用于触发DAC、ADC 在更新事件、触发事件、输入捕获、输出比较时,会产生中断/DMA请求 4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式 使用外部信号控制定时器且可实

    2024年04月17日
    浏览(45)
  • STM32高级定时器详解

    ✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页:@rivencode的个人主页 🔥系列专栏:玩转STM32 💬保持学习、保持热爱、认真分享、一起进步!! 基本定时器TIM6和TIM7各包含 一个16位自动装载计数器 ,由各自的可编程预分频器驱动。

    2024年01月19日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包