在工程中,原来利用GPIO外部中断实现脉冲计数,因为是低功耗设计,所以MCU平时都是Halt状态。觉得如果利用ETR的输入,配合
tiM的计数溢出中断可以减少从低功耗模式中恢复的次数,以降低系统占空比。但是发现TIMx的设计必须依赖于内部sysclk的存在,如果halt模式下停止sysclk,则TIMx的CNTL/CNTH完全不更新。
- #include "stm8l15x.h"
- #include
- uint32_t ul2;
- uint32_t ul3;
- INTERRUPT_HANDLER(TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler,19)
- {
- if(TIM2_GetITStatus(TIM2_IT_Update) != RESET)
- {
- ul2++;
- TIM2_ClearITPendingBit(TIM2_IT_Update);
- }
- }
- INTERRUPT_HANDLER(TIM3_UPD_OVF_TRG_BRK_USART3_TX_IRQHandler,21)
- {
- if(TIM3_GetITStatus(TIM3_IT_Update) != RESET)
- {
- ul3++;
- TIM3_ClearITPendingBit(TIM3_IT_Update);
- }
- }
- void setup( void )
- {
- CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
- CLK->ICKCR |= 0x40;
- // enable CCKO 38kHz
- CLK->CCOR = CLK_CCOSource_LSI;
- GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Slow);
- GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_In_PU_No_IT);
- GPIO_Init(GPIOD, GPIO_Pin_1, GPIO_Mode_In_PU_No_IT);
- GPIO_Init(GPIOE, GPIO_Pin_2, GPIO_Mode_Out_PP_Low_Slow);
- GPIO_Init(GPIOA, GPIO_Pin_4, GPIO_Mode_In_PU_No_IT);
- GPIO_Init(GPIOA, GPIO_Pin_5, GPIO_Mode_In_PU_No_IT);
- SYSCFG->RMPCR3 |= SYSCFG_RMPCR3_CCO_REMAP;
- SYSCFG->RMPCR2 |= SYSCFG_RMPCR2_TIM2TRIG_REMAP;
- SYSCFG->RMPCR2 |= SYSCFG_RMPCR2_TIM3TRIG_REMAP1;
- // short cut PC4/PB3 or PC4/PD1 without changing SYSCFG_Remap.
- // SYSCFG_RMPCR3, CCO_REMAP = 0:1 = PC4:PE2
- // SYSCFG_RMPCR2, TIM2_TRG_REMAP = 0:1 = PB3:PA4
- // SYSCFG_RMPCR2, TIM3_TRG_REMAP = 0:1 = PD1:PA5
- TIM2_DeInit();
- CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
- //TIM2_ETRClockMode2Config(TIM2_ExtTRGPSC_DIV2, TIM2_ExtTRGPolarity_NonInverted,0x00);
- TIM2_ETRClockMode2Config(TIM2_ExtTRGPSC_OFF, TIM2_ExtTRGPolarity_Inverted,0x00);
- //TIM2_TimeBaseInit(TIM2_Prescaler_1,TIM2_CounterMode_Up,9999);
- TIM2_TimeBaseInit(TIM2_Prescaler_1,TIM2_CounterMode_Up,100);
- TIM2_ITConfig(TIM2_IT_Update,ENABLE);
- TIM2_SetCounter(0x0);
- TIM2_ClearITPendingBit(TIM2_IT_Update);
- TIM2_Cmd(ENABLE);
- TIM3_DeInit();
- CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);
- //TIM3_ETRClockMode2Config(TIM3_ExtTRGPSC_DIV2, TIM3_ExtTRGPolarity_NonInverted,0x00);
- TIM3_ETRClockMode2Config(TIM3_ExtTRGPSC_OFF, TIM3_ExtTRGPolarity_Inverted,0x00);
- //TIM3_TimeBaseInit(TIM3_Prescaler_1,TIM3_CounterMode_Up,9999);
- TIM3_TimeBaseInit(TIM3_Prescaler_1,TIM3_CounterMode_Up,100);
- TIM3_ITConfig(TIM3_IT_Update,ENABLE);
- TIM3_SetCounter(0x0);
- TIM3_ClearITPendingBit(TIM3_IT_Update);
- TIM3_Cmd(ENABLE);
- enableInterrupts();
- }
- void Halt_Init(void)
- {
- /* Set STM8 in low power */
- PWR->CSR2 = 0x2;
- /* Stop RTC Source clock */
- CLK_RTCClockConfig(CLK_RTCCLKSource_Off, CLK_RTCCLKDiv_1);
- #ifdef USE_LSE
- CLK_LSEConfig(CLK_LSE_OFF);
- while ((CLK->ECKCR 0x04) != 0x00);
- #else
- CLK_LSICmd(DISABLE);
- while ((CLK->ICKCR 0x04) != 0x00);
- #endif
- /* Stop clock RTC and LCD */
- CLK_PeripheralClockConfig(CLK_Peripheral_RTC, DISABLE);
- CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, DISABLE);
- CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, DISABLE);
- }
- int main( void )
- {
- setup();
- while(true){
- Halt_Init();
- asm("nop");
- halt();
- }
- //return 0;
- }
在Halt_Init中,如果把TIM2/TIM3 DISABLE掉,TIMx_CNTL/TIMx_CNTH一直保持初始值,无法进入中断服务程序。从RM0031.pdf中看到的图也发现,fsysclk一直存在于所谓的外部时钟源模式2(ETR)。也就是说所谓外部时钟源模式,其内部时钟必须始终存在。
我现在有两个选择:
1. 把LSI 38KHz作为sysclk赋给TIM2/TIM3,但是我TIM4的sysclk必须是HSI,因为我需要1ms的系统定时中断;
2. 恢复EXTI中断服务。
就是不清楚那种功耗更低些。
STM32L外设与STM8L外设类似,也欢迎纠错和讨论。