完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,我试着用PIC18F24K22的比较模块来实现速度测量。为了扩展测量范围,我考虑了time1的溢出,并将它们添加到测量结果中(见周期变量的计算):这种方法大部分时间工作良好,但是每分钟都发生CCPR2大于CCPR2i最后一次(Time1溢出不能HAV)。E发生)但Time1中断已触发(T1-溢出流计数为1)。在下一次测量中,缺少了Time1中断。看起来Time1中断太早了。下面我附上了一些调试输出示例:原因是什么?亲切的问候,沃尔夫冈
以上来自于百度翻译 以下为原文 Hi, I’m trying to implement speed measurement with the compare-module of a PIC 18F24K22. To extend the measurement range I’m taking into account the overflows of Timer1 and add them to the measurement result (see calcualtion of period variable): //Initialization: //Timer1 config - CCP2 capture TMR1CS1 = 0; //Internal clock (Fosc/4) TMR1CS0 = 0; T1CKPS1 = 1; //11 = 1:8 Prescale value T1CKPS0 = 1; TMR1GE = 0; //Timer1 counts regardless of Timer1 gate function TMR1ON = 1; //Enable Timer1 //CCP2 config - engine speed measurement CCP2M3 = 0; //0100 = Capture mode: every falling edge CCP2M2 = 1; CCP2M1 = 0; CCP2M0 = 0; C2TSEL1 = 0; //00 = CCP1 - Capture modes use Timer1 C2TSEL0 = 0; //interrupts IPEN = 0; //Disable priority levels on interrupts TMR1IE = 1; //Enables the TMR1 overflow interrupt CCP2IE = 1; //Enable CCP2 interrupt PEIE = 1; //Enables all unmasked peripheral interrupts GIE = 1; //Enables all unmasked interrupts //ISR: void interrupt myisr(void) { static unsigned int t1_overflow_count = 0; if (TMR1IE && TMR1IF) { //TMR1 overflow interrupt t1_overflow_count ++; TMR1IF = 0; //reset interrupt } if (CCP2IE && CCP2IF) { //CCP2 interrupt - rev counter unsigned int ccpr2 = 0; static unsigned int ccpr2_last = 0; unsigned long period = 0; #ifdef DEBUG debug_t1_overflow_count = t1_overflow_count; #endif ccpr2 = ((unsigned int) CCPR2H << 8) | CCPR2L; //read capture value if(ccpr2 < ccpr2_last) //if new value is smaller then old value t1_overflow_count--; //ignore (first) overflow period = (unsigned long)t1_overflow_count * 0xFFFF + (unsigned int)(ccpr2 - ccpr2_last); #ifdef DEBUG debug_period = period; debug_ccpr2h = CCPR2H; debug_ccpr2l = CCPR2L; debug_ccpr2 = ccpr2; debug_ccpr2_last = ccpr2_last; #endif ccpr2_last = ccpr2; calculate_and_set_x(period); //calculate engine speed and update process variable t1_overflow_count = 0; CCP2IF = 0; //reset interrupt } This approach works good most of the time, but every few minutes it happens that ccpr2 is bigger than ccpr2_last (Timer1 overflow can not have happened) but Timer1 interrupt has triggered (t1_overflow_count is 1). At the next measurment the Timer1 interrupt is missing. It looks like the Timer1 interrupt is triggerd too early. Below I have attached some debug output examples: ccpr2_last ccpr2 overlow_count period 30716 56360 0 25644 --> correct example --------------------------------------------------------------------------------------------------------------- 32359 65383 1 98559 --> Timer1 overflow too early 65383 30716 0 4294867094 --> missing Timer1 overflow --------------------------------------------------------------------------------------------------------------- 32296 65533 1 98772 --> Timer1 overflow too early 65533 30078 0 4294866306 --> missing Timer1 overflow --------------------------------------------------------------------------------------------------------------- 33159 65535 1 97911 --> Timer1 overflow too early 65535 30165 0 4294866391 --> missing Timer1 overflow What could be the reason? Kind regards, Wolfgang |
|
相关推荐
3个回答
|
|
如果T1接近0xFFFF且即将翻转,则捕获发生在捕获之后,但在ISR检查TMR1IF之前发生。所以你的ISR在翻转前的捕捉时计算翻转。只需做16位算术运算,16位结果将是正确的,不管RoLoVal.Ed-加上你的数学反正是错误的。周期= t1yOffFuffySt**0xFFFF+(CCPR2-ccPR2x最后);0xFFFF应为0x10000。
以上来自于百度翻译 以下为原文 Interrupt Latency. If capture occurs when T1 is close to 0xffff and about to rollover, the rollover happens after the capture but before the ISR checks TMR1IF. So your ISR counts a rollover when capture happened before rollover. Why bother checking for rollovers anyway? Just do 16bit arithmetic and the 16bit result will be correct regardless of rollovers. edit - Plus your math is wrong anyway. period = t1_overflow_count * 0xFFFF + (ccpr2 - ccpr2_last); 0xffff should be 0x10000. |
|
|
|
CCPR2i最后的最小值是当问题发生时是65275.2 ^ 16-6255=261 T1计数,直到RoLoVrt1预分频器=8261×8=2088指令周期2088指令周期中断延迟。那是真的吗?所以我可以测量超过2 ^ 16的持续时间,恐怕你是Reall:
以上来自于百度翻译 以下为原文 The smallest value of ccpr2_last I have seen when the problem has occured was 65275. 2^16-65275=261 T1 counts left until rollover T1 prescaler = 8 261 * 8 = 2088 instruction cycles 2088 instruction cycles interrupt latency? Can that be true? So I can measure durations which are longer than 2^16 counts I'm afraid that you are rightLoL: |
|
|
|
您的ISR在自由模式下编译的ISR具有接近50个周期的延迟,因为所有的上下文保存,但这与2000相差甚远。但是即使是一个小的延迟也会最终导致你看到的问题,所以你需要有一些机制来处理它。如果你没有显示的代码在一段时间内禁用中断,这可能会加剧这一点。或写入/擦除闪存(外围设备在代码执行冻结时继续)。
以上来自于百度翻译 以下为原文 Your ISR compiled with XC8 in free mode has close to 50 cycles latency due to all the context saving, but that is a far cry from 2000. But even a small latency will eventually cause the problem you are seeing, so you need to have some mechanism to handle it. If the code you haven't shown is disabling interrupts for a time, that could exacerbate this. Or writing/erasing Flash (as peripherals continue while code execution freezes) . |
|
|
|
只有小组成员才能发言,加入小组>>
5183 浏览 9 评论
2005 浏览 8 评论
1932 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3178 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2229 浏览 5 评论
739浏览 1评论
626浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
510浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
637浏览 0评论
535浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 19:36 , Processed in 1.490446 second(s), Total 81, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号