Strange behaviour in PIC18 interrupt

I am using a PIC18F4320 and have been trying to solve a very strange problem..

I have configured an interrupt using Timer1 which fires every 1ms. In that interrupt an ascii character gets sent, and is incremented, every time. Also, every 79 interrupts another section of the code gets executed, which just sends a '%' and resets the ascii code to '1'.

Nothing else is going on AT ALL in the program (i.e. no main routines at all). There are NO other interrupts running, just this one. The PIC is running at 40MHz and the serial comms are at 115,200 baud. Looking at the output on hyperterminal, it works fine streaming these lines of

79 ascending ascii characters and then a '%' then periodically, about every 13 lines of this some characters get missed. Its really odd.

Changing the baud rate makes no change at all to the problem. Changing the interrupt rate even just the tiniest bit either makes the problem never occur or occur much much less often. Changing the clock rate also makes the problem disappear (from 40MHz to 10MHz). I literally have been stripping the program down to find the problem and its just one interrupt routine now, sending this data - note I even got rid of the context saving at the start and end to see if that helped...:

int btfsc PIR1,0 ; check if its the timer goto int_timer1 ; in which case service the interrupt goto int_end ; else go to the end int_timer1 ; comes here every 1.0002ms incf SPECIAL movf SPECIAL,W addlw 0x30 ; so we are in numbers movwf TXREG movlw Timer1L ; setup the timer period again movwf TMR1L ; movlw Timer1H ; movwf TMR1H ; bcf PIR1,0 ; clear the flag decfsz INTDIV1 ; divide the interrupt by 10 goto int_end int_timer2 clrf SPECIAL movlw '%' movwf TXREG movlw IntDiv movwf INTDIV1 ; int_end ; retfie ; return from int

Any suggestions? I couldn't paste the output from hyperterminal in here because the wrapping messed it up - go here for a screen shot:

formatting link

you can see the weird glitch happening three times in that window.

Hope someone can help! I could of course just change the interrupt rate which solves it, but I would like to know the cause of the problem,

Cheers,

Reuben

Reply to
R. Wilcock
Loading thread data ...

every

Are you SURE this isn't a problem with hyperterminal/your PC serial port? There are many problems with hyperterminal and the screenshot you have looks just like hyperterminal is throwing characters away..

Iain

Reply to
tebbutt

I have two thoughts:

  1. If updating the timer register while it is running, you may have a problem if the timer is in the process of rolling the ls byte over and carrying to the ms byte. For that, you can disable the timer while updating.

  1. Program another controller to look at the input characters and set a output whenever a wrong character is seen. Use this to trigger a digital scope looking at the serial line to get a better idea of what is happening: is there unusual timing between characters, etc.

Thad

Reply to
Thad Smith

I suspect your difficulty really has to do with hyperterminal/Windoze and unterminated lines rather than the sender. Try terminating the lines with or '\n' rather than '%', or with both. Try another terminal program, such as Telix or ProComm. Receive it on a machine running plain MSDOS rather than Windoze. Is the PC RS232 interface using something like a USB intermediary, or do you have a real RS232 port?

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
Reply to
CBFalconer

Sounds like you are sending too quickly for hyperterminal. Try putting some pauses into the stream, say every 16 bytes, or maybe implement XON/XOFF or hardware handshaking.

Reply to
Ppelectron

Thanks for all the responses:

Iain: this is something I am trying to determine right now. I believe that it is not the computer, because I have tried different baud rates and exactly the same thing happens (even with very slow baud rates). I have tried 3 different serial monitors and all three show the same thing.

Thad: The timer registers are such that you update the high one then the low one and only when you have updated the low one, both are written (i.e. the regs you write to are not the actual timer regs). The idea of having another PIC to check the output is a good idea - I had planned to do this today.

CBFalconer: The problem was originally spotted when the normal program functionality was running, which contained plenty of end of regular terminated lines, so this is not the problem. I have tried it with 3 terminal programs and all show the same response. This is direct to serial, not with USB VCP.

Ppelectron: I doubt that I am sending it too often - once every ms is nothing for a baud rate of 115,200. In any case, the original program had plenty of spaces and end of line characters etc.. and the problem was still there (this example I have put is just to try and nail down to the problem).

Any more suggestions?

Cheers,

Reuben

Reply to
Reuben Wilcock

Reuben, Can you post the entire program with initialization? Any chance the watchdog time has been enabled? How is int_timer2 accessed? Do you have Timer1 configured for 8bit or 16bits writes?

"A write to the high byte of Timer1 must also take place through the TMR1H Buffer register. Timer1 high byte is updated with the contents of TMR1H when a write occurs to TMR1L. This allows a user to write all 16 bits to both the high and low bytes of Timer1 at once. The high byte of Timer1 is not directly readable or writable in this mode. All reads and writes must take place through the Timer1 High Byte Buffer register. Writes to TMR1H do not clear the Timer1 prescaler. The prescaler is only cleared on writes to TMR1L."

Reply to
AntiSPAM_g9u5dd43

This is a clue. Have you checked the errata for the chip? More specifically, have you checked the errata for the chip you are using, not for the latest silicon revision (or, alternately, tried the silicon revision that is current). There were a number of "issues" with early 18F parts running at full speed.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

So you have two code blocks that want to use the UART, one of which is a timerINT - or the UART is ONLY under the 1msINT control, which 78/79 does CH_TX, and 1/79 does %_TX ?

There are clues there. Sounds like a classic aperture effect - hard part is to figure out where/what the critical aperture is :) You could very slowly sweep the timer rate, and try and track the failure pattern. What about other clocks, between 10Mhz and 40MHz ?

-jg

Reply to
Jim Granville

Interesting one... I don't know PIC in depth, but here are some obervations...

  • I see you are using 8-N-1 in the screenshot, so this isn't a clock slip / parity failure, or you'd see garbage. It'd seem the USART is not sending at all.

  • The values keep incrementing, so clearly the ISR keeps firing. Again, you need to focus on why the USART isn't sending.

  • I only see 2 skips in the screen shot - one is ~63 characters, the other is ~73. They're ~882 characters apart. Look for more patterns like this and see if you can find trends that hint at a cause. (Like, is the number of milliseconds or characters consistant at different baud rates?)

  • Does the USART support any hardware flow controls? Are their inputs floating?

  • Have you tried checking (halting on) USART status flags before / after loading the USART buffer? Maybe it's reporting a condition that you're ignoring. At 1mS & 115Kb, it shouldn't ever fill up, but this might narrow your search.

  • What's your USART accuracy at 115Kb with 10MHz vs. 40MHz? I'd suggest you're cutting your timing budget too close, but if it happens at lower baud rates too, this isn't likely the issue. Have you checked your bit/byte timing with a scope to confirm the accuracy?

Cheers, Richard

Reply to
Richard H.

I saw this post before but due to a glitch it got wiped before I had a chance to reply. If I remeber right you were losing characters and your code had no handshaking protocal.You might at first think that a high speed uart with a fifo and a 3Ghz processor could keep up with a little PIC, sadly not. You must implement some handshaking, xon/xoff is best as it needs less harware but cts/rts is easier on the software.

Reply to
CBarn24050

strange

In

every

chance

had no

with a

You must

but

I'm inclined to agree with this. Even at only one character per mS, if windows zones out for 16mS you have lost data. It doesn't sound sensible, but I could easily see windows being out to lunch and not servicing interrupts for the 100mS needed to cause your data loss. In fact I've seen a PC freeze intermittently (due to a brain dead VXD device driver) so badly that the clock lost hours per day because of all the lost timer ticks (these only occur every 50 something mS). If you use OE for email and have large numbers of records in your folders, win98 will freeze the machine (mouse even stops moving) while rifling thru the database and toss timer ticks out. It's really kinda sad. I'd trust a DOS terminal program or even another PIC long before believing anything hyperterm showed me.

Reply to
Anthony Fremont

Yes well I eventually found the problem, by making another PIC read the first one, and a few of you were right - the PC was at fault. It was just dropping characters for no reason.

Thanks for all the help! I have doubled the interrupt period and it doesnt happen any more, but still, pretty pathetic if you ask me that a

2Gig PC cannot keep up with a PIC!

Reuben

Reply to
reubenwilcock

Of course we were right. We have dealt with Micro$loth OSs before. It's not the PC, its the alleged programming of it.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.