UART INTERRUPT PROBLEM

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

 

I am programming at90can128 and I "talking" with a module through UART peripheral. The receive characters received via interrupt into a ring-buffer. 

Except from the UART ISR I also have TIMER ISR, ADC ISR , SPI ISR, CAN BUS ISR etc... in my code.
I encountered a weird problem : I am getting half words as a response from the module I am talking with into the ring-buffer. For example : if I am expecting for "OK\r\n", I am getting just the : "O\n" without the "k\r" in the middle as if something interrupt the uart interrupt from occurring in the middle of the line being received

 

Does someone encountered this problem ? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you get the same results when you disable the other interrupt sources?

 

The shortest answer is, as almost always:  Post the smallest complete test program that exhibits the symptoms.

 

From what we have given, we cannot tell whether it is parity problem (enabled on one end and not the other), clock speed, ring buffer, SEI in ISRs, or ...

 

Does your receive ISR trap and report errors (framing, overrun, parity)?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could one of the other interrupting sources be taking so long to handle its interrupt service that some of the inbound characters are simply lost as the RXC buffering interrupt doesn't get a chance to operate?

 

As you cut down your program to make the test program that Lee suggests I bet you find the problem "goes away" at some stage as you remove the seemingly innocuous code that is blocking things ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Could one of the other interrupting sources be taking so long to handle its interrupt service that some of the inbound characters are simply lost as the RXC buffering interrupt doesn't get a chance to operate?

 

clawson,

 

can you elaborate more on this please ?

I neutralized the other interrupts in the beginning of the UART ISR by the cli() command and at the end I put sei() so the other interrupt work again then the problem solved but it's not a proper way for the program to work, but just to find where is the problem (interrupt clashing)

 

what is your suggestion to solve it ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Putting a cli and sei in your usart isr won't achieve much - the AVR does this for you already. The suggestion was to disable other interrupt sources by not enabling them.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Putting a cli and sei in your usart isr won't achieve much - the AVR does this for you already.

+1

 

While it is therefore benign to put a cli() at the start of an ISR() it can be catastrophic to have an sei() in there if the same interrupt might occur and interrupt the already executing handling of the previous one (do that a few times and you have BIG problems!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Putting a cli and sei in your usart isr won't achieve much - the AVR does this for you already. The suggestion was to disable other interrupt sources by not enabling them.

 

I have for now just a TIMER interrupt that is working and I can't disable it by treating it as a comment (i.e , //) cause otherwise my program won't work. So I disabled it just when handling the USART ISR by putting cli() and sei() in the beginning and at the end of the USART interrupt.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I disabled it just when handling the USART ISR by putting cli() and sei() in the beginning and at the end of the USART interrupt.

The hardware itself disables all interrupts globally (via the I bit in SREG) when servicing an interrupt, and re-enables them before returning to the interrupted code (via a RETI instruction).  It is therefore already impossible for the TIMER interrupt to break into the USART ISR.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So how do you explain that without the adding of the cli() and the sei() the program omit received characters , hence stucked , and with the cli() and sei() it works perfectly ! ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So how do you explain that without the adding of the cli() and the sei() the program omit received characters , hence stucked , and with the cli() and sei() it works perfectly ! ?

How can you ask someone to troubleshoot your code without showing it?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would be glad to post my code here but it's too long... 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then reduce it to the smallest test program that still shows the issue you are having and post that.

 

(often in preparing such a test program you will stumble upon the reason for your problem - so it's a useful exercise anyway. For example you may find that cutting away some (seemingly) completely unrelated part of the code makes the problem go away and then you realise that the removed code was overflowing a buffer, corrupting a pointer or something like that!).