Author Topic: USART, PIC->ATmega  (Read 7041 times)

0 Members and 1 Guest are viewing this topic.

Offline Spekkio

  • Regular Contributor
  • *
  • Posts: 94
  • Country: se
USART, PIC->ATmega
« on: May 08, 2011, 01:16:09 pm »
Hi!

I have written a program for PIC that responds to a Modbus request. It works fine!
But I'm not going to use the PIC, instead I'm using a ATmega324P, I use the same C-code with only the minor changes of
registers and settings ofcourse. The program works for ATMega324P. But the receiving side does not accept the data.
I could not understand why, I used a display to debug. I set up both the PIC and ATmega circuit with a display to verify
that both the MCU's are receiving the same data. They do!
Then I used a oscilloscope on the TX pin to verify that they were also transmitting the same data. And they do!

But the difference is that the ATmega324P is sending the data a little bit slower than the PIC.
And I cannot figure out why. I was thinking maybe the ATMega was set to send 9 bit's, but it's not.
Both MCU's are set to 9600bps with 4MHz crystal oscillator. The ATMega is set to "Full Swing oscillator, fast rising"
I have tried a different setting, same result.

setting for ATMega324P

UBBR0=0x19 //25 for 4MHz
U2X0=0;
RXEN0=1;
TXEN0=1;
UCSZ02=0;
USBD0=1;
UCSZ00=3;


this is a picture of the data on the TX pin. It does seem like the ATmega is sending in 9-bit format, or sending an extra bit.
since it's approx 1ms longer. This data is 13 bytes big, so 13bit's take approx 0.00135417s or 1.3ms to send in 9600bps.
But it shouldn't, UCSZ00=3; is 8-bit format right?
I have also tried to change the value of UBBR0 to make the MCU send data faster, but the it cannot receive data correctly...
« Last Edit: May 08, 2011, 01:51:05 pm by Spekkio »
 

alm

  • Guest
Re: USART, PIC->ATmega
« Reply #1 on: May 08, 2011, 04:21:57 pm »
I'm not familiar with the compiler you're using (which you failed to mention), assigning directly to bits (as opposed to directly assigning to registers) seems like an undesirable level of abstraction to me. So UCSZ00 refers to both UCSZ00 and UCSZ01? What is USBD0?

Do you actually see a ninth bit or second stop bit? I find it hard to tell from this low-res screenshot. Try outputting something like a string of U's and measuring the baud rate for both the PIC and the AVR. I would also verify the crystal frequency (using CLKOUT and a counter/scope), maybe the micro's require a different amount of load capacitance? You expect the baud rate to be off by about 0.2% with a 4MHz crystal (use something like 3.686MHz or 7.372MHz for exact divisors), but not ~10%.

this is a picture of the data on the TX pin. It does seem like the ATmega is sending in 9-bit format, or sending an extra bit.
since it's approx 1ms longer. This data is 13 bytes big, so 13bit's take approx 0.00135417s or 1.3ms to send in 9600bps.
But it shouldn't, UCSZ00=3; is 8-bit format right?
In that case the baud rate would be ~2.4% off, which is still way too much.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9386
  • Country: my
  • reassessing directives...
Re: USART, PIC->ATmega
« Reply #2 on: May 08, 2011, 06:05:54 pm »
from picture... atmega send slower bitrate compared to PIC, but it is sending the first (rising) bit faster than the PIC ???
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline oPossum

  • Frequent Contributor
  • **
  • Posts: 918
  • Country: us
  • The other white meat
Re: USART, PIC->ATmega
« Reply #3 on: May 08, 2011, 08:17:49 pm »
Write some code to send 0xAA 0xAA and look at that on the scope. The bit timing, number of bits, and number of stop bits will be quite clear.
 

Offline deephaven

  • Frequent Contributor
  • **
  • Posts: 783
  • Country: gb
  • Civilization is just one big bootstrap
    • Deephaven Ltd
Re: USART, PIC->ATmega
« Reply #4 on: May 08, 2011, 08:48:13 pm »
Also increase the timebase speed on the scope as it is difficult to see the true nature of the serial data with your present setting.
 

Offline Spekkio

  • Regular Contributor
  • *
  • Posts: 94
  • Country: se
Re: USART, PIC->ATmega
« Reply #5 on: May 09, 2011, 01:48:25 pm »
I'm not familiar with the compiler you're using
I'm using GCC in AVR Studio 4.

Also increase the timebase speed on the scope as it is difficult to see the true nature of the serial data with your present setting.
I know, I wanted to see the entire message. I've made a program to send a smaller message.

I found out I'm ofcourse sending 2-stop bits, that's the extra bit in the ATMega324P data.
So I configured it to 1-stop bit, to my dissapointment it still doesn't work.


I'm serious, I'm not trolling you. The exakt same serial data is sent from ATMega324P
I am confused and tired of this problem.

 

Offline bilko

  • Frequent Contributor
  • **
  • Posts: 405
  • Country: 00
Re: USART, PIC->ATmega
« Reply #6 on: May 09, 2011, 02:06:43 pm »
From your latest photo it looks like you have scopeCH1 set to 5V and CH2 set to 200mV. assume Ref B is set to same level
Where are you measuring the signals and what are they referenced to ?

Signal timings look identical so its either the levels or you have an inverted signal
« Last Edit: May 09, 2011, 02:47:47 pm by yachtronics »
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9386
  • Country: my
  • reassessing directives...
Re: USART, PIC->ATmega
« Reply #7 on: May 09, 2011, 02:42:10 pm »
get a good rest. you almost there.
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

alm

  • Guest
Re: USART, PIC->ATmega
« Reply #8 on: May 09, 2011, 04:36:13 pm »
I'm not familiar with the compiler you're using
I'm using GCC in AVR Studio 4.
I would double check how to set registers, because the way I'd write:
Code: [Select]
RXEN0=1;
TXEN0=1;
Is:
Code: [Select]
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);

As far as I know, constants like RXEN0 are bit positions (RXEN0=4 for the ATmega324P), so I'm not sure what an assignment is going to do. But maybe they added some magic that I'm not aware of? I haven't paid that much attention to avr-gcc development lately. In that case I'd appreciate a link to some documentation.

See Bit manipulation and Using the USART on AVRfreaks for more information.
 

Offline Spekkio

  • Regular Contributor
  • *
  • Posts: 94
  • Country: se
Re: USART, PIC->ATmega
« Reply #9 on: May 09, 2011, 06:24:32 pm »
From your latest photo it looks like you have scopeCH1 set to 5V and CH2 set to 200mV. assume Ref B is set to same level

I'm only using one channel, CH1. The other signals that are a little bit more gray are stored signalas/saved in memory.

Code: [Select]
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
This is the way I wrote it in the code, sorry I could not copy&paste since it was on another computer. :)


I will try measuring on the RS485 side of the MAX485 instead, and compare the signals. brb :)

 

Offline bilko

  • Frequent Contributor
  • **
  • Posts: 405
  • Country: 00
Re: USART, PIC->ATmega
« Reply #10 on: May 09, 2011, 08:03:54 pm »
Also worth double checking you don't have your A and B lines crossed over on the RS485 side
 

Offline Spekkio

  • Regular Contributor
  • *
  • Posts: 94
  • Country: se
Re: USART, PIC->ATmega
« Reply #11 on: May 10, 2011, 12:40:59 pm »
I found the problem by measuring on the RS485 side instead, I should have done that from the start :)

the RE/DE (RE is inverted) pins can be connected together, it's connected to a digital output on the MCU to control the Receiver Output/Driver Input.
To tell the MAX485 to work as a receiver or a driver.

On the ATMega324P, I needed to put a small delay before setting a 0 to the RE/DE pins when the transmission of data is complete, to disable the transmitter and enable the receiver. I needed that delay because it seemed like the last bits of data was not transmitted.

I dont need to do that on the PIC though..

the code on the PIC to send data is

Code: [Select]
TXREG=data;
while(!TRMT);

on the ATmega324P

Code: [Select]
while( !(UCSR0A & (1<<UDRE0)));
UDR0=data;

I tried to set the while loop after the UDR0 instead, like in the PIC.
It waits til the transmission is complete. But I don't really understand how it works in the ATmega,
this code is directly from the datasheet.
 

Offline Spekkio

  • Regular Contributor
  • *
  • Posts: 94
  • Country: se
Re: USART, PIC->ATmega
« Reply #12 on: May 10, 2011, 01:00:34 pm »
And also, the ATMega was configured for 2 stop bits, and the PIC for one. So that's why it was an extra bit for every byte.

Thanks for all your help :)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7438
  • Country: nz
Re: USART, PIC->ATmega
« Reply #13 on: May 10, 2011, 02:51:21 pm »
Code: [Select]
while( !(UCSR0A & (1<<UDRE0)));
UDR0=data;

That delay should always be there, it waits for the buffer to be empty (incase its not).
Thats important so that you dont write data over older data thats still waiting to be sent.

Ive not checked the pic datasheet to confirm this, but i suspect you were getting confused between the two approaches of "waiting for transmit buffer to be empty" on avrs (something you want to do before sending)
and "waiting for transmit to complete" on pics (something you want to do after sending)
« Last Edit: May 10, 2011, 03:11:03 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf