完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
我使用PIC16F86与2x40字符LCD控制器,HD44 780U接口。我使用计时器2定时器连同周期寄存器PR2每秒产生一个中断/标志。如果我检查了标志TMR2IF(当计时器2与周期寄存器匹配时),我的代码工作得很好,毫秒变量也会增加,所有都是好的。如果我把轮询函数变成一个中断函数,并且检查标记TMR2,如果我的PIC不断重置,我会得到很多奇怪的G。全方位显示LCD显示字符。我认为每秒可能有1000次中断太多,所以我把它减慢到500,然后是100,然后是50,在50,它看起来更正常。但阅读我觉得它不应该有一个问题在1000。也许我错了?下面是中断代码:
以上来自于百度翻译 以下为原文 I'm using a PIC16F886 to interface with a 2x40 character LCD controller, the HD44780U. I'm using the timer 2 timer along with its period register PR2 to generate an interrupt/flag every millisecond. If I poll for the flag TMR2IF (set when timer 2 matches the period register) my code works fine and my millisecond variable increments as it should and all is good. If I change my polling function to an interrupt function, and check for flag TMR2IF my PIC resets constantly and I get a lot of weird garbage characters all over the LCD display. I thought that maybe 1000 interrupts per second was too much, so I slowed it down to 500, then 100 then 50 and at 50 it seemed to behave more normally. But reading around I feel like it shouldn't have an issue at 1000. Maybe I'm wrong? Here's the interrupt code: void interrupt intFunc(){ //Timer2 Interrupt (TMR2IE) //TMR2 and PR2 match flag if(TMR2IF){ if(t2time == 4294967295){ //Reset the device RESET(); } else { t2time++; TMR2IF = 0; } } } |
|
相关推荐
17个回答
|
|
|
为什么要在代码中重新设置PIC?你为什么要这么做?T2TIME变量是否在ISR之外改变?如果是这样,它被宣布为波动性的吗?应该是这样。
以上来自于百度翻译 以下为原文 Why are you reseting the pic in your code? Why are you expecting it to do? Is the t2time variable changed outside the ISR? If so is it declared volatile? It should be. |
|
|
|
|
|
T2TIME是一个未声明的long,它是全局声明的。它在中断中增加每毫秒,所以它应该在溢出之前花50天。如果它达到了这个点,我需要PIC来重置,因为如果它溢出,它将打破依赖于它的程序的其他部分。程序中没有其他地方修改过。我会读波动,看看它的意思,谢谢。
以上来自于百度翻译 以下为原文 t2time is an unsigned long I declared globally. It increments every millisecond in the interrupt so it should take like 50 days before it overflows. And if it does reach that point I need the PIC to reset because if it overflows it will break other parts of the program that depend on it. It's not modified anywhere else in the program. I will read up on volatile to see what it means, thanks. |
|
|
|
|
|
不是重置PIC,为什么不重置var呢?还是让它溢出到0(零)?你在哪里初始化这个值?怎么办?啊,但是你并没有完全理解你读到的关于挥发性限定词的内容。如果在中断中改变VAR,并且在中断外读取,那么这些访问可能被中断,因此VAR的值可能被破坏。易失性将告诉编译器,它不能假定值没有改变,必须刷新值(不使用从临时位置等)。也就是Time2中断启用(IE位)总是设置(启用),没有其他中断启用?如果不是,你还需要在ISR测试(TMR2IE和TMR2IF)中检查它,以便正确地确定中断是否来自Time2。
以上来自于百度翻译 以下为原文 Instead of reseting the pic why not just reset the var? Or let it overflow back to 0 (zero)? Where do you initialise this value? What to? Ah but you did not fully understand what you read about the volatile qualifier. If the var is changed in the interrupt and you read it outside the interrupt then those accesses could be interrupted and thus the value of the var can be corrupted. Volatile will tell the compiler it must not assume the value has not changed and must refresh the value (not use it from a temporary location, etc). Also is the timer2 interrupt enable (IE bit) always set( enabled) and no other interrupts are enabled? If not then you also need to check for it in your ISR test (TMR2IE & TMR2IF) to properly determine if the the interrupt was from the timer2. Also might be a good idea to put the postqualifier UL after the number (4294967295UL). |
|
|
|
|
|
PIC没有重置指令,所以我不确定RESET()是否是期望的行为。
以上来自于百度翻译 以下为原文 That PIC doesn't have a reset instruction, so I'm not sure whatever RESET() does is the desired behavior. |
|
|
|
|
|
正如Jtemples所说,PIC没有重置指令,如果在RESET()中没有清除TMR2。此外,代替429 4967,5包含和lt;限制。h & gt;并使用uluulax MAX。
以上来自于百度翻译 以下为原文 As Jtemples said, that PIC does not have a RESET instruction, and you did not clear TMR2IF when RESET(). Also, instead of 4294967295, #include |
|
|
|
|
|
我可以猜出数学中的问题,用来确定两次之间的差异。这将是一个独立的问题。
以上来自于百度翻译 以下为原文 I can guess the issue in the math used to determine the difference between two times. That would be fixable as a seperate issue. |
|
|
|
|
|
我刚刚检查过了。ReSET()用于该PIC设备编译ToHiHIC是一个无限循环。
以上来自于百度翻译 以下为原文 I just checked it. RESET() for that PIC device compiles to LGOTO $which is an infinite loop. |
|
|
|
|
|
我在文件中找不到任何重置,但这里是头文件中的内容:所以我猜目的是通过WDT获得重置。我也找不到任何关于PyP14Ex的提及。
以上来自于百度翻译 以下为原文 I couldn't find any mention of RESET in the documentation, but here's what's in the header file:#if defined(_PIC14E) || defined(_PIC14EX) || defined(_PIC18) #define RESET() asm("reset") #else #define RESET() asm("ljmp $") #endifSo I guess the intent was to get a reset via the WDT. And I couldn't find any mention of _PIC14EX, either. |
|
|
|
|
|
我仍然没有看到测试T2时间对最大值的目的。为什么?
以上来自于百度翻译 以下为原文 I still do not see the purpose in testing t2time against the max value. Why? |
|
|
|
|
|
不仅仅是关于值的改变,16F编译器是否生成了对long声明为常量的原子访问?是否在读取值时禁用中断?如果是这样,我会很惊讶,并且很不高兴编译器在我的控制之外中断。
以上来自于百度翻译 以下为原文 Not just about changing value, Does the 16F compiler generate atomic accesses for longs declared volatile? I.e does it disable interrupts whilst reading the value? I would be very surprised if it does, and very upset that the compiler is dicking with the interrupts outside my control. |
|
|
|
|
|
这取决于你的PIC跑得多快,你没有告诉我们。假设你在全速使用8 MHz的内部振荡器,你每毫秒有2000个指令周期,所以你的简单中断不会引起任何问题。
以上来自于百度翻译 以下为原文 That depends on how fast your PIC is running, which you haven't told us. Assuming you're using the 8 MHz internal oscillator at full speed, you have 2000 instruction cycles per ms, so your simple interrupt won't cause any issues. |
|
|
|
|
|
这很好知道,谢谢。这是正确的。为了更新我的显示,我将T2TIME当前值与先前记录的值进行比较,如果它大于或等于我的刷新间隔,则显示更新。如果T2时间环绕0,那么LCD将停止更新(因为当前时间减去上次保存的时间现在等于一个大的负值),这就是为什么我只想重置设备。这取决于您的PIC正在运行的速度,这是您没有告诉我们的。假设你使用全速8 MHz的内部振荡器,你每毫秒有2000个指令周期,所以你的简单中断不会引起任何问题。YEP,我运行在8MHz从内部振荡器。在宣布T2TIME是不稳定的,它似乎改善事情。作为一个简单的测试,我向LCD输出一个计数器,从0增加到9,然后回到0。在它计数过快的时候,增加或冻结额外的字符,但是它现在稳定了,但是它仍然是奇怪的。如果我让计数器通过9,它将从0计数到10,然后PIC重置每一次。
以上来自于百度翻译 以下为原文 This is good to know, thanks. That is correct. To update my display, I compare the current value of t2time to a previously recorded value and if its greater or equal to my refresh interval the display updates. If t2time wraps around to 0 then the LCD will stop updating (since current time minus the last saved time now equals a large negative value) which is why I just wanted to reset the device. That depends on how fast your PIC is running, which you haven't told us. Assuming you're using the 8 MHz internal oscillator at full speed, you have 2000 instruction cycles per ms, so your simple interrupt won't cause any issues. Yep I'm running at 8Mhz from the internal oscillator. After declaring t2time as volatile, it seemed to improve things. As a simple test I output a counter to the LCD that incremented from 0 to 9 then goes back to 0. Before it was counting too fast at times, getting extra characters added or freezing but its stable now. But its still being weird. If I let the counter go past 9, it will count from 0 to 10 then the PIC resets every single time. uint32_t volatile t2time = 0; int count = 0; void interrupt intFunc(){ //Timer2 Interrupt (TMR2IE) //TMR2 and PR2 match flag if(TMR2IF && TMR2IE){ t2time++; TMR2IF = 0; } } void updateDisplay() { setDdramAddress(0x40); lcdPrintInt(count++); } uint32_t millis(){ return t2time; } void lcdPrintInt(uint32_t data) { uchar buff[11]; sprintf(buff, "%lu", data); lcdPrint(buff); } |
|
|
|
|
|
如果从当前值中减去以前的时间,使用未签名的算术,这将不会发生。您将得到正确的差值。这是正确使用的无符号算术的魔力。
以上来自于百度翻译 以下为原文 If you subtract the previous time from the current value, using unsigned arithmetic, this will not happen. You will get the correct difference value. That is the magic of unsigned arithmetic when used correctly. |
|
|
|
|
|
如果从当前值中减去以前的时间,使用未签名的算术,这将不会发生。您将得到正确的差值。这是使用正确的无符号算术的魔力。哇,你说得对……这相当方便。
以上来自于百度翻译 以下为原文 If you subtract the previous time from the current value, using unsigned arithmetic, this will not happen. You will get the correct difference value. That is the magic of unsigned arithmetic when used correctly. Wow you're right...thats pretty convenient. |
|
|
|
|
|
所以我好像在堆栈。编译器向我发出了一个警告:我可能没有注意到一个可能的堆栈溢出,也可能被忽略了,所以我重新排列了一些代码,以减少函数调用,并且现在不必发生损坏。微控制器的编程非常有趣……我有很多东西要学。
以上来自于百度翻译 以下为原文 So it seems like I was overflowing the stack. The compiler was throwing me a warning about a possible stack overflow which I never noticed and also probably ignored, so I rearranged some code to have less function calls and it works without the corruption now! Programming for microcontrollers is very interesting...I have many things to learn. |
|
|
|
|
|
重置处理器将导致变量被重新初始化,可能为零(0),除非您明确地赋予它不同的值。更容易让它滚到零(0),当你从第14页学到的时候,如果正确的话,运算就可以了。
以上来自于百度翻译 以下为原文 Resetting the processor will result in the variable being re-initialized, probably to zero (0) unless you explicetly assign it a different value. Much easier to just let it roll over to zero (0) and as you learned from post#14 the arithmetic will work OK if done properly. |
|
|
|
|
|
显示刷新通常是每秒200到500毫秒。您可以使用每1毫秒更新的无符号字符(字节),以256毫秒的间隔刷新显示。当它从255翻滚时,检测零。只有8位变量和一个机器周期才能检测到零,这将更有效率。
以上来自于百度翻译 以下为原文 Display refresh is usually every 200-500 mSec. You could just use an unsigned character (byte) updated every 1 mSec for display refresh at 256 mSec intervals. Just detect zero when it rolls over from 255. That would be more efficient with only an 8 bit variable and one machine cycle to detect zero. |
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
475 浏览 0 评论
5794 浏览 9 评论
2334 浏览 8 评论
2224 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3530 浏览 3 评论
1125浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1098浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
873浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
475浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 14:59 , Processed in 0.993950 second(s), Total 103, Slave 86 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1358