第30章 通用定时器-同步

第三十章 通用定时器-同步

1. 硬件设计

无需硬件设计

2. 软件设计

  • 定时器相关参数宏定义
// 定时器参数宏定义
#define GENERAL_TIM_MASTER            TIM2                // 主定时器--TIM2
#define GENERAL_TIM_MASTER_CLK        RCC_APB1Periph_TIM2 // 主定时器时钟--RCC_APB1Periph_TIM2

#define GENERAL_TIM_SLAVE1            TIM3                // 从定时器1--TIM3
#define GENERAL_TIM_SLAVE1_CLK        RCC_APB1Periph_TIM3 // 从定时器1时钟--RCC_APB1Periph_TIM3

#define GENERAL_TIM_SLAVE11           TIM4                // 从定时器11--TIM4
#define GENERAL_TIM_SLAVE11_CLK       RCC_APB1Periph_TIM4 // 从定时器11时钟--RCC_APB1Periph_TIM4

// TIM主模式PWM输出引脚
#define GENERAL_MASTER_PIN            GPIO_Pin_10          // 主定时器PWM输出引脚             
#define GENERAL_MASTER_GPIO_PORT      GPIOB                // 主定时器PWM输出端口             
#define GENERAL_MASTER_GPIO_CLK       RCC_APB2Periph_GPIOB // 主定时器PWM输出端口时钟
#define GENERAL_MASTER_PINSOURCE      GPIO_PinSource5      // 主定时器PWM输出引脚源
#define GENERAL_MASTER_AF             GPIO_AF_TIM2         // 主定时器PWM输出引脚复用功能

// TIM从模式PWM输出引脚
#define GENERAL_SLAVE1_PIN            GPIO_Pin_6             
#define GENERAL_SLAVE1_GPIO_PORT      GPIOC                      
#define GENERAL_SLAVE1_GPIO_CLK       RCC_APB2Periph_GPIOC
#define GENERAL_SLAVE1_PINSOURCE      GPIO_PinSource6
#define GENERAL_SLAVE1_AF             GPIO_AF_TIM3

// TIM从模式的从模式PWM输出引脚 
#define GENERAL_SLAVE11_PIN           GPIO_Pin_6             
#define GENERAL_SLAVE11_GPIO_PORT     GPIOB                      
#define GENERAL_SLAVE11_GPIO_CLK      RCC_APB2Periph_GPIOB
#define GENERAL_SLAVE11_PINSOURCE     GPIO_PinSource6
#define GENERAL_SLAVE11_AF            GPIO_AF_TIM4
  1. 定时器参数宏定义
  • GENERAL_TIM_MASTER 和 GENERAL_TIM_MASTER_CLK 定义了主定时器(TIM2)及其时钟。
  • GENERAL_TIM_SLAVE1 和 GENERAL_TIM_SLAVE1_CLK 定义了从定时器1(TIM3)及其时钟。
  • GENERAL_TIM_SLAVE11 和 GENERAL_TIM_SLAVE11_CLK 定义了从定时器11(TIM4)及其时钟。
  1. TIM主模式PWM输出引脚
  • GENERAL_MASTER_PINGENERAL_MASTER_GPIO_PORT 和 GENERAL_MASTER_GPIO_CLK 定义了主定时器的PWM输出引脚(PB10)及其相关端口和时钟。
  • GENERAL_MASTER_PINSOURCE 和 GENERAL_MASTER_AF 定义了引脚的复用功能设置,表明该引脚用于TIM2的PWM输出。
  1. TIM从模式PWM输出引脚
  • GENERAL_SLAVE1_PINGENERAL_SLAVE1_GPIO_PORT 和 GENERAL_SLAVE1_GPIO_CLK 定义了从定时器1的PWM输出引脚(PC6)及其相关端口和时钟。
  • GENERAL_SLAVE1_PINSOURCE 和 GENERAL_SLAVE1_AF 定义了引脚的复用功能设置,表明该引脚用于TIM3的PWM输出。
  1. TIM从模式的从模式PWM输出引脚
  • GENERAL_SLAVE11_PINGENERAL_SLAVE11_GPIO_PORT 和 GENERAL_SLAVE11_GPIO_CLK 定义了从定时器11的PWM输出引脚(PB6)及其相关端口和时钟。

  • GENERAL_SLAVE11_PINSOURCE 和 GENERAL_SLAVE11_AF 定义了引脚的复用功能设置,表明该引脚用于TIM4的PWM输出。

  • GPIO初始化

// TIM所使用的GPIO初始化
static void TIMx_GPIO_Config(void) 
{
  // 1.先定义一个GPIO_InitTypeDef结构体变量
  GPIO_InitTypeDef GPIO_InitStructure;

  // 2.使能GPIO时钟
  RCC_APB2PeriphClockCmd(GENERAL_MASTER_GPIO_CLK |GENERAL_SLAVE1_GPIO_CLK | GENERAL_SLAVE11_GPIO_CLK, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能AFIO时钟
  GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);   // 完全重映像TIM2_CH3->PB10
  GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);   // 完全重映像TIM3_CH1->PC6

  // 3.GPIO 配置: PC6(TIM3 CH1) 作为推挽复用输出功能
  GPIO_InitStructure.GPIO_Pin = GENERAL_SLAVE1_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;;
  GPIO_Init(GENERAL_SLAVE1_GPIO_PORT, &GPIO_InitStructure);

  // 4.GPIO 配置: PB6(TIM4 CH1) 作为推挽复用输出功能
  GPIO_InitStructure.GPIO_Pin = GENERAL_SLAVE11_PIN;
  GPIO_Init(GENERAL_SLAVE11_GPIO_PORT, &GPIO_InitStructure);

  // 5.GPIO 配置: PB10(TIM2 CH3) 作为推挽复用输出功能
  GPIO_InitStructure.GPIO_Pin = GENERAL_MASTER_PIN;
  GPIO_Init(GENERAL_MASTER_GPIO_PORT, &GPIO_InitStructure);
}
  1. 使能GPIO时钟
  • RCC_APB2PeriphClockCmd 使能了与主定时器和从定时器相关的GPIO时钟,并使能了AFIO时钟。
  • GPIO_PinRemapConfig 配置了定时器通道的引脚重映射,例如将 TIM2_CH3 重映射到 PB10
  1. 配置GPIO引脚
  • 使用 GPIO_InitTypeDef 结构体配置引脚。
  • GPIO_InitStructure.GPIO_Mode 设置为推挽复用输出 (GPIO_Mode_AF_PP),以支持定时器的PWM输出。
  • GPIO_InitStructure.GPIO_Speed 设置为 50MHz。
  1. 具体GPIO引脚配置
  • PC6: 配置为 TIM3_CH1 的推挽复用输出。
  • PB6: 配置为 TIM4_CH1 的推挽复用输出。
  • PB10: 配置为 TIM2_CH3 的推挽复用输出。

这里出现了一个新的库函数,我们需要分析一下:

GPIO_PinRemapConfig 是一个用于配置GPIO引脚重映射的库函数,通常用于定时器或其他外设的引脚重映射,以便将外设功能映射到不同的引脚上。它的主要功能是在微控制器中重新定义某些功能引脚的位置。

函数原型

void GPIO_PinRemapConfig(GPIO_TypeDef* GPIOx, FunctionalState NewState);

参数说明

  • GPIOx: 需要重映射的GPIO配置。例如,GPIO_FullRemap_TIM2 代表定时器2的完全重映射。
  • NewState: 指定是否启用重映射。ENABLE 启用重映射,DISABLE 禁用重映射。

功能描述

  • 重映射引脚: 该函数将定时器或其他外设的特定功能引脚映射到其他可用引脚上。例如,将 TIM2_CH3 的功能映射到 PB10
  • 灵活性: 提供了更大的灵活性以适应不同的硬件布局和需求。

使用场景

  • 当你需要将外设的功能引脚分配到不同的物理引脚时,例如在开发过程中调整硬件布局或在应用程序中使用不同的引脚。

示例

GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); // 启用 TIM2 的完全重映射

  • TIM模式配置
// TIM模式配置
static void TIM_Mode_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

  // 使能TIM时钟
  RCC_APB1PeriphClockCmd(GENERAL_TIM_MASTER_CLK | GENERAL_TIM_SLAVE1_CLK | GENERAL_TIM_SLAVE11_CLK, ENABLE);
  // 时基配置
  TIM_TimeBaseStructure.TIM_Period = 72;      
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(GENERAL_TIM_MASTER, &TIM_TimeBaseStructure);

  TIM_TimeBaseStructure.TIM_Period = 4;
  TIM_TimeBaseInit(GENERAL_TIM_SLAVE1, &TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 4;
  TIM_TimeBaseInit(GENERAL_TIM_SLAVE11, &TIM_TimeBaseStructure);

  // 主定时器设置成PWM1模式
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 36; // 占空比
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC3Init(GENERAL_TIM_MASTER, &TIM_OCInitStructure); // 初始化 TIM2 输出通道3

  // 使能主从模式
  TIM_SelectMasterSlaveMode(GENERAL_TIM_MASTER, TIM_MasterSlaveMode_Enable);
  // 输出触发源选项
  TIM_SelectOutputTrigger(GENERAL_TIM_MASTER, TIM_TRGOSource_Update);

  // 从定时器设置成PWM1模式
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 1; // 占空比
  TIM_OC1Init(GENERAL_TIM_SLAVE1, &TIM_OCInitStructure);  // 初始化 TIM3 输出通道1
  TIM_OC1Init(GENERAL_TIM_SLAVE11, &TIM_OCInitStructure); // 初始化 TIM4 输出通道1
  // 使能主从模式
  TIM_SelectMasterSlaveMode(GENERAL_TIM_SLAVE1, TIM_MasterSlaveMode_Enable);
  // 输出触发源选项 
  TIM_SelectOutputTrigger(GENERAL_TIM_SLAVE1, TIM_TRGOSource_Update);

  TIM_SelectSlaveMode(GENERAL_TIM_SLAVE1, TIM_SlaveMode_Gated); // 从模式配置 : TIM3
  TIM_SelectInputTrigger(GENERAL_TIM_SLAVE1, TIM_TS_ITR1);      // 设置输入触发源

  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated);               // 从模式配置 : TIM4
  TIM_SelectInputTrigger(GENERAL_TIM_SLAVE11, TIM_TS_ITR2);     // 设置输入触发源

  // TIM 计数器溢出中断启用
  TIM_Cmd(GENERAL_TIM_SLAVE1, ENABLE);
  TIM_Cmd(GENERAL_TIM_MASTER, ENABLE);
  TIM_Cmd(GENERAL_TIM_SLAVE11, ENABLE);
}
  • 主函数
#include "stm32f10x.h"
#include "./tim/bsp_general_tim.h"

int main(void)
{
    // 初始化通用定时器级联同步PWM输出 
    // 实现:TIM2发生事件更新时发送触发信号驱动TIM3计数 
    //       TIM3发生事件更新时发送触发信号驱动TIM4计数
    TIMx_Configuration();

  while(1)
  {

  }
}

3. 小结

其他步骤我们已经很熟悉了,下面重点来分析一下配置TIM模式:

1. 启用定时器时钟

RCC_APB1PeriphClockCmd(GENERAL_TIM_MASTER_CLK | GENERAL_TIM_SLAVE1_CLK | GENERAL_TIM_SLAVE11_CLK, ENABLE);

这行代码启用了主定时器(GENERAL_TIM_MASTER)和两个从定时器(GENERAL_TIM_SLAVE1GENERAL_TIM_SLAVE11)的时钟,使能它们的计数功能。

2. 配置时基

TIM_TimeBaseStructure.TIM_Period = 72;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(GENERAL_TIM_MASTER, &TIM_TimeBaseStructure);
  • TIM_Period:定时器计数周期。当计数器的值从0增加到此值时,会产生一个溢出事件。
  • TIM_Prescaler:预分频器的值。它控制定时器计数频率。此处设置为0,意味着时钟频率没有被分频。
  • TIM_ClockDivision:时钟分频系数。设置为0时,定时器时钟没有额外分频。
  • TIM_CounterMode:计数模式,这里设置为TIM_CounterMode_Up,意味着计数器将从0向上计数。

3. 配置 PWM 模式

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 36; // 占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(GENERAL_TIM_MASTER, &TIM_OCInitStructure);
  • TIM_OCMode:输出比较模式,这里设置为TIM_OCMode_PWM1,配置为PWM1模式。
  • TIM_OutputState:设置为TIM_OutputState_Enable,启用输出。
  • TIM_Pulse:设置PWM信号的脉宽,决定占空比。脉宽为36。
  • TIM_OCPolarity:输出极性设置为高,即PWM信号的高电平在计数器计数期间持续时间。

4. 配置从定时器

TIM_TimeBaseStructure.TIM_Period = 4;
TIM_TimeBaseInit(GENERAL_TIM_SLAVE1, &TIM_TimeBaseStructure);
TIM_TimeBaseInit(GENERAL_TIM_SLAVE11, &TIM_TimeBaseStructure);

为两个从定时器设置周期为4的计数器。

TIM_OCInitStructure.TIM_Pulse = 1; // 占空比
TIM_OC1Init(GENERAL_TIM_SLAVE1, &TIM_OCInitStructure);
TIM_OC1Init(GENERAL_TIM_SLAVE11, &TIM_OCInitStructure);

5. 配置主从模式

使能主从模式

TIM_SelectMasterSlaveMode(GENERAL_TIM_MASTER, TIM_MasterSlaveMode_Enable);

启用主定时器的主从模式,这使得主定时器可以作为触发源来驱动从定时器。

选择输出触发源

TIM_SelectOutputTrigger(GENERAL_TIM_MASTER, TIM_TRGOSource_Update);

设置主定时器的触发源为更新事件(计数器溢出时),主定时器的更新事件将触发从定时器。

配置从定时器为从模式

TIM_SelectSlaveMode(GENERAL_TIM_SLAVE1, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(GENERAL_TIM_SLAVE1, TIM_TS_ITR1);

GENERAL_TIM_SLAVE1配置为“门控模式”(Gated Mode),这意味着从定时器的计数会被主定时器的触发事件控制。触发源设置为输入触发1(ITR1),这是主定时器的触发信号。

TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(GENERAL_TIM_SLAVE11, TIM_TS_ITR2);

同样地,将GENERAL_TIM_SLAVE11配置为“门控模式”,并设置触发源为输入触发2(ITR2),另一个主定时器的触发信号。

6. 启用定时器

TIM_Cmd(GENERAL_TIM_SLAVE1, ENABLE);
TIM_Cmd(GENERAL_TIM_MASTER, ENABLE);
TIM_Cmd(GENERAL_TIM_SLAVE11, ENABLE);

最后,启用所有定时器,使它们开始计数和生成PWM信号。


2024.9.13 第一次修订,后期不再维护

posted @ 2024-09-13 15:40  hazy1k  阅读(7)  评论(0编辑  收藏  举报