你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8L TIMx ETR并不能够实现完全的外部时钟计数

[复制链接]
allankliu 提问时间:2019-3-1 17:05 /
在工程中,原来利用GPIO外部中断实现脉冲计数,因为是低功耗设计,所以MCU平时都是Halt状态。觉得如果利用ETR的输入,配合TIM的计数溢出中断可以减少从低功耗模式中恢复的次数,以降低系统占空比。但是发现TIMx的设计必须依赖于内部sysclk的存在,如果halt模式下停止sysclk,则TIMx的CNTL/CNTH完全不更新。
  1. #include "stm8l15x.h"
  2. #include <stdbool.h>

  3. uint32_t ul2;
  4. uint32_t ul3;

  5. INTERRUPT_HANDLER(TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQHandler,19)
  6. {
  7.   if(TIM2_GetITStatus(TIM2_IT_Update) != RESET)
  8.   {
  9.     ul2++;
  10.     TIM2_ClearITPendingBit(TIM2_IT_Update);
  11.   }
  12. }

  13. INTERRUPT_HANDLER(TIM3_UPD_OVF_TRG_BRK_USART3_TX_IRQHandler,21)
  14. {
  15.   if(TIM3_GetITStatus(TIM3_IT_Update) != RESET)
  16.   {
  17.     ul3++;
  18.     TIM3_ClearITPendingBit(TIM3_IT_Update);
  19.   }
  20. }

  21. void setup( void )
  22. {
  23.   CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);

  24.   CLK->ICKCR |= 0x40;
  25.   // enable CCKO 38kHz
  26.   CLK->CCOR = CLK_CCOSource_LSI;
  27.   
  28.   GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Slow);
  29.   GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_In_PU_No_IT);
  30.   GPIO_Init(GPIOD, GPIO_Pin_1, GPIO_Mode_In_PU_No_IT);
  31.   
  32.   GPIO_Init(GPIOE, GPIO_Pin_2, GPIO_Mode_Out_PP_Low_Slow);
  33.   GPIO_Init(GPIOA, GPIO_Pin_4, GPIO_Mode_In_PU_No_IT);
  34.   GPIO_Init(GPIOA, GPIO_Pin_5, GPIO_Mode_In_PU_No_IT);
  35.   
  36.   SYSCFG->RMPCR3 |= SYSCFG_RMPCR3_CCO_REMAP;
  37.   SYSCFG->RMPCR2 |= SYSCFG_RMPCR2_TIM2TRIG_REMAP;
  38.   SYSCFG->RMPCR2 |= SYSCFG_RMPCR2_TIM3TRIG_REMAP1;

  39.   
  40.   // short cut PC4/PB3 or PC4/PD1 without changing SYSCFG_Remap.
  41.   // SYSCFG_RMPCR3, CCO_REMAP = 0:1 = PC4:PE2
  42.   // SYSCFG_RMPCR2, TIM2_TRG_REMAP = 0:1 = PB3:PA4
  43.   // SYSCFG_RMPCR2, TIM3_TRG_REMAP = 0:1 = PD1:PA5

  44.   TIM2_DeInit();
  45.   CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
  46.   
  47.   //TIM2_ETRClockMode2Config(TIM2_ExtTRGPSC_DIV2, TIM2_ExtTRGPolarity_NonInverted,0x00);
  48.   TIM2_ETRClockMode2Config(TIM2_ExtTRGPSC_OFF, TIM2_ExtTRGPolarity_Inverted,0x00);
  49.   //TIM2_TimeBaseInit(TIM2_Prescaler_1,TIM2_CounterMode_Up,9999);
  50.   TIM2_TimeBaseInit(TIM2_Prescaler_1,TIM2_CounterMode_Up,100);
  51.   TIM2_ITConfig(TIM2_IT_Update,ENABLE);
  52.   TIM2_SetCounter(0x0);
  53.   TIM2_ClearITPendingBit(TIM2_IT_Update);
  54.   TIM2_Cmd(ENABLE);

  55.   TIM3_DeInit();
  56.   CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);
  57.   
  58.   //TIM3_ETRClockMode2Config(TIM3_ExtTRGPSC_DIV2, TIM3_ExtTRGPolarity_NonInverted,0x00);
  59.   TIM3_ETRClockMode2Config(TIM3_ExtTRGPSC_OFF, TIM3_ExtTRGPolarity_Inverted,0x00);
  60.   //TIM3_TimeBaseInit(TIM3_Prescaler_1,TIM3_CounterMode_Up,9999);
  61.   TIM3_TimeBaseInit(TIM3_Prescaler_1,TIM3_CounterMode_Up,100);
  62.   TIM3_ITConfig(TIM3_IT_Update,ENABLE);
  63.   TIM3_SetCounter(0x0);
  64.   TIM3_ClearITPendingBit(TIM3_IT_Update);
  65.   TIM3_Cmd(ENABLE);

  66.   enableInterrupts();
  67. }

  68. void Halt_Init(void)
  69. {

  70. /* Set STM8 in low power */
  71.   PWR->CSR2 = 0x2;
  72.   
  73. /* Stop RTC Source clock */
  74.   CLK_RTCClockConfig(CLK_RTCCLKSource_Off, CLK_RTCCLKDiv_1);
  75.   
  76.   #ifdef USE_LSE
  77.     CLK_LSEConfig(CLK_LSE_OFF);
  78.     while ((CLK->ECKCR & 0x04) != 0x00);
  79.   #else
  80.     CLK_LSICmd(DISABLE);
  81.     while ((CLK->ICKCR & 0x04) != 0x00);
  82.   #endif
  83.   
  84.   /* Stop clock RTC and LCD */        
  85.   CLK_PeripheralClockConfig(CLK_Peripheral_RTC, DISABLE);
  86.   CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, DISABLE);
  87.   CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, DISABLE);
  88.   
  89. }

  90. int main( void )
  91. {
  92.   setup();
  93.   while(true){
  94.     Halt_Init();
  95.     asm("nop");
  96.     halt();
  97.   }
  98.   //return 0;
  99. }
复制代码
在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外设类似,也欢迎纠错和讨论。

收藏 评论2 发布时间:2019-3-1 17:05

举报

2个回答
allankliu 回答时间:2019-3-1 17:09:50
如果有其他的模式,请指教一二。
butterflyspring 回答时间:2019-3-20 10:46:44
STM8L的外设工作需要系统时钟支持,而低功耗模式下(HALT),系统时钟停止,降低功耗。相应的定时器TIMX也没有了时钟,所以整个外设就不能工作了。 而部分STM32L系列产品是有低功耗定时器的外设,可以在STOP模式下利用低速时钟工作。所以可以根据你的需求平衡一下功耗或者选择

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版