- /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_B) * PLL_A */
- #define PLL_B 8
- /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLL_D */
- #define PLL_D 4
- #define PLL_A 192
- /* SYSCLK = PLL_VCO / PLL_C */
- #define PLL_C 2
接下来继续进行定时器的初始化配置:
- void APM_TMR1_Init(void)
- {
- TMR_BaseConfig_T TMR_BaseConfigStruct;
- /* Enable TMR1 Periph Clock */
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
-
- APM_HCLKFreq = RCM_ReadHCLKFreq();
- /* 定时10ms */
- APM_TMR1_DIV = APM_HCLKFreq/1000*10/1000-1;
- /* Config TMR1 */
- TMR_BaseConfigStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_BaseConfigStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_BaseConfigStruct.division = APM_TMR1_DIV;
- TMR_BaseConfigStruct.period = 999;
- TMR_BaseConfigStruct.repetitionCounter = 0;
- TMR_ConfigTimeBase(TMR1, &TMR_BaseConfigStruct);
- /* Enable TMR1 Interrupt */
- TMR_EnableInterrupt(TMR1, TMR_INT_UPDATE);
- NVIC_EnableIRQRequest(TMR1_UP_TMR10_IRQn, 0, 0);
- TMR_Enable(TMR1);
- }
在中断处理中加入按键判断,KEY2控制灯的闪烁:
- void TMR1_UP_TMR10_IRQHandler(void)
- {
- if(TMR_ReadIntFlag(TMR1, TMR_INT_UPDATE) == SET)
- {
- TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
-
- if(APM_EINT0_flag == 1)
- {
- TMR1_cnt++;
- if(TMR1_cnt%50 == 0)
- {
- APM_LED3_Toggle;
- APM_LED2_Toggle;
- }
- }
-
- }
- }
接下来是通过定时器的PWM功能实现呼吸灯的效果,LED对应的PE5和PE6的引脚功能如下:
可以看到对应的是定时器9的CH1和CH2,我们用的产生PWM的定时器为定时器9,使用的时钟依然是APB2.
初始化如下:
- void APM_TMR9_Init(void)
- {
- TMR_BaseConfig_T TMR_BaseConfigStruct;
- TMR_OCConfig_T OCcongigStruct;
- GPIO_Config_T GPIO_ConfigStruct;
-
-
- /* Enable TMR1 Periph Clock */
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOE);
-
-
- /* TMR9_CH1 */
- GPIO_ConfigPinAF(GPIOE, GPIO_PIN_SOURCE_5, GPIO_AF_TMR9);
- /* TMR9_CH2 */
- GPIO_ConfigPinAF(GPIOE, GPIO_PIN_SOURCE_6, GPIO_AF_TMR9);
-
- // /* Config TMR2 GPIO for output PWM */
- // GPIO_ConfigStruct.pin = GPIO_PIN_5|GPIO_PIN_6;
- // GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- // GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- // GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- // GPIO_Config(GPIOE, &GPIO_ConfigStruct);
-
-
- APM_HCLKFreq = RCM_ReadHCLKFreq();
- /* 频率200Hz */
- APM_TMR1_DIV = APM_HCLKFreq/200/1000-1;
- /* Config TMR1 */
- TMR_BaseConfigStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_BaseConfigStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_BaseConfigStruct.division = 999;
- TMR_BaseConfigStruct.period = APM_TMR1_DIV;
- TMR_ConfigTimeBase(TMR9, &TMR_BaseConfigStruct);
-
- /* Configure channel1 */
- TMR_ConfigOCStructInit(&OCcongigStruct);
- OCcongigStruct.mode = TMR_OC_MODE_PWM1;
- OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;
- OCcongigStruct.polarity = TMR_OC_POLARITY_HIGH;
-
- OCcongigStruct.pulse = 500;
- TMR_ConfigOC1(TMR9, &OCcongigStruct);
- TMR_ConfigOC1Preload(TMR9, TMR_OC_PRELOAD_ENABLE);
- /* Configure channel2 */
- OCcongigStruct.pulse = 200;
- TMR_ConfigOC2(TMR9, &OCcongigStruct);
- TMR_ConfigOC2Preload(TMR9, TMR_OC_PRELOAD_ENABLE);
- TMR_EnableAutoReload(TMR9);
- // TMR_Enable(TMR9);
- }
注意,我们在初始化里面没有开启定时器和引脚的初始化,这里主要因为LED的引脚的功能是复用的,在正常状态默认是输出控制,只有开启后才是PWM控制,这里面的切换在按键中断中进行:
- void EINT1_IRQHandler(void)
- {
- if(EINT_ReadIntFlag(EINT_LINE_1))
- {
-
- /*Clear EINT_LINE0 interrupt flag*/
- EINT_ClearIntFlag(EINT_LINE_1);
-
- if(APM_EINT1_flag == 0)
- {
- if(APM_EINT0_flag == 0)
- {
- GPIO_Config_T GPIO_ConfigStruct;
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOE);
- /* Config TMR2 GPIO for output PWM */
- GPIO_ConfigStruct.pin = GPIO_PIN_5|GPIO_PIN_6;
- GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- GPIO_Config(GPIOE, &GPIO_ConfigStruct);
-
- TMR_EnableAutoReload(TMR9);
- TMR_Enable(TMR9);
-
- APM_EINT1_flag = 1;
-
-
- printf("APM_LED breathing start \r\n");
- }
- else
- {
- printf("Plase stop APM_LED bilinking \r\n");
- }
- }
- else
- {
- APM_EINT1_flag = 0;
- TMR_Disable(TMR9);
-
- GPIO_Config_T GPIO_ConfigStruct;
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOE);
-
- GPIO_ConfigStruct.pin = GPIO_PIN_5|GPIO_PIN_6;
- GPIO_ConfigStruct.mode = GPIO_MODE_OUT;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- GPIO_Config(GPIOE, &GPIO_ConfigStruct);
-
- APM_LED2_Off;
- APM_LED3_Off;
-
-
- printf("APM_LED breathing stop \r\n");
- }
- }
- }
定时器中断中加入呼吸灯程序:
- if(APM_EINT1_flag == 1)
- {
- TMR_OCConfig_T OCcongigStruct;
- TMR1_breaking_cnt++;
-
- TMR_ConfigOCStructInit(&OCcongigStruct);
- OCcongigStruct.mode = TMR_OC_MODE_PWM1;
- OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;
- OCcongigStruct.polarity = TMR_OC_POLARITY_HIGH;
-
- if(TMR1_breaking_cnt >= 200)
- {
- TMR1_breaking_cnt = 0;
- }
-
- if(TMR1_breaking_cnt<=100)
- {
- OCcongigStruct.pulse = TMR1_breaking_cnt*10;
- }
- else if(TMR1_breaking_cnt>100)
- {
- OCcongigStruct.pulse = (200 - TMR1_breaking_cnt)*10;
- }
-
- TMR_ConfigOC1(TMR9, &OCcongigStruct);
- TMR_ConfigOC2(TMR9, &OCcongigStruct);
- TMR_ConfigOC1Preload(TMR9, TMR_OC_PRELOAD_ENABLE);
- TMR_ConfigOC2Preload(TMR9, TMR_OC_PRELOAD_ENABLE);
-
- }
可以看到串口打印基本操作:
实际上咱们得按键采集没有加入防抖,所以会有出现连键的情况,不过和现象还是一致的,效果如下: