完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
大家好,芯片是PIC18F46K22,使用XC8编译器。我在UART RX中断处理程序中有一个简单的状态机。它每隔几秒钟从另一个设备接收一个10字节的数据包。我想检测另一个设备不发送完整的10字节数据包的情况。假设另一个设备只发送5个字节,然后停止发送数据。如果在超时间隔内没有接收到新的数据包,我必须重置状态机。是否需要禁用主()函数中的全局中断来编写这个逻辑?如果以上情况发生,有人能帮助我如何重置状态机吗?非常感谢你的帮助。
以上来自于百度翻译 以下为原文 Hello everyone My chip is PIC18F46K22 and using XC8 compiler. I have a simple state machine inside the UART RX Interrupt handler. It is receiving a packet of 10 bytes from another device after every few seconds. I want to detect the condition in which the other device do not send a complete 10 bytes of packet. Let us say the other device just sends 5 bytes and then stops sending data. I have to reset the state machine if it does not receive a new packet within a timeout interval. Do i need to disable the Global interrupts in the main() function to write this logic? Can anyone help me how to reset the state machine if the above condition occurs? Your help is highly appreciated. |
|
相关推荐
19个回答
|
|
|
不要禁用中断。绝对不会中断中断服务!启用一个常规的定时器中断,例如每毫秒一次。每次从UART接收字符时,初始化一个变量到毫秒数,直到发生超时。在定时器中断服务中,如果该变量为非零,则减一次。如果它变为零,则发生超时。然后做任何你需要做的重置你的状态机。
以上来自于百度翻译 以下为原文 Don't disable interrupts. Most definitely do NOT stop inside an interrupt service! Enable a regular timer interrupt, say once per millisecond. Every time you receive a character from the UART, initialise a variable to the number of milliseconds until a timeout should occur. In the timer interrupt service, if that variable is non-zero, decrement it once. If it becomes zero, a timeout has occurred. Then do whatever you need do to reset your state machine. |
|
|
|
|
|
每次收到一个字节,就启动一个定时器。如果计时器中断,你知道你超时了。如果收到完整的数据包,请停止计时器。
以上来自于百度翻译 以下为原文 Every time you receive a byte, start a timer. If the timer interrupts, you know you timed out. If you receive a complete packet, stop the timer. |
|
|
|
|
|
打你约翰,功能和我的建议非常相似:
以上来自于百度翻译 以下为原文 Just beat you John. Functionally very similar to what I suggested :) |
|
|
|
|
|
我在主()中使用一个计时器,它在100毫秒时到期:它用来计时超循环@ 100MSEC。这是一个阻塞代码,没有一个手持机,在某种程度上,我可以使用这个计时器,用于你在帖子中提到的目的,那就是检测超时条件吗?
以上来自于百度翻译 以下为原文 I am using a timer in the main() which expires at 100 msec as following: while (TMR0IF==0); // 8 * 65536 / 5MHz = 100msec interval TMR0IF=0; It is used to time the superloop @100msec. It's a blocking code and don't have a handler Is there someway that i can use this timer for the purpose you mentioned in your post, that is to detect the timeout condition? |
|
|
|
|
|
有几十种不同的方法可以做到这一点。在我看来,有一个以1ms间隔运行的计时器服务(或者如果合适的话慢一些)是实现各种延迟的最简单的方法。你可以有多个计时器变量同时被同一个服务并行地递减以实现MU。不同的延迟。偶定时器(2/4/6)是有用的,因为PRX寄存器意味着您可以设置它在每个中断上自动预加载,以保持均匀的速率。您正在运行的时钟速度是多少?
以上来自于百度翻译 以下为原文 There are dozens of different ways you could do it. In my opinion, having a timer service running at 1ms intervals (or slower if that suits) is the easiest way to implement all sorts of delays. You can have multiple timer variables all being decremented in parallel by the same service to implement multiple different delays. The even timers (2/4/6) are useful for this, as the PRx register means you can set it to automatically preload on every interrupt to maintain an even rate. What clock speed are you running at? |
|
|
|
|
|
|
|
|
|
|
|
如果在主()函数内禁用短时间的全局中断位,我会错过任何中断,特别是外围中断吗?
以上来自于百度翻译 以下为原文 If i disable global interrupt bit for a short duration inside the main() function will i possibly miss any interrupts, specially peripheral interrupts due to that? |
|
|
|
|
|
如果你将TMR2设置为:PoxSale==1:10PrPoCale= 1:4PR2= 124,那么定时器将每1毫秒翻转而不必做任何事情。(20MHz / 4/10/4/125=1000)中断将被推迟直到您再次设置GIE。但是,如果GIE关闭时发生两次,那么您将错过一次。他们当中。
以上来自于百度翻译 以下为原文 If you set TMR2 up as: Postscaler = 1:10 Prescaler = 1:4 PR2 = 124 Then the timer will roll over every 1 millisecond without you having to do anything. (20MHz /4 /10 /4 /125 = 1000) The interrupts will be deferred until you set GIE again. However, if one occurs twice while GIE is off, then you will miss one of them. |
|
|
|
|
|
如果你将TMR2设置为:PoxSale==1:10PosiCale= 1:4PR2= 124,那么定时器将每1毫秒翻转,而不必做任何事情。(20MHz / 4/10/4/125=1000)看起来非常干净。一定要试试看。你能告诉我如何做TMR2上面的初始化吗?
以上来自于百度翻译 以下为原文 If you set TMR2 up as: Postscaler = 1:10 Prescaler = 1:4 PR2 = 124 Then the timer will roll over every 1 millisecond without you having to do anything. (20MHz /4 /10 /4 /125 = 1000) That looks very clean. Will definitely give it a try. Can you tell me how to do above initializations for TMR2? |
|
|
|
|
|
以上来自于百度翻译 以下为原文 // Setup TMR2 to interrupt every 1ms from a 20MHz oscillator T2CON = 0b01001101; // Postscaler 1:10, Tmr On, Prescaler 1:4 PR2 = 124; // Count from 0 to 124 =125 counts PIE1bits.TMR2IE = 1; // Enable interrupts |
|
|
|
|
|
非常感谢。如果我需要它在每10毫秒中断,那么我应该改变它的后标器或预分频器值吗?10ms的新价值是什么?
以上来自于百度翻译 以下为原文 Thanks a lot. If i need it to interrupt at every 10ms then should i change its postscaler or prescaler value? What would be the new value for 10ms? |
|
|
|
|
|
你不能精确到10ms,除非你运行1ms并且计数十的中断。否则,在1:16之前,Pr1 194,Pr2 194将给出20MHz / 4/16 / 16/195=100.16赫兹=9984ms。
以上来自于百度翻译 以下为原文 You can't get exactly 10ms, unless you run 1ms and count off ten of those interrupts. Otherwise, pre 1:16, post 1:16, PR2 194 will give 20MHz /4 /16 /16 /195 = 100.16 Hz => 9.984ms |
|
|
|
|
|
如何快速计算这些值?我花了好几个小时进行打击和审判,但仍然找不到结果。请告诉我们如何轻松地进行这些计算。
以上来自于百度翻译 以下为原文 How do you calculate those values so quickly.. it took me hours to do hit and trial and still could not find results closely. Pls tell how to do these calculations easily? |
|
|
|
|
|
我想我只是在手机上使用了一个计算器应用程序,并尝试了几个因素。从20000000开始,除以4得到指令时钟,100因为这是期望的中断率,现在给你五千元你必须除以(1, 4,或16),然后(1到16)得到一个数字。这是一个很大的数字,所以我对预分频器进行了1∶16,所以50000/16=3125,5的末尾直接告诉我,我只能除以5。快速检查确认你不能除以3.3125/5=625,这对于PR2来说太大了。
以上来自于百度翻译 以下为原文 Experience I guess. I was just using a calculator app on my phone, and trying a few factors. Starting from 20,000,000, divide by 4 to get the instruction clock, and 100 because that is the desired interrupt rate, gives 50,000 You now have to divide by (1, 4, or 16), then by (1 to 16) to get a number <= 256 That number is big, so I went traight to 1:16 for the prescaler, so 50,000/16 =3125 The 5 on the end tells me straight away I can only divide by 5. A quick check confirms you can't divide by 3. 3125/5=625 which is too big for PR2. |
|
|
|
|
|
如果你这样做,你可以创建一个变量来计算你的超循环,我们称之为TigkCube。这会给你的应用程序带来时间感。将TICKCOUNT声明为未签名,并确保TigkCube足够长。
以上来自于百度翻译 以下为原文 If you do this, you can create a variable which counts your superloops, let's call it TickCount. This will give your app the sense of time. Declare TickCount as unsigned and make sure TickCount is long enough. When you receive a character, you simply do: if (TickCount - PrevTickCount) > TIMEOUT { // whatever you might have received before has expired. Therefore you // reset the reception, store the received character at the beginning of the buffer } else { // add the character to the buffer as you would normally do } PrevTickCount = TickCout; |
|
|
|
|
|
我使用Time2来实现从UART端口1接收字节的超时,现在我还有第二个UART端口也接收数据包。我的芯片是PIC18F46K22,它有2个UART端口。如何使用TimeR2分别重置两个UART端口的RX状态机?或者我应该使用另一个定时器为第二UART端口超时?
以上来自于百度翻译 以下为原文 I used TIMER2 for the above implementation of timeout in the receive bytes from UART port 1. Now i have second UART port also receiving packets. My chip is PIC18F46K22 which has 2 UART ports. How can i use TIMER2 for separately reset the RX state machines of both UART ports? Or should i use another timer for the second UART port timeout? |
|
|
|
|
|
我在POST后6中提出的方法可以让您实现多个并行,所有使用单个硬件定时器。
以上来自于百度翻译 以下为原文 The method I proposed in post#6 lets you implement as many as you want in parallel, all using a single hardware timer. |
|
|
|
|
|
这正是我所做的。我通常减去零点。这里有一个最近的例子,使用100US定时器0中断:对于主循环中的LED,例如:
以上来自于百度翻译 以下为原文 That's almost exactly what I do. I usually decrement and stop at zero. Here's a recent example using a 100us timer 0 interrupt: void __interrupt(irq(IRQ_TMR0),base(IVT_BASE),low_priority) tmr0_isr() { TMR0IF = 0; // clear the TMR0 interrupt flag if (tmr1ms) tmr1ms--; else { // 1ms tasks tmr1ms = 9; if(ledtmr) ledtmr--; // led timing if(seqtmr) seqtmr--; // power sequencer timing if(statctr) statctr--; else { statctr = 4; statflag = 1;} // 5ms timer for status output } if(i2c_dly) i2c_dly--; // I2C timing // 100us tasks and for the LED in the main while loop for example: while(1) { if (ledtmr == 0) { LED = !LED; ledtmr = 250; // 500ms blinker } |
|
|
|
|
|
此外,确保所有这些变量(LeDTMR,SEQTMR,STATCTR)都符合“易失性”,并确保它们只有8位,否则非中断代码不能可靠地检查它们是否为零。
以上来自于百度翻译 以下为原文 Exactly Mark. Also, make sure all this variables (ledtmr, seqtmr, statctr) are qualified as "volatile", and make sure they are only 8 bits, otherwise non interrupt code cannot reliably check they are 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 16:21 , Processed in 1.719114 second(s), Total 110, Slave 93 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
9139