ST意法半导体
直播中

李名扬

7年用户 630经验值
私信 关注
[问答]

请问为什么定时器启动时会立即发生TIM2中断?

181336

以上来自于谷歌翻译


以下为原文

181336

回帖(4)

张莉

2019-6-14 09:22:35
ST定时器的“更新事件”包括溢出,但也可以是其他内容(例如,当您'更新'ARR时,定时器寄存器初始化)。
这是关于计时器的方式。
关于你的代码,什么是ARR(自动重载寄存器)?似乎您使用默认值0x0000,在这种情况下,定时器将以更新开始(请记住,定时器在溢出时自动重载,溢出'更新'事件是定时器从ARR翻转为零的时间。计时器计为:0,1,2,3,4,5,6,0,1,2,...(ARR = 6)。溢出更新事件为0)。
我必须在这里说我没有使用ST hal库(或者它的名字)。为什么不直接使用寄存器?这是一个如此简单的芯片...... hal库只是隐藏了你的信息。最后,您可能无论如何都被迫阅读手册/数据表,并且您很难将hal库映射到手册。想一想:为什么在手册中所有的故事都是寄存器而不是hal库函数?我有一个经验法则:当手册/数据表将包括明确使用它以及硬件寄存器正常文档时,我将使用芯片供应商hal库....

以上来自于谷歌翻译


以下为原文




The ST timers 'update events' include overflow, but can be other things too (timer register initialization for example, when you 'update' the ARR as an example).
That's the way it is about st timers.
Regarding your code, what is the ARR (auto reload register)? Seems that you use the default, 0x0000, and in that case the timer will start with an update (Remember that the timers are auto-reload on overflow, the overflow 'update' event is when the timer roll-over to zero from ARR. The timer counts as that: 0,1,2,3,4,5,6,0,1,2,... (ARR=6). Overflow update event is at 0).
I must say here that I'm not using the ST hal library (or whatever it's name is). Why you don't work with registers directly? It's such a simple chip... The hal library is just hiding the information from you. In the end you may be forced to read the manual/datasheets anyway, and you will have a hard time mapping the hal library to the manual. Think of that: why in the manual all the stories are with registers and NOT the hal library functions? I have a rule of thumb: I will use a chip vendor hal library when the manual/datasheet will include clear use of it along with the hardware register normal documentation....
举报

赖治添

2019-6-14 09:29:38
我在Timer2中断时遇到了同样的问题。因此,我忽略了应用程序中的第一个中断,并清除TIM2_SR1以进行下一个中断。

以上来自于谷歌翻译


以下为原文




I  encountered the same problem with Timer2 interrupt. So I ignore the first interrupt in my application and clear the TIM2_SR1 for the next interrupt.
举报

李名扬

2019-6-14 09:47:32
嗨dragomir.raimond,谢谢你的回复。 ARR的值由TIM2_Deinit()设置为0xFFFF;然后将其更改为(大约值)0x0344
TIM2_TimeBaseInit()在它启动的计时器之前:
void TIM2_DeInit(void)
 
{
 TIM2-> CR1 =(uint8_t)TIM2_CR1_RESET_VALUE;
 TIM2-> IER =(uint8_t)TIM2_IER_RESET_VALUE;
...
 TIM2-> ARRH =(uint8_t)TIM2_ARRH_RESET_VALUE;
 
 TIM2-> ARRL =(uint8_t)TIM2_ARRL_RESET_VALUE;
...
}
 
 
void TIM2_TimeBaseInit(TIM2_Prescaler_TypeDef TIM2_Prescaler,
 
 uint16_t TIM2_Period)
 
{
 / *设置预分频器值* /
 TIM2-> PSCR =(uint8_t)(TIM2_Prescaler);
 / *设置自动重载值* /
 TIM2-> ARRH =(uint8_t)(TIM2_Period> 8);
 TIM2-> ARRL =(uint8_t)(TIM2_Period);
}
我已经尝试在TIM2_> SR1更新位(0x01)之前立即通过设置TIM2-> CR1的CEN位来激活定时器,因为我认为它应该阻止由于前面的设置引起的任何中断。它没有帮助 - 我仍然得到立即中断。
>为什么不直接使用寄存器?
这是一个外部客户的一次性项目,可能是我唯一一次使用STM8;我正在使用ST的HAL库来加速开发,因为我没有任何其他基于STM8的项目即将出现,并且不想花太多时间仔细研究寄存器定义,因为整个软件开发时间只有一周左右。
目前我刚刚在中断处理程序中使用静态bool来忽略它第一次运行,但我想要一个更好的方法。
再次感谢,
托德

以上来自于谷歌翻译


以下为原文




Hi dragomir.raimond, and thanks for the reply. The value of ARR set by to 0xFFFF by TIM2_Deinit(); it is then changed to (a value of approximately)  0x0344 by
TIM2_TimeBaseInit() before the timer it started:

void TIM2_DeInit(void)

{
  TIM2->CR1 = (uint8_t)TIM2_CR1_RESET_VALUE;
  TIM2->IER = (uint8_t)TIM2_IER_RESET_VALUE;
...

  TIM2->ARRH  = (uint8_t)TIM2_ARRH_RESET_VALUE;

  TIM2->ARRL  = (uint8_t)TIM2_ARRL_RESET_VALUE;
...

}



  
void TIM2_TimeBaseInit( TIM2_Prescaler_TypeDef TIM2_Prescaler,


                        uint16_t TIM2_Period)

{
  /* Set the Prescaler value */
  TIM2->PSCR = (uint8_t)(TIM2_Prescaler);
  /* Set the Autoreload value */
  TIM2->ARRH = (uint8_t)(TIM2_Period >> 8);
  TIM2->ARRL = (uint8_t)(TIM2_Period);
}
I have tried clearing the TIM2->SR1 update bit (0x01) immediately before TIM2_Cmd() activates the timer by setting TIM2->CR1's CEN bit as I figured that should block any interrupts due to the preceding setup. It doesn't help though -- I still get that immediate interrupt.

> Why you don't work with registers directly?
This is a one-off project for an external customer and may be the only time I use an STM8; I was using ST's HAL library to expedite the development as I don't have any other STM8-based projects coming up and didn't want to spend too much time poring over register definitions as the whole software development time was only around a week.
At the moment I've just used a static bool in the interrupt handler to ignore the first time it runs, but I wanted a better way.
Thanks again,
Todd
举报

张莉

2019-6-14 10:08:54
这总是一个不幸的情况,很难说什么是更好的事情
无论如何,可能你处于这种情况:第一个ARR计数在默认预分频器上,只是/ 1
这将非常接近您的测量(836计数* 0.0625ns = 52us)。预分频器将在'下一个'更新事件中获得您想要的值(16384),在您的情况下只是第一个。
从用户手册中引用:
'预分频器值通过预加载寄存器加载。影子寄存器,其中
 
包含当前写入的LS字节时加载的当前值。
新的预分频值将在下一个时期(下一个计数器之后)考虑在内
更新活动)。'

以上来自于谷歌翻译


以下为原文




That's always an unfortunate situation, and it's hard to say what is better to do
Anyway, probably you are in this situation: The first ARR counts are on the default prescaler which is just /1
That will be quite close to your measurement (836 counts * 0.0625ns = 52us). The prescaler will get your desired value (16384) at the 'next' update event, in your case just the first one.
Quote from the user manual:
'The prescaler value is loaded through a preload register. The shadow register, which

contains the current value to be used is loaded as soon as the LS Byte has been written.
The new prescaler value is taken into account in the following period (after the next counter
update event).'
举报

更多回帖

发帖
×
20
完善资料,
赚取积分