完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我在time2预分卡上遇到了麻烦。我使用中断程序来打开和关闭一个LED。LED在等待中断时打开,当检测到中断时关闭1秒。这部分工作良好,但是LED的停留时间不会改变,当我改变预分频位。后标位完美地工作。我的代码在下面供参考。非常感谢您的帮助。include
以上来自于百度翻译 以下为原文 I am having trouble with the Timer2 Prescale. I use the interrupt routine to turn on and off an LED. The LED is on while it is waiting for the interrupt and turns off for 1 sec when an interrupt is detected. This part works well, however the time the LED stays on does not change when I change the Prescale bits. The Postscale bits work perfectly. My code is below for reference. Any help would be greatly appreciated. #include #include #include #include #include //Configuration setting /* INTOSC oscillator: I/O function on CLKIN pin Watchdog Timer disabled Power-up Timer disabled MCLR/VPP pin function is digital input Data memory code protection is disabled CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin Fail-Safe Clock Monitor is disabled 4x PLL diabled Write protection off */ __CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & WRT_OFF & LVP_OFF); //Definitions #define SENSOR LATAbits.LATA1 //Method Declarations void initialize(void); void initializeT2(void); void delay(unsigned short int delay); //Main Loop void main (void) { initialize(); SENSOR = 1; while(1) { } } void interrupt isr(void) { if(TMR2IE && TMR2IF) { SENSOR = 0; TMR2IF =0; delay(1000); SENSOR = 1; initializeT2(); } } void initialize(void) { OSCCON = 0b00010010; // 250 kHz //Port A Registers TRISA = 0b00000001; ANSELA = 0b00000001; //Timer2 TMR2 = 0b00000000; PR2 = 0b11111111; PIR1bits.TMR2IF = 0; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; PIE1bits.TMR2IE = 1; T2CON = 0b01011100; //T2CON = 0b01011111; } void initializeT2(void) { TMR2 = 0b00000000; PR2 = 0b11111111; PIR1bits.TMR2IF = 0; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; PIE1bits.TMR2IE = 1; T2CON = 0b01011100; //T2CON = 0b01011111; } void delay(unsigned short int delay) { unsigned short int i, j; for(i = 0; i < delay; i++) { for(j = 0; j < 2; j++); } } |
|
相关推荐
7个回答
|
|
如果不看别的东西,就不要在ISR中延迟或阻塞呼叫。这样就停止了其他代码的运行。相反,ISR应该执行得非常快,如果需要额外的工作,则将其设置为在主循环中测试的标志。此外,从ISR调用函数常常不是一个好主意。编译器将保存ISR中使用的所有寄存器,并在最后恢复它们,但是如果您调用一个函数,那么(通常)编译器将不得不保存和恢复所有内容,因为它不知道函数将发生什么变化。这只会减慢ISR的执行速度,不要在ISR内部玩PIE和GIE位。ISR会自己调整这些位。据我所知,您在“初始化”和“初始化T2”函数中初始化Timer2的代码是一样的。也不要包括您从未使用过的文件——在本例中是字符串、stdio和stdlib;后面两个(至少)几乎从不需要R嵌入式程序设计。我不知道HTC包含,但是您应该检查它没有包含处理器特定的头文件。按照您的方式编写延迟函数时要小心——对于编译器来说,将整个优化到单个“否”太容易了。FIFFR有点在OSCCON,但它是只读的——浪费时间。如果要设置IrCF位,则只需设置那些。(实际上,对于这些设备来说,没有太大区别,但是最好主动地只设置那些您想要设置的位。现在来看看您的问题(或者我认为是问题)。你使用的是250kHz的CulkC,这意味着我们看到了一个62500赫兹的定时器。然后,你有一个1:12预卡拉和255 PR2值,这意味着中断有20.5Hz频率或每49毫秒发生。即使你曲柄达到1:16预卡拉值,中断仍然是65毫秒分开。在另一个极端,在1:1预标度的情况下,中断间隔为4mSec。除非在输出上使用作用域,否则您将无法(通过眼睛)看到差异。还有“关闭”时间(你说是1秒,我必须相信你的话,0没有办法计算“延迟”函数将如何工作)将比准时至少大2个数量级。
以上来自于百度翻译 以下为原文 Without looking at anything else, NEVER put a delay or blocking call into an ISR. This stops any other code from functioning. Instead an ISR should execute very quickly and if additional work is required then set as flag that is tested in the main loop. Further, it is often not a good idea to call functions from a ISR. The compiler will save all registers that are used in the ISR and restore them at the end, but if you call a function then (generally) the compiler will have to save and restore everything as it has no idea what the function will be changing. This just slows down the execution of the ISR. Don't play with the PEIE and GIE bits inside an ISR. The ISR will be adjusting those bits itself. As far as I can see your code for initialising Timer2 in the 'Initialze' and 'InitializeT2' functions is the same. Also don't include files that you never use - in this case the string, stdio and stdlib; the latter two (at least) are almost never needed for embedded programming. I don't know about the HTC include, but you should check that it is not already including the processor specific header file. Be careful with writing a delay function the way you have - it is all too easy for the compiler to optimise the whole thing away to a single 'nop'. You are trying to set the LFIOFR bit in OSCCON but it is read only - a waste of time. If you want to set the IRCF bits then just set those. (Actually for these devices is does not make a great deal of difference but it is good proactive to only set those bits that you mean to. Now to your problem (or what I think is the problem). You are using a 250kHz clokc which means the timer us seeing a 62500Hz source. You then have a 1:12 prescalar and a 255 Pr2 value which means the interrupts have a 20.5Hz frequency or occur every 49mSec. Even if you crank that up to a 1:16 prescalar value, the interrupts will still be 65mSec apart. At the other extreme with a 1:1 prescalar you have the interrupts at 4mSec apart. Unless you are using a scope on the output, you would never see (by eye) the difference. Also the 'off' time (which you say is 1sec and I'll have to take your word for that 0 there is no way to calculate how that 'delay' function will work) will be at least 2 orders of magnitude greater than the on time. Susan |
|
|
|
我相信无符号短int实际上是一个16位的整数(无符号int),所以它可以接受0到65535。
以上来自于百度翻译 以下为原文 I believe an unsigned short int is actually a 16 bit integer (unsigned int) so it will accept 0 to 65535. Edit: for XC8 this is in section 5.4.2 Integer Data Types in the user guide. |
|
|
|
我改正了。但是中断问题依然存在。
以上来自于百度翻译 以下为原文 I stand corrected. But the interrupt problems remain. TABLE 5-1: INTEGER DATA TYPES Type Size (bits) Arithmetic Type bit 1 Unsigned integer signed char 8 Signed integer unsigned char 8 Unsigned integer signed short 16 Signed integer unsigned short 16 Unsigned integer signed int 16 Signed integer unsigned int 16 Unsigned integer signed short long 24 Signed integer unsigned short long 24 Unsigned integer signed long 32 Signed integer unsigned long 32 Unsigned integer signed long long 32 Signed integer unsigned long long 32 Unsigned integer |
|
|
|
我同意这不是一个好的实现,但是应该没有堆栈溢出,因为中断在ISR退出之前不会被重新启用。定时器2中断标志(TM2IF)可以在延迟期间设置,但是对ISR的调用直到ISR退出才会发生。这可能导致立即重新进入ISR函数,而没有执行主循环指令,因此看起来图片已经“挂”在这个代码上,但是“堆栈”应该被正确处理。阻塞ISR函数内部的延迟从来都不是一个好方法,并且可以导致许多有趣的结果(虽然通常不是期望的结果)。
以上来自于百度翻译 以下为原文 I agree this is not a good implementation however there should be no stack overflow as the interrupts would not be re-enabled until the ISR exits. The Timer 2 interrupt flag (TM2IF) could be set during the delay however the call to the ISR will not occur until adter the ISR exits. This may result in immediate reentry into the ISR function with no main loop instructions executing thus looking like the pic has "hung" on this code however the "stack" should be handled correctly. Blocking delays inside of an ISR function are never a good approach and can result in a lot of interesting results (not usually what is desired though). |
|
|
|
initializeT2()函数是从ISR内部调用的,并且正在设置GIE,但是它更早地清除了TMR2IF两个指令,所以这是非常糟糕的实践,但是您可能已经摆脱了它。
以上来自于百度翻译 以下为原文 The initializeT2() function is called from inside the ISR, and is setting GIE, but it clears TMR2IF two instructions earlier, so it is very bad practice, but you MIGHT get away with it. |
|
|
|
我错过了,谢谢。这也是一个非常糟糕的想法。除非在非常奇怪的情况下,中断不应该在ISR内部重新启用(这绝对不是其中的一个!).
以上来自于百度翻译 以下为原文 I missed that, thanks. That is also a VERY BAD idea. Interrupts should not be re-enabled inside an ISR except under VERY odd circumstances (and this is definitely NOT one of those!). |
|
|
|
我错过了ISR中的initializeT2()函数。由于PR2预设为0xff,在设置TMR2IE后不久,T2CON将定时器打开(位2),PR2将溢出并导致中断。目前还不清楚OP想要实现什么,首先要解决的是代码的正确性。我假设目的是简单地在中断发生时闪动LED,而不是非常不寻常的东西。一旦代码被修复,如果它仍然是一个问题,那么预分频器的问题就可以解决。中断代码应该在主循环中,ISR应该简单地设置一个标志,发出检测到中断的信号,然后LED可以闪烁。TMR2IF标志可以在主回路中复位,在LED闪烁之后。如果目的是提供TIMER2中断的视觉指示,ISR可以简单地在每个中断上颠倒LED的状态。
以上来自于百度翻译 以下为原文 I had missed the initializeT2() function in the ISR. void initializeT2(void) { TMR2 = 0b00000000; PR2 = 0b11111111; PIR1bits.TMR2IF = 0; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; PIE1bits.TMR2IE = 1; T2CON = 0b01011100; //T2CON = 0b01011111; } Since PR2 is preset to 0xff, shortly after TMR2IE is set, and T2CON turns the timer ON (bit 2), PR2 will overflow and cause an interrupt. It is unclear what the OP wants to accomplish with this, and first priority is to fix the code so that it makes sense. I am assuming that the purpose is simply to flash the LED when the interrupt occurs, and not something highly unusual. Once the code is fixed, the problem with the prescaler can be addressed, if it is still an issue. The interrupt code should be in the main loop, and the ISR should simply set a flag that signals an interrupt detected and then the LED could flash. The TMR2IF flag could be reset in the main loop, after the LED has flashed. If the purpose is to provide visual indication of the TIMER2 interrupts, the ISR could simply invert the state of the LED on each interrupt. SENSOR = ~SENSOR |
|
|
|
只有小组成员才能发言,加入小组>>
5189 浏览 9 评论
2009 浏览 8 评论
1933 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3181 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2232 浏览 5 评论
746浏览 1评论
632浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
517浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
644浏览 0评论
544浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-30 23:52 , Processed in 1.297036 second(s), Total 59, Slave 52 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号