[APM32E0] APM32E030的定时器驱动(PWM互补输出)

[复制链接]
42|0
口天土立口 发表于 2025-10-16 08:59 | 显示全部楼层 |阅读模式
8270868f0411dd9b92.png

APM32E030的定时器有三类,不同定时器支持的功能互有差异,部分定时器支持互补输出,可用于控制电机;

驱动代码如下:
  1. #define TIM_INS     (TMR1)

  2. /* 定时器更新中断处理函数 */
  3. static tim_update_deal_func_f tim_update_deal_func;
  4. /* 100%占空比值 */
  5. static uint32_t DUTY_100;
  1. /*
  2. * [url=/u/brief]@brief[/url]       PWM引脚初始化
  3. *
  4. * @param       None
  5. *
  6. * @retval      None
  7. *
  8. */
  9. static void bsp_tim_pwm_gpio_init(void)
  10. {
  11.     GPIO_Config_T gpioConfig;
  12.    
  13.     /*  PA8  -> TMR1_CH1
  14.      *  PA9  -> TMR1_CH2
  15.      *  PA10 -> TMR1_CH3
  16.      *  PA11 -> TMR1_CH4
  17.      *
  18.      *  PB12 -> TMR1_BKIN
  19.      *  PB13 -> TMR1_CH1N
  20.      *  PB14 -> TMR1_CH2N
  21.      *  PB15 -> TMR1_CH3N
  22.      */
  23.     RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
  24.     RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
  25.     GPIO_ConfigStructInit(&gpioConfig);
  26.     gpioConfig.pin     = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
  27.     gpioConfig.mode    = GPIO_MODE_AF;
  28.     gpioConfig.outtype = GPIO_OUT_TYPE_PP;
  29.     gpioConfig.speed   = GPIO_SPEED_50MHz;
  30.     gpioConfig.pupd    = GPIO_PUPD_NO;
  31.     GPIO_Config(GPIOA, &gpioConfig);
  32.     gpioConfig.pin     = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  33.     GPIO_Config(GPIOB, &gpioConfig);
  34.    
  35.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_8, GPIO_AF_PIN2);
  36.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_9, GPIO_AF_PIN2);
  37.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_10, GPIO_AF_PIN2);
  38.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_11, GPIO_AF_PIN2);
  39.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_12, GPIO_AF_PIN2);
  40.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_13, GPIO_AF_PIN2);
  41.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_14, GPIO_AF_PIN2);
  42.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_15, GPIO_AF_PIN2);
  43. }
  1. /*
  2. * @brief       定时器初始化
  3. *
  4. * @param       ms: 定时间隔
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_tim_init(uint16_t ms)
  10. {
  11.     TMR_TimeBase_T timeBaseConfig;
  12.     TMR_OCConfig_T OCcongigStruct;
  13.     TMR_BDTInit_T BDTStruct;
  14.    
  15.     /* 寄存器AUTORLD为16bit */
  16.     if ((ms >= 1) && (ms <= 6553)) {
  17.         bsp_tim_pwm_gpio_init();
  18.         
  19.         /* 定时器周期 */
  20.         RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
  21.         TMR_Reset(TIM_INS);
  22.         TMR_ConfigTimeBaseStruct(&timeBaseConfig);
  23.         /* CK_CNT=fCK_PSC/(PSC+1) */
  24.         timeBaseConfig.div = 7200 - 1;              /* 10KHz */
  25.         timeBaseConfig.period = (ms * 10) - 1;
  26.         timeBaseConfig.clockDivision = TMR_CKD_DIV1;
  27.         timeBaseConfig.counterMode = TMR_COUNTER_MODE_UP;
  28.         timeBaseConfig.repetitionCounter = 0;
  29.         TMR_ConfigTimeBase(TIM_INS, &timeBaseConfig);
  30.         
  31.         /* PWM */
  32.         DUTY_100 = timeBaseConfig.period;
  33.         TMR_OCConfigStructInit(&OCcongigStruct);
  34.         /* PWM 模式 1(计数器值 < 输出比较值时置为高,否则反之) */
  35.         OCcongigStruct.OC_Mode = TMR_OC_MODE_PWM1;
  36.         /* 输出使能 */
  37.         OCcongigStruct.OC_OutputState = TMR_OUTPUT_STATE_ENABLE;
  38.         /* 互补输出使能 */
  39.         OCcongigStruct.OC_OutputNState = TMR_OUTPUT_NSTATE_ENABLE;
  40.         /* 默认50%占空比 */
  41.         OCcongigStruct.Pulse = (DUTY_100 + 1) / 2;
  42.         OCcongigStruct.OC_Polarity = TMR_OC_POLARITY_HIGH;
  43.         OCcongigStruct.OC_NPolarity = TMR_OC_NPOLARITY_HIGH;
  44.         OCcongigStruct.OC_Idlestate = TMR_OCIDLESTATE_RESET;
  45.         OCcongigStruct.OC_NIdlestate = TMR_OCNIDLESTATE_RESET;
  46.         TMR_OC1Config(TIM_INS, &OCcongigStruct);
  47.         TMR_OC2Config(TIM_INS, &OCcongigStruct);
  48.         TMR_OC3Config(TIM_INS, &OCcongigStruct);
  49.         TMR_OC4Config(TIM_INS, &OCcongigStruct);
  50.         /* 使能预装载功能: 写入比较寄存器CC的值在更新事件后才起作用 */
  51.         TMR_OC1PreloadConfig(TIM_INS, TMR_OC_PRELOAD_ENABLE);
  52.         TMR_OC2PreloadConfig(TIM_INS, TMR_OC_PRELOAD_ENABLE);
  53.         TMR_OC3PreloadConfig(TIM_INS, TMR_OC_PRELOAD_ENABLE);
  54.         TMR_OC4PreloadConfig(TIM_INS, TMR_OC_PRELOAD_ENABLE);
  55.         /* 刹车 */
  56.         TMR_ConfigBDTStructInit(&BDTStruct);
  57.         BDTStruct.RMOS_State = TMR_RMOS_STATE_DISABLE;
  58.         BDTStruct.IMOS_State = TMR_IMOS_STATE_DISABLE;
  59.         BDTStruct.lockLevel = TMR_LOCK_LEVEL_OFF;
  60.         /* 定时器时钟源为72MHz, 死区时间1us = 72  */
  61.         BDTStruct.deadTime = 72;
  62.         /* 使能刹车功能 */
  63.         BDTStruct.breakState = TMR_BREAK_STATE_ENABLE;
  64.         /* 刹车信号高电平有效 */
  65.         BDTStruct.breakPolarity = TMR_BREAK_POLARITY_HIGH;
  66.         /* 刹车信号无效时自动恢复输出 */
  67.         BDTStruct.automaticOutput = TMR_AUTOMATIC_OUTPUT_ENABLE;
  68.         TMR_ConfigBDT(TIM_INS, &BDTStruct);
  69.         /* 不使能刹车信号无效自动恢复输出功能时,需调用此函数手动开启互补输出 */
  70. //        TMR_EnablePWMOutputs(TIM_INS);
  71.         
  72.         /* 使能更新中断 */
  73.         TMR_EnableInterrupt(TIM_INS, TMR_INT_UPDATE);
  74.         /* 使能刹车中断 */
  75.         TMR_EnableInterrupt(TIM_INS, TMR_INT_BRK);
  76.         /* 使能中断 */
  77.         NVIC_SetPriority(TMR1_BRK_UP_TRG_COM_IRQn, 0);
  78.         NVIC_EnableIRQ(TMR1_BRK_UP_TRG_COM_IRQn);   
  79.         
  80.         /* 使能定时器 */
  81.         TMR_Enable(TIM_INS);
  82.     }
  83. }
  1. /*
  2. * @brief       中断
  3. *
  4. * @param       None
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void TMR1_BRK_UP_TRG_COM_IRQHandler(void)
  10. {
  11.     /* 更新标志 */
  12.     if (TMR_ReadIntFlag(TIM_INS,  TMR_INT_FLAG_UPDATE) == SET) {
  13.         TMR_ClearIntFlag(TIM_INS,  TMR_INT_FLAG_UPDATE);
  14.         (tim_update_deal_func != NULL) ? tim_update_deal_func() : NULL;
  15.     }
  16.     /*  刹车标志 */
  17.     if (TMR_ReadIntFlag(TIM_INS,  TMR_INT_FLAG_BRK) == SET) {
  18.         TMR_ClearIntFlag(TIM_INS,  TMR_INT_FLAG_BRK);
  19.     }
  20. }
  1. /*
  2. * @brief       定时器更新处理函数注册
  3. *
  4. * @param       func: 定时器更新中断处理函数
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_tim_update_deal_func_register(tim_update_deal_func_f func)
  10. {
  11.     tim_update_deal_func = func;
  12. }
  1. /*
  2. * @brief       PWM占空比设置
  3. *
  4. * @param       duty1: PWM1占空比
  5. *              duty2: PWM2占空比
  6. *              duty3: PWM3占空比
  7. *              duty4: PWM4占空比
  8. *
  9. * @retval      None
  10. *
  11. */
  12. void bsp_pwm_duty_set(uint8_t duty1, uint8_t duty2, uint8_t duty3, uint8_t duty4)
  13. {
  14.     (duty1 <= 100) ? \
  15.         TMR_SetCompare1(TIM_INS, (DUTY_100 + 1) * duty1 / 100) : NULL;
  16.     (duty2 <= 100) ? \
  17.         TMR_SetCompare2(TIM_INS, (DUTY_100 + 1) * duty2 / 100) : NULL;
  18.     (duty3 <= 100) ? \
  19.         TMR_SetCompare3(TIM_INS, (DUTY_100 + 1) * duty3 / 100) : NULL;
  20.     (duty4 <= 100) ? \
  21.         TMR_SetCompare4(TIM_INS, (DUTY_100 + 1) * duty4 / 100) : NULL;
  22. }


测试代码如下:
  1. /* 占空比 */
  2. uint8_t pwm1_duty = 20;
  3. uint8_t pwm2_duty = 40;
  4. uint8_t pwm3_duty = 60;
  5. uint8_t pwm4_duty = 80;
  1. void test_gpio_init(void)
  2. {
  3.     GPIO_Config_T gpioConfig;
  4.     RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
  5.     GPIO_ConfigStructInit(&gpioConfig);
  6.     gpioConfig.pin     = GPIO_PIN_5;
  7.     gpioConfig.mode    = GPIO_MODE_OUT;
  8.     gpioConfig.outtype = GPIO_OUT_TYPE_PP;
  9.     gpioConfig.speed   = GPIO_SPEED_50MHz;
  10.     gpioConfig.pupd    = GPIO_PUPD_NO;
  11.     GPIO_Config(GPIOA, &gpioConfig);
  12. }
  1. void test_gpio_toggle(void)
  2. {
  3.     (GPIO_ReadOutputBit(GPIOA, GPIO_PIN_5) == BIT_SET) ? \
  4.         GPIO_ClearBit(GPIOA, GPIO_PIN_5) : \
  5.         GPIO_SetBit(GPIOA, GPIO_PIN_5);
  6. }
  1. // 应用初始化
  2. void app_init(void)
  3. {
  4.     test_gpio_init();
  5.     bsp_tim_update_deal_func_register(test_gpio_toggle);
  6.     bsp_tim_init(100);
  7. }

  8. // 应用任务
  9. void app_task(void)
  10. {
  11.     bsp_pwm_duty_set(pwm1_duty, pwm2_duty, pwm3_duty, pwm4_duty);
  12. }

2488768f0431f5d756.png 670068f0435cc818c.png

详细代码,请查看附件!
PWM_TIM1.zip (2.14 MB, 下载次数: 0)



您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

54

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部