EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Unusual USART behaviour on AVR AT90CAN128

Started by Rav July 12, 2007
Hi,

I have found some unusual USART behaviour when i was trying to send
characters from USART1 of my AT90CAN128 to the PC terminal. Below is
the code that i have been using for the same. The problem is, what i
am getting on my PC hyperterminal is some garbage. I did some
calculations and found that there was a difference of 128 between the
characters sent and the character received. For example, if i sent 0 i
received 128 and if i sent 10 i received 10+128 = 138.

The same code works well with the USART0. Also, i checked the
waveforms on my oscilloscope by probing on the controller pin(TXD1)
and on the transmit pins of MAX232 (before RS232). The patterns were
almost identical. What i was wondering is that whether my USART was
corrupt internally?

While on chip debugging with Atmel's JTAG ICE mkII, i found that the
USART's data register UDR1, in the IO register window, was still
showing zero even when i have put a breakpoint at the place where i
was assigning the data to the USART data register for transmitting.
Kindly, help me overcome this problem.

#include<avr/io.h>

#define F_CPU 16000000L    // F_CPU = 16MHz
#define BAUD 9600              // Baudrate = 9600

void USART1_Init ()
{
  /* Set baud rate */
  UBRR1H = (unsigned char) (((F_CPU/(16L*BAUD))-1) >> 8);
  UBRR1L = (unsigned char) ((F_CPU/(16L*BAUD))-1);

  /* Set frame format: 8data, no parity & 1 stop bits */
  UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (1<<USBS1) | (3<<UCSZ1);

  /* Enable transmitter and receiver */
  UCSR1B = (0<<RXEN1) | (1<<TXEN1);
}

void USART1_Transmit(void )
{
   while ( ! ( UCSR1A & (1<<UDRE1)))
    ;

   UDR1 = trans_data ; // Place for breakpoint.
   trans_data++;

   if(trans_data >= 0x64)
   trans_data = 0x00;
}


void main(void)
{

   unsigned char trans_data = 0x00;

   USART1_Init();

   while(1)
      USART1_Transmit();

}

> I have found some unusual USART behaviour when i was trying to send > characters from USART1 of my AT90CAN128 to the PC terminal. Below is > the code that i have been using for the same. The problem is, what i > am getting on my PC hyperterminal is some garbage. I did some > calculations and found that there was a difference of 128 between the > characters sent and the character received. For example, if i sent 0 i > received 128 and if i sent 10 i received 10+128 = 138.
Make sure the number of bits per byte, number of stop bits, and parity matches on the sender and receiver.
> The same code works well with the USART0. Also, i checked the > waveforms on my oscilloscope by probing on the controller pin(TXD1) > and on the transmit pins of MAX232 (before RS232). The patterns were > almost identical. What i was wondering is that whether my USART was > corrupt internally?
It's tempting to blame the UART but always exhaust all SW root cause possibilities first. It's embarrassing to call the tech support line and then later be shown the mistake is in SW. JJS
Rav wrote:
> Hi, > > I have found some unusual USART behaviour when i was trying to send > characters from USART1 of my AT90CAN128 to the PC terminal. Below is > the code that i have been using for the same. The problem is, what i > am getting on my PC hyperterminal is some garbage. I did some > calculations and found that there was a difference of 128 between the > characters sent and the character received. For example, if i sent 0 i > received 128 and if i sent 10 i received 10+128 = 138. > > The same code works well with the USART0. Also, i checked the > waveforms on my oscilloscope by probing on the controller pin(TXD1) > and on the transmit pins of MAX232 (before RS232). The patterns were > almost identical. What i was wondering is that whether my USART was > corrupt internally?
If you have one that works, and one that does not, try running both at the same time, and compare the outputs with the scope. You can also try deliberate skew of the Baud divider to values either side of ideal, to check margins. -jg
On Jul 12, 6:50 am, Rav <rav.tech...@gmail.com> wrote:
> Hi, >
[... USART problems ...]
> > /* Set frame format: 8data, no parity & 1 stop bits */ > UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (1<<USBS1) | (3<<UCSZ1);
Get out the data sheet and read it. This line doesn't do what you think it does. For example, you're specifying two stop bits, not one. Regards, -=Dave
On Jul 13, 3:03 am, Dave Hansen <i...@hotmail.com> wrote:
> On Jul 12, 6:50 am, Rav <rav.tech...@gmail.com> wrote:> Hi, > > [... USART problems ...] > > > > > /* Set frame format: 8data, no parity & 1 stop bits */ > > UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (1<<USBS1) | (3<<UCSZ1); > > Get out the data sheet and read it. This line doesn't do what you > think it does. For example, you're specifying two stop bits, not one. > > Regards, > > -=Dave
My apologies. It had been corrected to UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (0<<USBS1) | (3<<UCSZ1);
On Jul 12, 11:09 pm, Rav <rav.tech...@gmail.com> wrote:
> On Jul 13, 3:03 am, Dave Hansen <i...@hotmail.com> wrote: > > > On Jul 12, 6:50 am, Rav <rav.tech...@gmail.com> wrote:> Hi, > > > [... USART problems ...] > > > > /* Set frame format: 8data, no parity & 1 stop bits */ > > > UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (1<<USBS1) | (3<<UCSZ1); > > > Get out the data sheet and read it. This line doesn't do what you > > think it does. For example, you're specifying two stop bits, not one. > > > Regards, > > > -=Dave > > My apologies. It had been corrected to > UCSR1C = (0<<UMSEL1) | (0<<UPM1) | (0<<USBS1) | (3<<UCSZ1);
Does that fix it? What is the value of UCSZ1? If it is 2 (which is what I would guess given the name), you are putting your UART into 7-bit mode rather than 8-bit. Regards, -=Dave

The 2024 Embedded Online Conference