[活动] 【APM32F411V Tiny Board测评】2.定时器和PWM输出测试

[复制链接]
976|1
 楼主| yuyy1989 发表于 2024-5-7 22:05 | 显示全部楼层 |阅读模式
APM32F411有2个16位高级定时器、8个16位通用定时器、2个32位通用定时器
微信截图_20240507195218.png
使用Timer9实现一个1ms周期的定时器,先配置一下系统时钟,开启外部高速晶振,PLL到120MHz

  1. void ConfigSysClock(void)
  2. {
  3.     RCM_Reset();

  4.     /* Open HSE 8MHz */
  5.     RCM_ConfigHSE(RCM_HSE_OPEN);

  6.     if(RCM_WaitHSEReady() == SUCCESS)
  7.     {
  8.         FMC_EnablePrefetchBuffer();
  9.         FMC_ConfigLatency(FMC_LTNCY_4);

  10.         RCM_ConfigAHB(RCM_AHB_DIV_1);
  11.         RCM_ConfigAPB2(RCM_APB_DIV_1);
  12.         RCM_ConfigAPB1(RCM_APB_DIV_2);

  13.         RCM_ConfigPLL1(RCM_PLLSEL_HSE, 4,120,RCM_PLL_SYS_DIV_2,6);
  14.         RCM_EnablePLL1();

  15.         /* Wait for PLL1 Ready */
  16.         while(RCM_ReadStatusFlag(RCM_FLAG_PLL1RDY) == RESET);

  17.         /* Select PLL1 as System Clock */
  18.         RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
  19.         while(RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_PLL);
  20.         SystemCoreClockUpdate();
  21.     }
  22.     else
  23.     {
  24.         while(1);
  25.     }
  26. }
参考时钟树
微信截图_20240507195320.png
Timer9在APB2上,时钟配置里APB2分频是1,Timer9基础频率为120MHz,配置Timer9和中断
  1. void tim9_init()
  2. {
  3.     TMR_BaseConfig_T TMR_TimeBaseStruct;
  4.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
  5.     TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
  6.     TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
  7.     TMR_TimeBaseStruct.division = 119;
  8.     TMR_TimeBaseStruct.repetitionCounter = 0;
  9.     TMR_TimeBaseStruct.period = 999;
  10.     TMR_ConfigTimeBase(TMR9, &TMR_TimeBaseStruct);
  11.     TMR_EnableInterrupt(TMR9,TMR_INT_UPDATE);
  12.     NVIC_EnableIRQRequest(TMR1_BRK_TMR9_IRQn, 0, 0);
  13.     TMR_Enable(TMR9);
  14. }
  15. uint16_t timer9_count = 1000;
  16. void TMR1_BRK_TMR9_IRQHandler(void)
  17. {
  18.     if(TMR_ReadIntFlag(TMR9, TMR_INT_UPDATE) == SET)
  19.     {
  20.         TMR_ClearIntFlag(TMR9, TMR_INT_UPDATE);
  21.         if(timer9_count > 0)
  22.             timer9_count -= 1;
  23.         if(timer9_count == 0)
  24.         {
  25.             timer9_count = 1000;
  26.             yuyy_LedToggle(YUYY_LED2);
  27.             yuyy_LedToggle(YUYY_LED3);
  28.         }
  29.         LedChangeColor();
  30.     }
  31. }
运行效果
WeChat_20240507215532 00_00_00-00_00_30.gif
接下来通过PWM让这个RGB灯珠实现彩色变化
微信截图_20240426205352.png
选用PA6 PA7 PB0作为RGB输出,分别对应Timer3的CH1、CH2、CH3
微信截图_20240507215811.png
微信截图_20240507215826.png
灯珠是共阳极的,这里采用PWM1模式,计数小于设定值时输出有效电平,设置低电平为有效电平
  1. void pwm_init()
  2. {
  3.     TMR_BaseConfig_T TMR_TimeBaseStruct;
  4.     TMR_OCConfig_T OCcongigStruct;
  5.     GPIO_Config_T GPIO_ConfigStruct;
  6.    
  7.     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
  8.     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
  9.    
  10.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
  11.     GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
  12.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_0, GPIO_AF_TMR3);
  13.    
  14.     GPIO_ConfigStruct.pin = GPIO_PIN_6 | GPIO_PIN_7;
  15.     GPIO_ConfigStruct.mode = GPIO_MODE_AF;
  16.     GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
  17.     GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
  18.     GPIO_Config(GPIOA, &GPIO_ConfigStruct);
  19.     GPIO_ConfigStruct.pin = GPIO_PIN_0;
  20.     GPIO_Config(GPIOB, &GPIO_ConfigStruct);
  21.    
  22.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
  23.     TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
  24.     TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
  25.     TMR_TimeBaseStruct.division = 119;
  26.     TMR_TimeBaseStruct.repetitionCounter = 0;
  27.     TMR_TimeBaseStruct.period = 999; //频率1k 占空比调节0-1000
  28.     TMR_ConfigTimeBase(TMR3, &TMR_TimeBaseStruct);
  29.    
  30.     OCcongigStruct.mode = TMR_OC_MODE_PWM1;              //PWM模式1,计数小于比较值时输出有效电平
  31.     OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;    //通道使能
  32.     OCcongigStruct.idleState = TMR_OC_IDLE_STATE_SET;    //空闲高电平
  33.     OCcongigStruct.polarity = TMR_OC_POLARITY_LOW;       //有效电平为低电平
  34.     OCcongigStruct.outputNState = TMR_OC_NSTATE_DISABLE; //互补通道失能
  35.     OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;//互补通道空闲电平
  36.     OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH;    //互补通道有效电平
  37.     OCcongigStruct.pulse = 0;                          //初始0%
  38.     TMR_ConfigOC1(TMR3, &OCcongigStruct);
  39.     TMR_ConfigOC2(TMR3, &OCcongigStruct);
  40.     TMR_ConfigOC3(TMR3, &OCcongigStruct);
  41.    
  42.     TMR_ConfigOC1Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
  43.     TMR_ConfigOC2Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
  44.     TMR_ConfigOC3Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
  45.     TMR_EnableAutoReload(TMR3);
  46.     TMR_Enable(TMR3);
  47.     TMR_EnablePWMOutputs(TMR3);

  48.     TMR_ConfigCompare1(TMR3,0);
  49.     TMR_ConfigCompare2(TMR3,0);
  50.     TMR_ConfigCompare3(TMR3,0);
  51. }
实现彩色渐变函数
  1. uint8_t ledstep = 0;
  2. uint16_t pwm = 0;
  3. void LedSetPwm(uint8_t ch,uint16_t pwm)
  4. {
  5.     if(ch == 0)
  6.         TMR_ConfigCompare1(TMR3,pwm);
  7.     else if(ch == 1)
  8.         TMR_ConfigCompare2(TMR3,pwm);
  9.     else if(ch == 2)
  10.         TMR_ConfigCompare3(TMR3,pwm);
  11. }
  12. void LedChangeColor(void)
  13. {
  14.     uint8_t ch1 = 0;
  15.     uint8_t ch2 = 1;
  16.     if(ledstep >1)
  17.     {
  18.         ch1 = 2;
  19.         ch2 = 0;
  20.     }
  21.     else if(ledstep >0)
  22.     {
  23.         ch1 = 1;
  24.         ch2 = 2;
  25.     }
  26.     LedSetPwm(ch1,1000 - pwm);
  27.     LedSetPwm(ch2,pwm);
  28.     pwm += 1;
  29.     if(pwm > 1000)
  30.     {
  31.         ledstep += 1;
  32.         pwm = 0;
  33.     }
  34.     if(ledstep == 3)
  35.         ledstep = 0;
  36. }
在之前的1ms定时器中调用LedChangeColor,运行效果
WeChat_20240507215523 00_00_00-00_00_30.gif


HJLVVV 发表于 2024-8-21 09:35 | 显示全部楼层
大佬,我想用APM32F411输出一个互补PWM,有没有相似的案例能提供参考?跪求!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

168

主题

826

帖子

10

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