problem with continuos USART communication btw PC & ATme

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

I am trying to establish a communication system between atmega32 and PC using RS232.
previously i used the following code:


unsigned char usart_receive( void ){
  unsigned char data;
  while ((UCSRA & 0x80) == 0x00); // Wait for till the data arrives data
  data=UDR;	
  return data;
}
void usart_transmit( unsigned char data )
{
  while ((UCSRA & 0x20) == 0x00);  // Wait until the transmit buffer is empty
  UDR = data; // As soon as the buffer is empty, put the data in UDR
}
void main()
{
while(1)
{
char c,buf[50];
int i=0;
for(i=0;i<20;i++)
{
buf[i]=usart_receive();
}
for(i=0;i<20;i++)
{
usart_transmit(buf[i]);
}
}
}


i took care of initiallising the usart,but code was not working properly, as it got stuck in while loop of recieve function if it doesnot recieve any data, so do not proceed for transmission.
Then i changed the function for tranmission and receiving by replacing while loop as follow:

unsigned char usart_receive( void )
{
  unsigned char data;
if((UCSRA & 0x80))
 {
 data=UDR;
  return data;
  }

}
void usart_transmit( unsigned char data )
{
  
if(UCSRA & 0x20)
  {UDR = data; 
}
}


now when i executed it with same main function. after sending the complete string buf, it kept continously sending the last byte of buf string . repeative sending happens if i send a single character also in place of string.
all i want is to have system which can receive data any time and transmit data anytime, without any external swithing.
Please help me out.Please reply soon. Thanks in advance.[/code]

Hari

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

just to make sure the hardware path is OK:
- when you transmit a character on the PC it is received correctly on the AVR?
- When you transmit a character from the AVR it is correctly received on the PC side?

what is your clock source ? internal RC, XTAL or oscillator?

did you take a look already in the tutorials forum? there are a couple of tutorials on how the uart is best used. You might also find what is wrong there.
basic code should be:

main{
init uart
loop
 if charcater is received send character
end loop
}

I never see you initializing the uart, if you do, but not tolled us here, post also that code so we can see what is going on there (might be an init fault)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
unsigned char usart_receive( void )
{
  unsigned char data;
if((UCSRA & 0x80))
 {
 data=UDR;
  return data;
  } // else { what should it do??? }

} 

Or you should have a global variable , let us call it receive_status, which is , say one if uart receide something, zero else (and echo back only if uart receved a char...)

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

The dos c compilers had a kbhit() function that returned true if a char was waiting to be read. Its just the state of the status bit in the status reg.

Imagecraft compiler user

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

meslomp wrote:
just to make sure the hardware path is OK:
- when you transmit a character on the PC it is received correctly on the AVR?
- When you transmit a character from the AVR it is correctly received on the PC side?

what is your clock source ? internal RC, XTAL or oscillator?

did you take a look already in the tutorials forum? there are a couple of tutorials on how the uart is best used. You might also find what is wrong there.
basic code should be:

main{
init uart
loop
 if charcater is received send character
end loop
}

I never see you initializing the uart, if you do, but not tolled us here, post also that code so we can see what is going on there (might be an init fault)


Thanks Meslomp for replying.
reception and tranmission is absolutly correct. i got the same character at pc on transmission and reciceve the same char wat is transmitted by pc. only problem is that i get the last character (but correct) again and again and forever. it happens even when i transmit only one char.
I have used internal RC clok with freq. 8 Mhz.
I have read the complete USART part from datasheet of ATmega32 but cant get any clue regarding the problem.
The code for initiallisation is:

void _init_usart( unsigned int Baudrate );
{
  UBRRH=0x00;
  UBRRL = (unsigned char)Baudrate; // Set the baud rate
  UCSRB = 0x18; // enable transmitter and reciever
  UCSRC = 0x86; // set as 8 bit data, no parity bit and 1 stop bit.
}

Hari

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

Hi! Thank you freinds for making your efforts and giving time to the problem.
I got the problem solved about repetitive transmission, by using USART_RXC_vect interrupt for reception and USART_UDRE_vect intrrupt for transmission.
The working code is as follow:

volatile char c;
ISR(USART_RXC_vect)
{
c=UDR;
UDR=0;
}

ISR(USART_UDRE_vect)
{
c=UDR;
c=0;
}
void main()
{
while(1);
}

if c and UDR is not cleared in respective ISR then i got the repititive transmission again.

but now i am getting abother problem i.e.
i am unable to store the variable 'c' value.
The code for storing recieved data, i wrote, is as follow:

volatile char c,buf[50];
volatile int i=0;
ISR(USART_RXC_vect)
{
c=UDR;
UDR=0;
buf[i]=c;
i++;
}

ISR(USART_UDRE_vect)
{
c=UDR;
c=0;
}
void main()
{
while(1);
}

the code is supposed to store the recievd data in buf buffer but buf always empty, even c is getting the same values what is transmitted(i have checked it).

Hari

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ISR(USART_RXC_vect)
{
c=UDR;
UDR=0;
} 

Are you sure you want to do that. Writing 0 to UDR doesn't clear the receive register to a known value if that's what you were trying to do here. That actually causes 0x00 to be transmitted out through the TXD line. Surely that's not what you want?

c=UDR;
c=0;

Again curious code. What is the plan here? You read UDR (even though this is the transmitting not receiving interrupt) and then immediately over-write c with 0x00 anyway - why?

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

clawson wrote:
why?

If i dont clear c in UDRE interrupt and UDR in RXC interrupt then the last character which was in UDR after receiving or transmission keeps transmitting again and again. I want to stop that. And i get this repetitive transmission stopped only and only when i cleared those things, c and UDR.(this is proved, experimentally).

Hari

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

You should test whether there is a new character, and, only if there is a new one, read it....

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

Quote:

(this is proved, experimentally).

Don't just "suck it and see". Design it properly in the first place, implement it, if it stil doesn't work fix the implementation bugs or revise the design.

Just adding bits and pieces here and there until something appears to "work a bit" is not great design strategy.

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

You get a transmit interrupt after the data register is empty. That includes after the last char is gone. So if you get a tx int and there are no more chars, shut off the tx int?

Imagecraft compiler user

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

dbrion0606 wrote:
You should test whether there is a new character, and, only if there is a new one, read it....

this approach will fail in case the string (to be received)will have repeating characters.

Hari

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

Quote:

this approach will fail in case the string (to be received)will have repeating characters.

How do you come to that conclusion?

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

clawson wrote:
Quote:

this approach will fail in case the string (to be received)will have repeating characters.

How do you come to that conclusion?

for checking if there is a new character or not, i have to compare the data in UDR with the previously received character, if they dont match then you can say that its new, but if they match then its may be old or may be new but the repeating character of string.
this is what goes in mind when i think of "checking the new incoming character".
Let me know if you know any other way or in case i am wrong.

Hari

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

I refrred to your first software: you did not test the status in the non-blocking usart_receive (then, if a character was not incoming, you had a weird value/duplicate one ) : there is an if, but what does it do when condition is not fulfilled? an else would be useful or you should return outside the if block....

That was for the part without interrupts.

And could you explain whar happens to c ? in the sending interrupt?

If the sending interrupt is :
c=UDR;
c=0;

Is UDR a printable character?
Is c the character you want to send?
I do not understand how this function works.

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

harimohan wrote:
dbrion0606 wrote:
You should test whether there is a new character, and, only if there is a new one, read it....
this approach will fail in case the string (to be received)will have repeating characters.
You have misunderstood.

Testing whether or not there is a new character does not involve comparing UDR with previous characters received. The hardware can tell you whether or not there is a received character waiting in UDR, and also whether the last character you wrote to UDR has been moved to the shift register for transmission (making it safe to write to UDR again), and also when the last character in the shift register has been completely transmitted.

You need to re-read the datasheet and understand the meaning and proper use of RXC, UDRE, RXCIE, and UDRIE.

Look in the tutorials section of these forums, this has all been done before. Go to the search page, and search for:

    uart usart -software
... click Search for any terms..., under Forum select AVR Tutorials, and under Search previous click Search message title only. I get 13 hits to tutorials that should get you started.

JJ

"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

dbrion0606 wrote:

And could you explain whar happens to c ? in the sending interrupt?

If the sending interrupt is :
c=UDR;
c=0;


Ohhh!! i am so sorry i wrote wrong code for sending interrupt part, unconsciously. sorry for it.
The correct code is

volatile char c,buf[50]; 
volatile int i=0; 
ISR(USART_RXC_vect) 
{ 
c=UDR; 
UDR=0; 
buf[i]=c; 
i++; 
} 

ISR(USART_UDRE_vect) 
{ 
UDR=c; 
c=0; 
} 
void main() 
{ 
while(1); 
} 

I apologies for it.
Notice ISR (USART_UDRE_vect) part.
And this is what i was trying with so far not that previous code and getting good result in sending one single character.

Hari

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

harimohan wrote:
Ohhh!! i am so sorry i wrote wrong code for sending interrupt part, unconsciously. sorry for it.
The correct code is
I'm sorry... are you saying that you're typing code into your forum posts? If you're having trouble with and have questions about a piece of code that you're working with, you should copy/paste it from your development environment instead of re-typing it. Typos and other mistakes waste everyone's time.

JJ

"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

Quote:
you should copy/paste it from your development environment instead of re-typing it.

actually i am doing this project in a institute where i am not allowed to use internet.
so i dont have the copy of actual code i am working on, in my house.

Quote:
Typos and other mistakes waste everyone's time.

JJ


I am sorry for this. This wont happen next time.[/code]

Hari

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

harimohan wrote:
so i dont have the copy of actual code i am working on, in my house.
Fair enough.

In any case you've asked for help and several people have hinted at where you're going wrong. The approach you've taken is unworkable. Please review my last post, and those of the others who have replied.

JJ

"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]