APM32F411有2个16位高级定时器、8个16位通用定时器、2个32位通用定时器
使用Timer9实现一个1ms周期的定时器,先配置一下系统时钟,开启外部高速晶振,PLL到120MHz
- void ConfigSysClock(void)
- {
- RCM_Reset();
- /* Open HSE 8MHz */
- RCM_ConfigHSE(RCM_HSE_OPEN);
- if(RCM_WaitHSEReady() == SUCCESS)
- {
- FMC_EnablePrefetchBuffer();
- FMC_ConfigLatency(FMC_LTNCY_4);
- RCM_ConfigAHB(RCM_AHB_DIV_1);
- RCM_ConfigAPB2(RCM_APB_DIV_1);
- RCM_ConfigAPB1(RCM_APB_DIV_2);
- RCM_ConfigPLL1(RCM_PLLSEL_HSE, 4,120,RCM_PLL_SYS_DIV_2,6);
- RCM_EnablePLL1();
- /* Wait for PLL1 Ready */
- while(RCM_ReadStatusFlag(RCM_FLAG_PLL1RDY) == RESET);
- /* Select PLL1 as System Clock */
- RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
- while(RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_PLL);
- SystemCoreClockUpdate();
- }
- else
- {
- while(1);
- }
- }
参考时钟树
Timer9在APB2上,时钟配置里APB2分频是1,Timer9基础频率为120MHz,配置Timer9和中断
- void tim9_init()
- {
- TMR_BaseConfig_T TMR_TimeBaseStruct;
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
- TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_TimeBaseStruct.division = 119;
- TMR_TimeBaseStruct.repetitionCounter = 0;
- TMR_TimeBaseStruct.period = 999;
- TMR_ConfigTimeBase(TMR9, &TMR_TimeBaseStruct);
- TMR_EnableInterrupt(TMR9,TMR_INT_UPDATE);
- NVIC_EnableIRQRequest(TMR1_BRK_TMR9_IRQn, 0, 0);
- TMR_Enable(TMR9);
- }
- uint16_t timer9_count = 1000;
- void TMR1_BRK_TMR9_IRQHandler(void)
- {
- if(TMR_ReadIntFlag(TMR9, TMR_INT_UPDATE) == SET)
- {
- TMR_ClearIntFlag(TMR9, TMR_INT_UPDATE);
- if(timer9_count > 0)
- timer9_count -= 1;
- if(timer9_count == 0)
- {
- timer9_count = 1000;
- yuyy_LedToggle(YUYY_LED2);
- yuyy_LedToggle(YUYY_LED3);
- }
- LedChangeColor();
- }
- }
运行效果
接下来通过PWM让这个RGB灯珠实现彩色变化
选用PA6 PA7 PB0作为RGB输出,分别对应Timer3的CH1、CH2、CH3
灯珠是共阳极的,这里采用PWM1模式,计数小于设定值时输出有效电平,设置低电平为有效电平
- void pwm_init()
- {
- TMR_BaseConfig_T TMR_TimeBaseStruct;
- TMR_OCConfig_T OCcongigStruct;
- GPIO_Config_T GPIO_ConfigStruct;
-
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
-
- GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
- GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_0, GPIO_AF_TMR3);
-
- GPIO_ConfigStruct.pin = GPIO_PIN_6 | GPIO_PIN_7;
- GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- GPIO_Config(GPIOA, &GPIO_ConfigStruct);
- GPIO_ConfigStruct.pin = GPIO_PIN_0;
- GPIO_Config(GPIOB, &GPIO_ConfigStruct);
-
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
- TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_TimeBaseStruct.division = 119;
- TMR_TimeBaseStruct.repetitionCounter = 0;
- TMR_TimeBaseStruct.period = 999; //频率1k 占空比调节0-1000
- TMR_ConfigTimeBase(TMR3, &TMR_TimeBaseStruct);
-
- OCcongigStruct.mode = TMR_OC_MODE_PWM1; //PWM模式1,计数小于比较值时输出有效电平
- OCcongigStruct.outputState = TMR_OC_STATE_ENABLE; //通道使能
- OCcongigStruct.idleState = TMR_OC_IDLE_STATE_SET; //空闲高电平
- OCcongigStruct.polarity = TMR_OC_POLARITY_LOW; //有效电平为低电平
- OCcongigStruct.outputNState = TMR_OC_NSTATE_DISABLE; //互补通道失能
- OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;//互补通道空闲电平
- OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH; //互补通道有效电平
- OCcongigStruct.pulse = 0; //初始0%
- TMR_ConfigOC1(TMR3, &OCcongigStruct);
- TMR_ConfigOC2(TMR3, &OCcongigStruct);
- TMR_ConfigOC3(TMR3, &OCcongigStruct);
-
- TMR_ConfigOC1Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_ConfigOC2Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_ConfigOC3Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_EnableAutoReload(TMR3);
- TMR_Enable(TMR3);
- TMR_EnablePWMOutputs(TMR3);
- TMR_ConfigCompare1(TMR3,0);
- TMR_ConfigCompare2(TMR3,0);
- TMR_ConfigCompare3(TMR3,0);
- }
实现彩色渐变函数
- uint8_t ledstep = 0;
- uint16_t pwm = 0;
- void LedSetPwm(uint8_t ch,uint16_t pwm)
- {
- if(ch == 0)
- TMR_ConfigCompare1(TMR3,pwm);
- else if(ch == 1)
- TMR_ConfigCompare2(TMR3,pwm);
- else if(ch == 2)
- TMR_ConfigCompare3(TMR3,pwm);
- }
- void LedChangeColor(void)
- {
- uint8_t ch1 = 0;
- uint8_t ch2 = 1;
- if(ledstep >1)
- {
- ch1 = 2;
- ch2 = 0;
- }
- else if(ledstep >0)
- {
- ch1 = 1;
- ch2 = 2;
- }
- LedSetPwm(ch1,1000 - pwm);
- LedSetPwm(ch2,pwm);
- pwm += 1;
- if(pwm > 1000)
- {
- ledstep += 1;
- pwm = 0;
- }
- if(ledstep == 3)
- ledstep = 0;
- }
在之前的1ms定时器中调用LedChangeColor,运行效果
|