Author Topic: Why oh why would a UART not be working?  (Read 4043 times)

0 Members and 1 Guest are viewing this topic.

Offline corrado33Topic starter

  • Supreme Robot
  • *****
  • Posts: 611
  • Helpful? 11
Why oh why would a UART not be working?
« on: July 23, 2011, 08:00:13 PM »
It's always something...

I set up my attiny4313 and mega8 for uart.  Running at 4MHz each, with a baud rate of 19.2k.  The loop back test works fine on both of them.

On the tiny4313 it just shows me zeros instead of what I actually sent... what's up with that?  It doesn't show anything if there is nothing being received.  (Or if what is received isn't a number) Should the variable being put into UDR and taken from UDR be chars, or ints?  Does it matter?

I'll post the code in a bit, I have to un-edit it, as I've messed with it a good bit...

Here's the code for the receiver, I'll spare you the long display function... This is on the tiny4313

Code: [Select]
int main()
{
int recieved_num=0,i; //Variables
DDRD &= ~0x01; //Set RX for input (Do I have to do this?)
//DDRD &= ~0x04; //I tried doing synchronous... still no luck this was for clock in
//DDRD |= 0x02; //Set TX for output (used it for loop back test)
UCSRC = 0x06; //Asynchronous, no parity, 1 stop bit, 8-bit char size
UBRRH = 0x00; //First part of baud rate... need value of 12 or 0x00C
UBRRL = 0x0C; //Second part of baud rate
UCSRB = 0x10; //Enable Reciever
display(888,500); //Just a test display, lets me know it's on
for(;;) //Infinite loop
{
while(!(UCSRA & 0x80)); //While recieve flag is not set...
recieved_num = UDR; //Get data in UDR
display(recieved_num,50); //Dispaly data
}
}

Transmitter code coming right up.  This is on the mega8
Code: [Select]
int main()
{
int i=0;
DDRD = 0x06; //Set TX for output (and blinker LED)
UBRRH = 0x00; //First part of baud rate (4 most sig. digits), need 12 or 0x00C
UBRRL = 0x0C; //Second part of baud rate (8 least sig. digits)
UBRRH = 0x80; //Set bit so I can access UCSRC
UCSRC |= 0x06; //Asynchronous, No parity, 1 stop bit, 8-bit char size
UCSRB = 0x08; //Enable Transmitter
pause(8000); //Pause to let the recieving chip come online
for(;;) //Infinite Loop
{
for(i=1;i<255;i++) //Wasn't sure how high of a number I could transmit..
{
while(!(UCSRA & 0x20)); //While data register is not empty...
UDR = i; //Put i into UDR
pause(2000); //Pause to let other MCU display number
}
}
}

What, oh what could I be doing wrong?  Chips are hooked together from Tx of the Mega to Rx of the tiny with a 2.2k resistor.  I just DON'T get it, I seem to be doing everything right, and it just doesn't work... I've messed with this thing on and off all day!  It's extremely frustrating that I can't figure this stupid thing out.  I can get both chips to communicate with the computer just fine, just not with each other...
« Last Edit: July 23, 2011, 08:22:26 PM by corrado33 »

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 99
Re: Why oh why would a UART not be working?
« Reply #1 on: July 24, 2011, 09:41:20 AM »
Try without the 2.2k series resistor on the TX & Rx lines. Or use a much smaller resistor value, like 22 Ohms.

Do you have a ground (common) between the two processors?

Since each works in loop-back and to a PC (Baud rate is correct) these are all I can think of.

Offline corrado33Topic starter

  • Supreme Robot
  • *****
  • Posts: 611
  • Helpful? 11
Re: Why oh why would a UART not be working?
« Reply #2 on: July 24, 2011, 11:54:33 AM »
Thanks waltr.

Yes I have a common ground between the MCUs.

Well, now that I think about it, it worked with the computer, but now how I would expect.

I sent it values of 1-254.  On the computer it displayed this... over and over again. (As long as I let it run).

Code: [Select]
‚ƒ€‚ƒ„…†‡„…†‡ˆ‰Š‹ˆ‰Š‹ŒŽŒŽ‘’“‘
’“”•–—”•–—˜™š›˜™š›œžŸœžŸ ¡¢£ ¡¢£¤¥¦§¤¥¦§¨©ª«¨©ª«¬ ®¯¬ ®¯°±²³°±²³´µ¶·´µ¶·¸¹º»¸¹
º»¼½¾¿¼½¾¿ÀÁÂÃÀÁÂÃÄÅÆÇÄÅÆÇÈÉÊËÈÉÊËÌÍÎÏÌÍÎÏÐÑÒÓÐÑÒÓÔÕÖ×ÔÕÖ×ØÙÚÛØÙÚÛÜÝÞßÜÝÞßàáâãàá
âãäåæçäåæçèéêëèéêëìíîïìíîïðñòóðñòóôõö÷ôõö÷øùúûøùúûüýþ üýþ

Now, one of my last threads dealt with this, but these characters don't match up to the ascii chart (like 49 does to '1').  So maybe something is going on there. 

I' going to try a smaller resistor now.

Offline corrado33Topic starter

  • Supreme Robot
  • *****
  • Posts: 611
  • Helpful? 11
Re: Why oh why would a UART not be working?
« Reply #3 on: July 24, 2011, 12:10:40 PM »
Ok, I'm starting from the very beginning, with easier to read code for people who don't feel like looking up hex values.

Code: [Select]
#include <avr/io.h>
#include "C:\\ReaperR.h"


int main()
{
PORT_OFF(DDRD,DDD0); //Make sure Rx is input
PORT_OFF(UCSRA,U2X); //Make sure double speed isn't activated
PORT_OFF(UCSRA,MPCM); //Make sure multiprocessor communication is off
PORT_OFF(UBRRH,URSEL); //Change URSEL so I can ccess UBRRH
UBRRH = 0x00; //Make sure they are all 0s
UBRRL = 0x19; //Set baud rate to 2400 at 1MHz osc.
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); //8 data bits
UCSRB = (1<<RXEN) | (1<<TXEN); //Enable Rx and Tx

DDRD = (1<<DDD2); //Enable D2 for output for blinker LED
PORTD = (1<<PORTD2); //Turn LED on initially

int i,rx_data;
for(;;)
{
for(i=32;i<127;i++)
{
while(!(UCSRA & 0x20)); //Wait until transmit buffer is empty
UDR = i; //Put i into UDR
if (UCSRA & 0x80) //If data recieved flag is set
{
rx_data = UDR; //Put recieved # into rx_data
if ((rx_data % 10 == 0) && (rx_data != 0)) //If number is divisible by 10 and is not 0
FLIP_PORT(DDRD,DDD2);
}
pause(500); //Pause so I can actually see the blinking.
}
}
}

This is my Mega8 loop back program.  It works.  I did the rx_data mod 10 so I could change the number and see if my blinking got more or less frequent.  I did this so I could actually see if what was being received was actually 32-127.  Make sense?  If I made it mod 5 the blinking would be faster, and if I made it mod 15 the blinking would get slower.  All of that worked.

Then I hooked it up to hyperterminal.  It outputs this.

Code: [Select]
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno
pqrstuvwxyz{|}~

Which makes sense.  Those are the ascii characters corresponding to 32-127.  Yay.  That same program when hooked up to the computer also turns the LED on and off when I send it '2'.  (50 is divisible by 10 and isn't 0).

Ok, I'm getting somewhere.  



EDIT:  So I've got it... kinda working.  The atmega sends 32-63 to the tiny4313 just fine.  But once it gets to 64, it skips to 192 ( I think).  Then it'll count up from there, sometimes it skips back to the lower number.  It does the same thing when I hook it to the computer.  I can send it '1' through whatever character a hex value of 63 is, but if I try to send it most letters, it gives me the higher number.  Also, while the atmega8 outputs to the computer just fine, the 4313 does not. 

I think it's noise.  I don't exactly have the solderless breadboard set up for eliminating noise.  And the 4313 is directly next to the display. It also could be overrun (atmega8 is sending more than one value before the 4313 can display it.)  But if it was that I'd assume I could make it display more numbers correctly by lowering the amount of time that I display the numbers.  But that didn't do anything...
« Last Edit: July 24, 2011, 05:48:22 PM by corrado33 »

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 99
Re: Why oh why would a UART not be working?
« Reply #4 on: July 24, 2011, 07:09:48 PM »
Yep, break it down and test each.
It could be noise but 19.2k Baud isn't that fast. You could try a slower Baud rate to see.
How long and the wires at TTL levels? Does it work better with shorter wires? Something else to try is to twist together the RX, TX and ground wires to reduces noise pickup.

It could still be a slight Baud rate mis-match. Have you checked the UART output bit timing of both processors with a scope?
Does the Tiny use an internal RC clock? Have you checked its accuracy?

Offline corrado33Topic starter

  • Supreme Robot
  • *****
  • Posts: 611
  • Helpful? 11
Re: Why oh why would a UART not be working?
« Reply #5 on: July 25, 2011, 02:41:20 PM »
Yep, break it down and test each.
It could be noise but 19.2k Baud isn't that fast. You could try a slower Baud rate to see.
How long and the wires at TTL levels? Does it work better with shorter wires? Something else to try is to twist together the RX, TX and ground wires to reduces noise pickup.

It could still be a slight Baud rate mis-match. Have you checked the UART output bit timing of both processors with a scope?
Does the Tiny use an internal RC clock? Have you checked its accuracy?

Well, when I restarted it I took it down to 2400 Baud, so that's not the reason.

Wires are pretty much a rats nest, so that could be a problem.  Also I thought I had .1uF caps, but I don't, I just have a bunch of pF ones.  However, when I put the biggest cap I have, 560 pF, on it it does get SLIGHTLY better.  It makes it to 67 instead of 63.  This is repeatable too.  I take it off and it's 63, put it on and it's 67.  

I can't try with shorter wires, but I can try to move the MCUs closer.  

I'm guessing it's a slight Baud rate mis-match.  Both are using the internal RC oscillator.  I don't have a scope (wish I did).  Would this be fixed by doing synchronous instead of asynchronous?  Hmmm, now that I think about it I did make a high level to low level converter for RCAs and I could probably use a scope on the computer through the audio in....  You make it output 'U' to check baud rate with a scope right?

The purpose of this circuit was a proof of concept.  It works, so now I can put it on my board (partially) designed to eliminate noise.  I may have to add an external clock or crystal to ensure accuracy.  The internal oscillator is only accurate to +-10% at 3V and room temp roughly.  That's not that good.  But it also says that it can be calibrated to +-2% at any Vcc and temperature.  **Googles how to calibrate MCU internal oscillator**

Maybe I'll try that.  Or maybe I'll just buy some sort of external clock source (crystal osc maybe) that doesn't vary with temperature since this could be on a bot an all.  Then I have to worry about protecting it... hmmmm..  Wow I got off topic.  

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 99
Re: Why oh why would a UART not be working?
« Reply #6 on: July 25, 2011, 07:21:49 PM »
If the cap is for the processor by-pass than you will need a least 0.1uF. Sounds like its time to order a variety of cap values or pull apart some old electronics and salvage some caps. For now try paralleling a number of the 560pF caps to see if things improve.

Yes an ASCII 'U' is 0x55 or 01010101b. So the Baud period is half the period of a rising to rising edge. Just remember that there is a Start and Stop bit.

Synchronous would not be sensitive to the processor's clock accuracy but requires a clock line from each transmitter thus you need four lines for bi-directional communication. I use synchronous for almost all serial between devces that are close together. It is also much easier to do high speed serial (10's of MHz) and/or isolation with synchronous.