STM32 定时器配置及代码问题处理复习文档

一、需求概述

实现使用外部输入的 PWM 触发内部定时器输出自定义的 m 序列,涉及tim.cmain.c文件的编写与配置,同时解决代码中函数重定义的问题。

二、代码关键部分分析

(一)tim.c文件

1. 定时器初始化

  • 功能:完成 TIM2 定时器的初始化配置,将其设置为外部触发模式(外部触发源为 ETR)。
  • 关键代码

c

TIM_HandleTypeDef htim2;
void MX_TIM2_Init(void) {
    // 定时器参数设置
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 1000; // 根据实际情况调整
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 1000;    // 根据实际情况调整
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
        Error_Handler();
    }

    // 外部触发配置
    TIM_SlaveConfigTypeDef sSlaveConfig = {0};
    sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
    sSlaveConfig.InputTrigger = TIM_TS_ETRF;
    sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED;
    sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
    sSlaveConfig.TriggerFilter = 0;
    if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK) {
        Error_Handler();
    }

    // 主模式配置
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
        Error_Handler();
    }

    // 使能定时器中断
    HAL_TIM_Base_Start_IT(&htim2);
}
  • 注意事项PrescalerPeriod参数需根据实际的外部 PWM 频率和想要的定时器输出序列的时间间隔进行调整。

2. 底层硬件初始化和反初始化

  • 功能:配置 TIM2 的时钟、GPIO 引脚和中断。
  • 关键代码

c

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) {
    if(tim_baseHandle->Instance==TIM2) {
        // 使能TIM2时钟
        __HAL_RCC_TIM2_CLK_ENABLE();

        // 配置GPIO引脚
        __HAL_RCC_GPIOA_CLK_ENABLE();
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        GPIO_InitStruct.Pin = GPIO_PIN_0;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF14_TIM2;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        // 配置TIM2中断
        HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(TIM2_IRQn);
    }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) {
    if(tim_baseHandle->Instance==TIM2) {
        // 禁用TIM2时钟
        __HAL_RCC_TIM2_CLK_DISABLE();

        // 反初始化GPIO引脚
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);

        // 禁用TIM2中断
        HAL_NVIC_DisableIRQ(TIM2_IRQn);
    }
}

3. 中断处理函数(可能导致重定义问题)

  • 功能:处理 TIM2 的中断。
  • 关键代码

c

void TIM2_IRQHandler(void) {
    HAL_TIM_IRQHandler(&htim2);
}

(二)main.c文件

1. m 序列生成和输出函数

  • 功能:生成和输出 m 序列。
  • 关键代码

c

// m序列生成函数
uint8_t generate_mbo(void) {
    static uint8_t m = 0x01; 
    uint8_t feedback;
    feedback = ((m >> 0) ^ (m >> 2) ^ (m >> 3) ^ (m >> 4)) & 0x01;
    m = (m >> 1) | (feedback << 7);
    return m & 0x01;
}

// m序列输出函数
void m_seq(void) {
    uint8_t mbo = generate_mbo();
    if (mbo) {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); 
    } else {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);  
    }
    __asm__ volatile("nop"); 
    __asm__ volatile("nop"); 
    __asm__ volatile("nop"); 
}

2. 主函数和中断回调函数

  • 功能:初始化系统和外设,在定时器溢出中断发生时调用 m 序列输出函数。
  • 关键代码

c

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM2_Init();
    HAL_TIM_Base_Start_IT(&htim2);

    while (1) {
        // 主循环
    }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM2) {
        m_seq();
    }
}

三、常见问题及解决办法

(一)函数重定义问题

  • 问题描述:出现 L6200E: Symbol TIM2_IRQHandler multiply defined (by stm32g4xx_it.o and tim.o) 错误,表明TIM2_IRQHandler函数被重复定义。
  • 可能原因:在多个文件中重复定义,或者自动生成代码与手动添加代码冲突。
  • 解决办法
    • 方法一:移除tim.c文件中的TIM2_IRQHandler定义,将中断处理逻辑移到stm32g4xx_it.c文件中。
    • 方法二:使用条件编译,在tim.c文件中添加条件编译,同时在stm32g4xx_it.c文件里注释掉或者删除TIM2_IRQHandler函数的定义。

四、复习要点总结

  1. 理解定时器初始化的各个参数的含义和作用,能够根据实际需求调整PrescalerPeriod参数。
  2. 掌握定时器外部触发模式的配置方法,包括TIM_SlaveConfigTypeDef结构体的使用。
  3. 熟悉 GPIO 引脚和中断的初始化和反初始化操作。
  4. 理解 m 序列的生成和输出原理,掌握相关函数的编写。
  5. 学会处理函数重定义问题,避免代码中出现类似错误。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇