完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
当使用tiM1测量信号的频率时,我发现了一些非常有趣/奇怪的东西:
将TIM2和TIM1设置为使用相同的预分频器(例如8)。 TIM2配置为生成周期为10000的PWM,在这种情况下产生2Mhz /(8 * 10000)= 25Hz信号。 然后,TIM1配置为输入CapCom模式,其触发控制器在输入通道1的每个上升沿复位定时器。 现在将引脚TIM2_Chan1与TIM1_Chan1连接。理论上,在TIM1的CapCompareReg1中获得的值应该完全等于TIM2的周期。 在这个例子中,CCR1包含8880而不是9999.当为TIM1采用较小的预分频器时,这些值的偏差更加严重。 : TIM1_DeInit(); / *将TIM1频率设置为1 Mhz(= 2Mhz / 2),因此1个单位= 1us * / TIM1_TimeBaseInit(8,TIM1_COUNTERMODE_UP,60000,0); //溢出前最多60000步 / * TIM1通道1用于(PC1)上升沿,没有分频器(1)和滤波器(0)* / TIM1_ICInit(TIM1_CHANNEL_1,TIM1_ICPOLARITY_RISING,TIM1_ICSELECTION_DIRECTTI,TIM1_ICPSC_DIV1,0x00); / *用于同步计数器的触发输入(TRGI)* / TIM1_SelectInputTrigger(TIM1_TS_TI1FP1); / *复位模式 - 所选触发信号的上升沿(本例中为TI1FP1)重新初始化计数器和 生成寄存器的更新。 * / TIM1_SelectSlaveMode(TIM1_SLAVEMODE_RESET); / *溢出中断;启用Capture1中断* / TIM1_ITConfig(TIM1_IT_UPDATE | TIM1_IT_CC1,ENABLE); / *生成更新事件* / TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE); / *清除CC1并更新标志* / TIM1_ClearFlag(TIM1_FLAG_CC1 | TIM1_FLAG_UPDATE); //更新URS位van TIM_CR1,只有上溢/下溢才会产生中断。 TIM1_UpdateRequestConfig(TIM1_UPDATESOURCE_REGULAR); / *启用TIM1 * / TIM1_Cmd(ENABLE); TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE); // --------------------------- TIM2_TimeBaseInit(TIM2_PRESCALER_8,9999); / * PWM1模式配置:Channel1 * / TIM2_OC1Init(TIM2_OCMODE_PWM1,TIM2_OUTPUTSTATE_ENABLE,4000,TIM2_OCPOLARITY_HIGH); TIM2_OC1PreloadConfig(ENABLE); TIM2_ARRPreloadConfig(ENABLE); / * TIM2启用计数器* / TIM2_Cmd(ENABLE); // --------------------------- / *启用常规中断* / enableInterrupts(); void TIM1_CAP_COM_IRQHandler(void)中断12 { measuredTime =(TIM1_GetCapture1()); TIM1_ClearFlag(TIM1_FLAG_CC1); //清除捕获比较标志 } 因此,计时器必须在某处丢失“计数”。具有讽刺意味的是,使用EXTI中断完成整个操作并在软件中启动/停止计数器更为准确。 我很想相信我的代码是错误的,但是我明白了while定时器同步实现可能是一个废话。 #破碎定时器STM8S 以上来自于谷歌翻译 以下为原文 I found something very funny/weird when using TIM1 to measure the frequency of a signal: Set TIM2 and TIM1 to use the same prescaler (e.g. 8). TIM2 is configured to generate PWM with period 10000, in this case resulting in 2Mhz/(8*10000)=25Hz signal. Then, TIM1 is configured in Input CapCom mode, and its trigger controller resets the timer on every rising edge on input channel1. Now connect pins TIM2_Chan1 with TIM1_Chan1. In theory, the values obtained in CapCompareReg1 of TIM1 should equal the period of TIM2 perfectly. In this example, the CCR1 contains 8880 instead of 9999. The values deviate even more worse when taking smaller prescalers for TIM1. : TIM1_DeInit(); /* Set TIM1 Frequency to 1 Mhz (=2Mhz/2), thus 1 unit = 1us */ TIM1_TimeBaseInit(8, TIM1_COUNTERMODE_UP, 60000, 0);//Max 60000 steps before overflow /* TIM1 channel 1 is used (PC1) with rising edge and no divider (1) nor filter (0) */ TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x00); /* the trigger input (TRGI) to used to synchronize the counter */ TIM1_SelectInputTrigger(TIM1_TS_TI1FP1); /* Reset mode - Rising edge of the selected trigger signal (TI1FP1 in this case) re-initializes the counter and generates an update of the registers. */ TIM1_SelectSlaveMode(TIM1_SLAVEMODE_RESET); /* Overflow interrupt ; Capture1 interrupt enabled */ TIM1_ITConfig(TIM1_IT_UPDATE | TIM1_IT_CC1, ENABLE); /* Generate an update event */ TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE); /* Clear CC1 and update Flag */ TIM1_ClearFlag(TIM1_FLAG_CC1 | TIM1_FLAG_UPDATE); //Update URS bit van TIM_CR1 so only over/underflow generates interrupt. TIM1_UpdateRequestConfig(TIM1_UPDATESOURCE_REGULAR); /* Enable TIM1 */ TIM1_Cmd(ENABLE); TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE); //--------------------------- TIM2_TimeBaseInit(TIM2_PRESCALER_8, 9999); /* PWM1 Mode configuration: Channel1 */ TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 4000, TIM2_OCPOLARITY_HIGH); TIM2_OC1PreloadConfig(ENABLE); TIM2_ARRPreloadConfig(ENABLE); /* TIM2 enable counter */ TIM2_Cmd(ENABLE); //--------------------------- /* Enable general interrupts */ enableInterrupts(); void TIM1_CAP_COM_IRQHandler(void) interrupt 12 { measuredTime = (TIM1_GetCapture1()); TIM1_ClearFlag(TIM1_FLAG_CC1);//Clear capture-compare flag } So, the timer must lose ''counts'' somewhere. Ironically, it is more accurate to do the whole thing with EXTI interrupts and start/stop the counter in software. I would love to believe that my code is wrong, but it dawns on me that the while timer synchronisation implementation could be a piece of crap. #broken-timer-stm8s |
|
相关推荐
4个回答
|
|
你好克拉斯。
第17.4.5节“RM0016参考手册”的STM8S微控制器系列的“触发同步”解释了为什么您的代码无法正常工作。 您的代码使TIM1工作在“触发器重置模式”,因此图47所示的内容也适用于您的示例。 即使图47不正确,因为TIM1_CNTR在触发沿之前被清除,它会在触发沿和更新事件之间显示延迟。 TI1输入上的重新同步电路会增加此延迟,这取决于预分频器和计数器值。 我不知道为什么STM8设计师添加了这个功能。 我认为TIM1可能是一个功能强大的计时器,但它是一个相当复杂的计时器,因为有很多方法可以完成任务但只有一个真正有效。 问候 EtaPhi 以上来自于谷歌翻译 以下为原文 Hello Klaas. Section 17.4.5 ''Trigger synchronization'' of RM0016 Reference Manual of STM8S microcontroller family explains why your code doesn't work as you think. Your code makes TIM1 work in ''trigger reset mode'', so what Figure 47 shows applies to your example too. Even if Figure 47 isn't correct, because TIM1_CNTR is cleared before the trigger edge, it shows a delay between the trigger edge and the update event. The resynchronization circuit on TI1 input adds this delay which depends on prescaler and counter values. I don't know why STM8 designers added this feature. I think that TIM1 may be a powerful timer but it's a rather complex timer to use because there are many ways to accomplish a task but only one really works. Regards EtaPhi |
|
|
|
嗨EtaPhi,
感谢您的回复!你对延迟是正确的,我一定错过了这一部分。 但我希望延迟只会'移位'复位时间,因此不会改变计数器本身的值。 如果它确实改变它,那么计数器中的值变得太高是有意义的,但在示例情况下,时间值结束得太低(8880而不是10000)。 另外,在我的例子中,定时器以250kHz运行,但神奇地失去了4.4ms的计数(误差为12%)。这有点极端,但可能会变得更糟:以1Mhz运行定时器,差值为3.3 ms,或计数器值的误差约为30%。 我会尝试其他一些方法来尝试测量频率,但对使用这个uC失去信心。就像你说的那样,可能用Timer1做到这一点,但它太复杂了,而且文档并没有多大帮助。 以上来自于谷歌翻译 以下为原文 Hi EtaPhi, Thanks for your reply! You are right about the delay, I must have missed that part. But I would expect that the delay only 'shifts' the time of reset, and therefore does not alter the value of the counter itself. And if it does alter it, it would make sense that the value in the counter becomes too high but in the example case the time value ends up too low (8880 instead of 10000). Also, in my example, the timer is running at 250kHz, but magically loses 4.4ms worth of counts (error of 12%). That is kind of extreme, but can get worse: running the timer at 1Mhz, the difference is 3.3 ms, or an error of about 30% on the counter value. I will try some other things to try to measure frequencies but losing confidence in using this uC. Like you say, it might be possible to do it with Timer1, but it's just too complex and the documentation does not really help much. |
|
|
|
克拉斯,
STM8 TIM1与STM32设备中的定时器相同。 因此,您对STM32微控制器也失去了信心...... 我不喜欢这个复杂的计时器,因为我已经熟悉了ST7Lite Auto Reload Timer,它更简单,更好地记录,尽管它不如TIM1灵活。 ST的一些优秀文档会有所帮助,而且非常需要,但我不想错过从ST轻松无痛地过渡到ARM微控制器的机会。 再见 EtaPhi 以上来自于谷歌翻译 以下为原文 Klass, STM8 TIM1 is the same timer that you can find in a STM32 device. You are therefore losing confidence in STM32 microcontrollers too... I don't like this complex timer, because I've been acquainted with ST7Lite Auto Reload Timer which is simpler and better documented, albeit it's less flexible than TIM1. Some great documentation from ST would help and it's strongly needed, but I don't want to miss the opportunity of an easy and painless transition to ARM microcontroller from ST. Ciao EtaPhi |
|
|
|
我发现了问题。当然是非常愚蠢的错误......:
/ *将TIM1频率设置为250kHz(= 2Mhz / 8)* / TIM1_TimeBaseInit(8,TIM1_COUNTERMODE_UP,60000,0); //溢出前最多60000步 Prescaler是一个一个!应该是7除以8。 知道这一点,一切都按预期工作,现在测量非常准确。 以上来自于谷歌翻译 以下为原文 I found the problem. Very stupid mistake of course...: /* Set TIM1 Frequency to 250kHz (=2Mhz/8) */ TIM1_TimeBaseInit(8, TIM1_COUNTERMODE_UP, 60000, 0);//Max 60000 steps before overflow The Prescaler is off-by-one! It should be 7 to divide by 8. Knowing this, everything works as it should and measurements are quite accurate now. |
|
|
|
只有小组成员才能发言,加入小组>>
请教:在使用UDE STK时,单片机使用SPC560D30L1,在配置文件怎么设置或选择?里面只有SPC560D40的选项
2725 浏览 1 评论
3237 浏览 1 评论
请问是否有通过UART连接的两个微处理器之间实现双向值交换的方法?
1807 浏览 1 评论
3646 浏览 6 评论
6034 浏览 21 评论
1337浏览 4评论
197浏览 3评论
对H747I-DISCO写程序时将CN2的st-link复用为usart1,再次烧录时无法检测到stlink怎么解决?
350浏览 2评论
STM32G474RE芯片只是串口发个数据就发烫严重是怎么回事?
442浏览 2评论
STM32处理增量式编码器Z信号如何判断中断是正转的还是反向转的?
273浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:55 , Processed in 1.287265 second(s), Total 85, Slave 68 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号