ATMEGA 32A UART Question

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

I hope someone can help this frustrated newbie to correct my simple UART application.

I have an LCD that communicates at 2400 Baud to accept commands and characters serially. I have written (and borrowed) the code below that is supposed to set up the UART in the 32A and then allow the sending of data (I am not interested in receiving data right now).

The data sheet for the LCD indicates that a character 254 or FE is the prefix to a command being sent and that  1  is the command to clear the screen. (when the 254 is NOT sent then what is sent is a character to show on the LCD). I am communicating  at 8,n,1 2400 baud with an external 16MHz crystal with fuses correctly set. I am using Atmel Studio with usbtiny.

 

I wonder if someone could point out my errors in the program since nothing happens on the LCD when this is executed.  Many thanks.

 

#include <avr/io.h>

#define F_CPU 16000000UL                    // set the CPU clock

#include <util/delay.h>

#define BAUD 2400UL                           // define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)    // set baudrate value for UBRR

 

// function to initialize UART
void uart_init (void)
{
    UBRRH=(unsigned char)(BAUDRATE>>8);
    UBRRL=(unsigned char)BAUDRATE;                         //set baud rate
    UCSRB|=(1<<TXEN);   ///|(1<<RXEN);             //enable receiver and transmitter
    UCSRC|=(1<<URSEL);   //1 to write to UCSRC
    UCSRC|=(1<<UCSZ0)|(1<<UCSZ1);  //8 bit words
    UCSRC&= ~(1<<UPM1)|~(1<<UPM0);  //No Parity       THESE THREE STEPS PROBABLY NOT NEEDED
    UCSRC&=~(1<<UMSEL);    //Asynch mode
    UCSRC&=~(1<<USBS);     //= = 1 stop bit
    
    _delay_ms(1000);
}

 

 // function to send data
void uart_transmit (signed int x)  //transmit a 16 bit word
{
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x;                // load data in the register         
}

// main function: entry point of program
int main (void)
{
    _delay_ms(1000);
    uart_init();                                     // initialize UART
    _delay_ms(1000);                     
    
    uart_transmit (0xFE);           
    uart_transmit (0b00010001);     //The second 1 should show on the cleared screen
    
    _delay_ms(5000);
    
}

This topic has a solution.

David Abineri

Last Edited: Tue. Dec 5, 2017 - 02:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is your DIV8 fuse programmed? I don't remember if the Mega32a has that fuse

Jim

 

EDIT Mega32A does not have that fuse.

 

can you post a link to the LCD?

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Tue. Sep 26, 2017 - 12:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
    UCSRC|=(1<<URSEL);   //1 to write to UCSRC
    UCSRC|=(1<<UCSZ0)|(1<<UCSZ1);  //8 bit words
    UCSRC&= ~(1<<UPM1)|~(1<<UPM0);  //No Parity       THESE THREE STEPS PROBABLY NOT NEEDED
    UCSRC&=~(1<<UMSEL);    //Asynch mode
    UCSRC&=~(1<<USBS);     //= = 1 stop bit

Nope, that's not the way the URSEL bit works. You are writing to UBRRH actually, and because of that the baud rate is wrong.

 

Stefan Ernst

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

The way to start with UART comms is always to get the communication working with a terminal, or a terminal emulator on a PC.

 

Only when this shows that the communication is working well should you move on to the actual application.

 

How to properly post source code: http://www.avrfreaks.net/comment...

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

sternst wrote:
Nope, that's not the way the URSEL bit works.
As Stefan says you are doing that wrong. The URSEL bit must be written at the same time as any other bits in UCSRC so if you REALLY feel the need to use UCSRC then do:

 UCSRC= (1<<URSEL) |               //1 to write to UCSRC
        (1<<UCSZ0) | (1<<UCSZ1) |  //8 bit words
        (0<<UPM1)  | (0<<UPM0)  |  //No Parity       THESE THREE STEPS PROBABLY NOT NEEDED
        (0<<UMSEL) |               //Asynch mode
        (0<<USBS);                 //= = 1 stop bit

which is now just a single write to UCSRC. The 1 bit in URSEL says "the next 7 bits are to go to UCSRC not UBRRH even though they share the same location"

 

HOWEVER! When you apply power to a mega32 the value preloaded in UCSRC is the value for 8-N-1 because that's what almost everyone always wants to use. So you might want to ditch this completely and just accept the power on default.

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

By the way:

void uart_transmit (signed int x)  //transmit a 16 bit word
{
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x;                // load data in the register         
}

The comment is misleading. That routine only ever transmits 8 bits because UDR is an 8 bit register and the UART can only send 1 byte at a time. Either you want:

void uart_transmit (uint8_t x)  //transmit an 8bit byte
{
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x;                // load data in the register         
}

or if you really want a rouinte to transmit 16 bits at a time then something like:

void uart_transmit (unsigned int x)  //transmit a 16 bit word
{
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x >> 8;                // send uppper 8 bits of 16
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x & 0xFF;              // send lower 8 bits of 16
}

I would recommend unsigned int (actually better: uint16_t) rather than signed int (UDR knows nothing about sign bits). Also you might actually choose to do this as:

void uart_transmit (uint8_t x)  //transmit an 8bit byte
{
    while (!( UCSRA & (1<<UDRE)));            // wait while register is free
    UDR = x;                // load data in the register         
}

void uart_transmit16 (uint16_t x)  //transmit a 16 bit word
{
    uart_transmit(x >> 8);
    uart_transmit(x & 0xFF);
}

In all cases whether you send high byte (>> 8) followed by low byte (& 0xFF) or the other way round needs to be your choice of whether you want to use big endian or little endian.

 

Personally I doubt you ever want to send 16 bits anyway!

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

Many thanks for this, I appreciate the help.

David Abineri

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

So is your issue resolved?

 

IF so, please mark it as such - see: http://www.avrfreaks.net/comment...

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

Unfortunately these suggestions did not fix it.  The new code is attached , I wonder if you nee any errors? 

 

Are there any worthwhile free terminal programs for Win10 that I could use to test this program?

 

Thanks again,   Dave

Attachment(s): 

David Abineri

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

RealTerm

TeraTerm

KiaTerm

Putty

......

The list goes on....

 

Jim

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

Thanks, Jim

Dave

David Abineri

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

ki0bk wrote:
KiaTerm

What's that?

 

I'm finding loads of different meanings for "KIA" - but no terminal programs

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

Sorry, i think its keaterm

 

Update: Seems that one has been dead for a while! 

 

Jim

Last Edited: Fri. Sep 29, 2017 - 08:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone have any ideas about the error in the code I recently posted.  It seems correct and yet by using Putty on my PC, nothing is showing.  It is as if no data is being transmitted from the chip and I cannot see the error.  I have used printable characters like 0x41 etc and still nothing.

 

There must be an error in the code somewhere but I certainly don't see it!  Code attached.

 

Any advice?     Thanks,  Dave

Attachment(s): 

David Abineri

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

dabineri wrote:
There must be an error in the code somewhere 

​It could also be a hardware problem - broken and/or incorrect connections ...

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

clawson, Is there any chance you can look at by newly posted code?  You were very helpful previously but it is still not working.

 

Do you see the error?  It all looks correct to me but I am missing something!

 

Thanks thanks,

 

Dave

David Abineri

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

You can use your PC's sound card as an oscilloscope to measure the serial data. Google soundcard oscilloscope.
There is also some confusion as to what speed your AVR is operating at. Setting F_CPU just tells the compiler what speed you think the AVR operates at, it doesn't actually do anything to the hardware.
You can also flash a led at a given rate using the delay() functions. Any gross errors should be apparent.

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

Thanks, Kartman. I am now running at 1MHz and have flased an LED to confirm this but am not getting anything on Putty.

 

Is there an error in the code?

 

Thanks,

 

Dave

David Abineri

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

You may have more than one defect and it may not be the code. I'd be using the soundcard to look at what is being sent.
How are you getting the signal from the avr pin to putty? There's a few possibilities for error there alone.

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

I am using pin PD1 (pin15), the TXD pin. Is this correct?  It seems that nothing is being sent and I cannot see why this would be the case with this code.

 

Thanks for you help,

 

Dave

David Abineri

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

I am using pin PD1 (pin15), the TXD pin. Is this correct?

For DIP package yes but not for TQFP.

 

        uart_transmit (0xF);
	uart_transmit (0xE);
	uart_transmit (0x1);
	uart_transmit (0x65);

only one character is printable, the last one,  but the other 3 may mess up the terminal.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Sun. Oct 1, 2017 - 02:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see any PORT setup. TXD should be output.
.
MG

I don't know why I'm still doing this hobby

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

The uart takes over the ports - no need for ddr setup.

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

Kartman wrote:
The uart takes over the ports - no need for ddr setup.

My bad.
.
MG

I don't know why I'm still doing this hobby

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

js wrote:

I am using pin PD1 (pin15), the TXD pin. Is this correct?

For DIP package yes but not for TQFP.

 

        uart_transmit (0xF);
	uart_transmit (0xE);
	uart_transmit (0x1);
	uart_transmit (0x65);

only one character is printable, the last one,  but the other 3 may mess up the terminal.

 

The data sheet for the LCD indicates that a character 254 or FE is the prefix to a command being sent and that  1  is the command to clear the screen.

 

You need to send two characters to clear the screen,  0xFE and 0x01,  then give the LCD time to perform the clear screen operation, (delay at lease 100ms or more, see LCD DS)

before sending any other characters.

 

Jim

 

 

 

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

ki0bk wrote:
uart_transmit (0xF); uart_transmit (0xE);
ki0bk wrote:
The data sheet for the LCD indicates that a character 254 or FE

What would the latter 0xFE "command" have to do with your transmittal of a 0x0F byte and then a 0x0E byte?

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

theusch wrote:
What would the latter 0xFE "command" have to do with your transmittal of a 0x0F byte and then a 0x0E byte?

 

The OP was sending two characters 0x0F and 0x0E when (s)he should have sent a single character 0xFE, (s)he miss-understood the value of the command byte.

 

I have a similar LCD backpack, it will display normal ASCII characters, but for special commands, they are proceeded by a command escape character (in this case 0xFE) then a command value.

so to clear the screen you send <FE><01>.....

Sparkfun lcd backpack if IRC.

 

Jim

 

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

Jim, You are correct, I am using the LCD you describe that use a prefix FE, then 1 clears the screen, and 2 positions at home and then I print a couple  of characters.

 

I see nothing happen on the screen (which is filled with characters like a capital  A  all filled in).

 

This does not seem that it should be this difficult!  What am I missing?

 

My program is attached.  Any chance you would run this o your system with your LCD?

 

Many thanks,   Dave

 

Attachment(s): 

David Abineri

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

dabineri wrote:
Thanks, Kartman. I am now running at 1MHz and have flased an LED to confirm this but am not getting anything on Putty.

First have your code work with a terminal.

Only then test with LCD.

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

Visovian wrote:

dabineri wrote:

Thanks, Kartman. I am now running at 1MHz and have flased an LED to confirm this but am not getting anything on Putty.

First have your code work with a terminal.

Errr ... PuTTY is a terminal!

 

EDIT

 

However, it is possible (likely?) that a terminal - including PuTTY - would not "show" characters outside the standard printable range - like 0xFE and 0x01

 

So you need a "terminal" or some other debug utility that will display the raw hex byte values

 

I think RealTerm can do this:

enter image description here

 

Image from https://electronics.stackexchange.com/questions/38342/capture-raw-data-in-com-port - which discusses this

 

Last Edited: Tue. Oct 3, 2017 - 07:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But OP wrote he got nothing in putty.

 

Edit:

Maybe my English is not good enough.

I wanted to say:

First try the code in a terminal and after it works, test with Lcd

 

Last Edited: Tue. Oct 3, 2017 - 07:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Visovian wrote:
But OP wrote he got nothing in putty

Yes - to which you replied,

First have your code work with a terminal

So I just pointed out that PuTTY is a terminal; so he is already doing what you suggested - and I suggested in #4.

 

The problem here is that he is sending non-printing characters - so he needs to use a terminal that will display the raw hex values.

 

PuTTY is not such a terminal.

 

 

 

 

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

However, it is possible (likely?) that a terminal - including PuTTY - would not "show" characters outside the standard printable range

I think to test printable chars would be enough.

I do not see why uart would transmit printable right and others wrong. 

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

Quite possibly the non-printing characters could be interpreted by PuTTY to do something like clear the screen ...

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

There is some misunderstanding here.

 

Probably I should not write "your code" but

 

"First test the uart communication with a terminal ..." (which is usualy done with printable characters) 

 

Sorry.

 

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

But, at some point, the OP is still going to need to verify that the non-printing control codes are being sent correctly.

 

So it would make sense to start using a terminal that is going to be able to do that ...

 

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

Thanks for all the comments, guys!

 

Let me clarify.

 

I have tested Putty, it does receive data from another device I have.

I have tested that I am running at 1 MHz by flashing an LED.

I am only sending printable characters now (see attached program)

I am including delays in case there is a timing issue.

Putty shows NOTHING when I run this program

 

A question.  When I connect to Putty, I am using  pin PD1 (pin15), the TXD pin, of my DIP Atmega 32A and am connecting that pin to pin 3 of a female DB9. I am also connecting ground to pin 5 of the DB9.  I am assuming that those are the only connections I need for one-way communications to Putty.

 

What am I doing wrong in this simple program?  Thanks for all the help!   Program attached.

 

Dave

Attachment(s): 

David Abineri

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

dabineri wrote:
Putty ... does receive data from another device I have.

Sounds like you have a basic problem with your setup of PuTTY and/or the PC, then.

 

What is this "other device"?

 

I have tested that I am running at 1 MHz by flashing an LED.

That will tell you that you don't have a gross error - such as a factor of 2 or more - but will not reveal smaller errors that could still mean your baud rate is too far out to work ...

 

Do you have an oscilloscope to see what's actually happening on the wires?

 

EDIT

 

Please see #4 for how to properly post source code!

 

Please post a schematic showing how you are connecting to the PC - again, see #4 for instructions .

 

Photos of you setup could also help.

 

Last Edited: Tue. Oct 3, 2017 - 09:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dabineri wrote:
What am I doing wrong in this simple program?
dabineri wrote:
I am using pin PD1 (pin15), the TXD pin, of my DIP Atmega 32A and am connecting that pin to pin 3 of a female DB9.

??? You are connecting the AVR directly into a DB9 serial port on a PC?

 

If so, then that is probably an RS232 port.  So you need to connect your AVR to a transceiver...

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

dabineri wrote:
I am using  pin PD1 (pin15), the TXD pin, of my DIP Atmega 32A and am connecting that pin to pin 3 of a female DB9.
So you are connecting the ATmega with a RS-232 interface directly without any adapter in between? And you are connecting TxD with TxD?

 

Stefan Ernst

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

Please clarify if you would.

 

On the PC if have a Serial Port (COM Port) to USB adapter so I am sending the data into that DB9 connector as  described.  How should I connect the output from the Atmega 32A to the Com port?

 

Many thanks,

 

Dave

David Abineri

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

On the PC if have a Serial Port (COM Port) to USB adapter so I am sending the data into that DB9 connector as  described.  How should I connect the output from the Atmega 32A to the Com port? Please describe a transceiver  if you would.

 

Many thanks,

 

Dave

David Abineri

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

dabineri wrote:
Please clarify if you would.
First, the PC should receive what the Mega32 is sending, shouldn't it? So you have to connect TxD of the Mega32 to RxD of the COM-Port.

Second, the DB9 connector is a strong indicator that the COM-Port is of type RS-232, which uses different levels than the Mega32, so you have to use an additional level adapter. (or alternatively replace the USB adapter with a more appropriate one)

Stefan Ernst

Last Edited: Tue. Oct 3, 2017 - 10:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your google must be broken. I googled avr rs232 and found this:
https://www.swharden.com/wp/2009-05-14-simple-case-avrpc-serial-communication-via-max232/

You can get little boards from china that have the max232, connector and other bits. Most would just buy arduino clones in order to avoid the mistakes you’ve made.
Now you’ve got some keywords to google with, troll some of the problems a zillion others have had and see how you compare. If you’ve managed to zap your avr, then you’ve hit the trifecta.

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

Jim, When communicating with this backpack, am I supposed to be using RS232 levels or is it a direct connection from the atmega serial out to the back pack.

 

Perhaps this is my misunderstanding.  What is the backpack expecting in terms of signal levels.

 

Many thanks,

Dave

 

 

David Abineri

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

If it has a db9 connector it is most likely RS232. Thus you need a device like the max232 to do the level translation.

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

PROBLEM SOLVED.  The serial LCD that I am trying to communicate with expects an RS232 signal and not TTL from the Atmega. It is the BPI-216 serial LCD.

 

Thanks to all who helped, I should be able to solve this now.

 

Dave

 

David Abineri

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

dabineri wrote:
PROBLEM SOLVED.  The serial LCD that I am trying to communicate with expects an RS232 signal and not TTL from the Atmega. It is the BPI-216 serial LCD.

Not quite! It will accept a TTL signal happily, but it needs to be inverted.

 

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

dabineri wrote:
PROBLEM SOLVED

Then please mark the solutionhttp://www.avrfreaks.net/comment...

 

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

 

Kartman wrote:
It will accept a TTL signal happily, but it needs to be inverted

 

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

That picture (ie the text) is misleading. Sure it says "inverted-TTL" but it is immediately preceded by "RS-232". The latter suggesting +/-12V signalling. In fact I would have suggested that "RS232" and "TTL" are oxymoronic in this sense.

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

A common technique for a ‘RS232’ receiver was to use a zener diode, resistor and a ttl inverter. Not quite to spec, but worked in most cases. Similarly, you can use a ttl device to output ‘RS232’ for short distances.

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

I think what it's saying is that it will accept either TTL (unipolar) or RS232 (bipolar) levels.

 

RS232 transmitters are usually inverting - so, if you skip the transmitter, you still need to provide an inverter...

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

I've skipped through the thread, so maybe I'm repeating something already mentioned.

 

RS-232 is a physical interface standard.

In days gone by it was one of the two many I/O methods for PC's, (the other being the Centronics parallel interface).

 

RS-232 signal levels are:

0 = +3 to +15 V

1 = -3  to -15 V 

 

These are measured with respect to a common Ground connection between the two devices.

 

The -3 to + 3 V range is a no man's land, which improves the noise immunity and data integrity for the signal transmission.

 

In practice, many old RS-232 devices routinely used +/-12V, some original IBM printers and other devices used +/-15V.

 

When Laptops first starting hitting the market, and size, weight, and power consumption were an issue, many laptops clamped the negative signal to ground, and didn't bother generating a true negative voltage.

Because most devices used a "standard" RS-232 line driver chip set, (1488 and 1489, IIRC), and the receiver worked fine with the ground level replacing the negative level, it worked.

 

RS-232 inverts the signal.  But as one typically has an RS-232 chip driver on both ends of the connection, the signal polarity ends up "correct", (i.e. non-inverted).

 

TTL is typically 0 and 5 V levels.

 

So, if one "inverts" the signal, and uses 0/5 V signal levels, one could in fact call it  (pseudo) RS-232.

 

To drive the LCD it appears that one could use the USART module if one inverted the output pin polarity.

On the Xmega's this is a simple set the bit in the register process to invert the I/O pin's polarity.

One could easily do this in hardware with a 2N7000 and a 10K resistor.

This assumes one is only sending data to the LCD, and doesn't need to read data back out from the LCD.

One can often define the output signal polarity when using a software USART, also; which would be another option.

 

Again, without having read the entire Thread, it looks like the OP might simply have to connect "logic level" (i.e. 5V)  signals to the LCD, but INVERT the usual USART output.

 

JC

 

Edit:

Cross post with others who are less wordy than I am...

 

 

 

 

 

Last Edited: Wed. Oct 4, 2017 - 01:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So any device that accepts a converted TTL signal should be described as a device that accepts TTL?

 

Thanks,

Dave

 

 

David Abineri

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

A device which accepts 0/5 V (logic level) signals can generally be considered TTL compatible.

 

This doesn't take into account whether or not the signal was inverted somewhere along the data processing chain.

 

There are lots of "details" about specific switching thresholds and current drive capabilities, but for a simple analysis on your connectivity issue they aren't important.

 

JC

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

dabineri wrote:
any device that accepts a converted (sic) TTL signal

What the device sees needs to be a TTL-level signal; that is all - it neither knows nor cares if that signal has been "converted" from something else.

 

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

I am not sure why this is so difficult to do.  I have now purchased an LCD with serial backpack from AdaFruit.

 

It powers up as it should with the ADAFruit name etc.

 

I am using an ATMEGA 32A and am taking the output from pin 15 to the input of the backpack.

 

I then Build and Burn the attached program and I get repeated characters that look like the upper left corner  of a square and the lower right corner of a square outlining the 'square' where each character is supposed to show.

 

I cannot get any other characters to show.  Please let me know what I can try to get this thing working, it can't be this difficult. Code attached.

 

Many thanks,  Dave

Attachment(s): 

David Abineri

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

One million divided by 32 divided by 9600 equals? Convert the result to an integer. Reverse the calculation. You get a significant error.
The datasheet has a nice little table of frequencies and baud rates. In that table there is 1MHz and 9600 baud. It tells us the error is too great. This is why your code won’t work. There’s a bit called U2X. Set this bit and recalculate the baud rate divisor.
Note that using the internal oscillator may cause problems- its specified error can to be too large for serial comms. Use a crystal.
Also realise you’re probably the millionth person who has fallen for the same trap. Did you not Google? Or try an online baud rate calculator?

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

Can you post a link to the LCD you bought from ADA?

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

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

clawson wrote:
That picture (ie the text) is misleading. Sure it says "inverted-TTL" but it is immediately preceded by "RS-232".

Actually, my little red box highlighting is obscuring a slash between "RS-232" and  "inverted-TTL";  it actually says, "RS-232inverted-TTL" - which is, presumably, intended to mean, "works with both RS-232 and inverted TTL"

 

On the 'Hardware Reference' page, Seetron wrote:

Serial Input

BPI-216s accept inverted serial input, such as the output of an *RS-232 port. The direct output of a UART is noninverted; it is not compatible unless inverted (NOT gate). In some cases, workarounds exist to avoid the additional component:

  • Basic Stamp SEROUT instructions accept a parameter that inverts the output in software.
  • Arduino v1.0+ SoftwareSerial supports inverted output: SoftwareSerial(rxPin, txPin, 1); (where 1 sets inverted output).
  • PIC microcontrollers with the "enhanced" USART (EUSART) can be configured for inverted output by setting the SCKP bit of the BAUDCON register during USART initialization.

*RS-232 serial signals often use ±10V signals. These voltages will not harm the BPI-216, which has a protective "clamp" circuit on its serial input.

 

https://www.seetron.com/bpi216/b...

 

EDIT

 

Sorry, I got here via the OP's recent (now Locked) re-post of the same question - and missed the fact that there was another page of stuff after Cliff's comment!

 

blush

 

Last Edited: Mon. Dec 4, 2017 - 11:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim, My apologies for starting a new thread.  This one had diverged so much from my original question I thought it best to start again especially since I received no responses from here to my new question and I am using a different LCD now.

 

Thanks for setting me straight on this issue.  Is there any way that I can respond to those who had replied to the newer thread?

 

Dave

David Abineri

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

Thanks, Kartman, I am investigating these ideas now and had not found them elsewhere when googling. 

 

I appreciate your comments, Dave

David Abineri

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

I googled avr 1MHz 9600
Get a feeling of deja vu?

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

dabineri wrote:
Is there any way that I can respond to those who had replied to the newer thread

Simply copy what they posted there, paste it here as a quote, and reply ...

 

EDIT

 

Oh - and include a link.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman, Your suggestions worked and I have an LCD to which I can write now.

 

Thanks to everyone for your help. The problem seemed to be solved by using the U2X bit set for better accuracy at 9600 baud.  I will certaainly use an external oscillator but it is working on the internal clock for now.

 

Thanks again.   Dave

David Abineri

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

dabineri wrote:
This one had diverged so much from my original question I thought it best to start again especially since I received no responses from here to my new question and I am using a different LCD now.

Not really, and in post #58 you tell us that you bought a new LCD from Adafruit so there was no need to start a new thread.

 

dabineri wrote:
I thought it best to start again especially since I received no responses from here to my new question and I am using a different LCD now.

What do you call Posts # 59, 60 and 61?

 

dabineri wrote:
Is there any way that I can respond to those who had replied to the newer thread?

Your answer is:

awneil wrote:
Simply copy what they posted there, paste it here as a quote, and reply ...   EDIT   Oh - and include a link.

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

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

Kartman, As a newbie, I had no idea to look for a link between 1MHz and a baud rate of 9600. Why would I connect these two ideas?

 

Looking back now at what has been said, it is obvious that that might have been a good search.

 

I find that one of the values of a forum like this is to be pointed in the right direction.

 

But when just starting out it is very difficult to know what to search for you answer your particular problem.

 

Thanks again for your help.  Dave

David Abineri

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

dabineri wrote:
Kartman, As a newbie, I had no idea to look for a link between 1MHz and a baud rate of 9600. Why would I connect these two ideas?

As a newbie or experienced guru, you always need to confirm that your UART clock is appropriate for the desired baud rate.  On an AVR8, as you know, the UART clock is derived from the system clock, via UBRR (see the datasheet for the gory sampling details).

 

Pick an AVR clock speed -- any clock speed.  So you have your 123456Hz speed.  If you want to use that clock and UBRR and send stuff over a UART, you cannot pick just any bit rate, ans the error with the clock divider needs to be within certain limits for usable UART communications.

 

This is also gone through at some length in the datasheet.

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

what if you googled mega32 uart problems?

AVRs have been around for about 20 years now, so there's been plenty of others before you trying to do the same thing. Basically, any question you have about AVRs has already been asked and answered - maybe a zillion times. The popular ones are to do with fuses and uart - so much so that there are online tools to calculate fuse values and baud rates. Go and google them. There's also a wealth of tutorials that explain the basics so you can avoid the common problems.

 

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

dabineri wrote:
Kartman, As a newbie, I had no idea to look for a link between 1MHz and a baud rate of 9600. Why would I connect these two ideas?
I was going to say that the chapter on UART in the mega32 datasheet would have explained it but I just had a quick scan through and the only relevant thing I can spot right now is:

but as Lee noted the other day, although that says about entries being bold, they aren't!

 

The key thing about UART use is that it only works up to the point where the timing at either end differs by about 4%. That means there can be an error as great as 2% at either end. Baud rate combinations beyond that will most likely not work. It is a bit of a shame that the Atmel datasheets don't come right out and say this at the very start of the chapters about UARTs in each datasheet as the presence of FAQ#3 in my signature here is because this thing about baud errors is possibly one of the most talked about errors in the whole use of AVR. At this stage I must have read literally hundreds of threads attempting 9600 at 1MHz not realising that without U2X it is -7.0% and will not work. If Atmel had alerted users to the importance of the Error% in the datasheets it could have prevented a lot of problems!

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

If Atmel had alerted users to the importance of the Error% in the datasheets it could have prevented a lot of problems!

Or if people would do some basic electronics and programming courses......

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:

If Atmel had alerted users to the importance of the Error% in the datasheets it could have prevented a lot of problems!

Or if people would do some basic electronics and programming courses......

I'll almost always "up vote" Cliff's responses.  In this case, though, I cannot agree.

 

-- Some years back, there was a thread I remember where a poster opined that "important" stuff in the datasheet should be emphasized.  Bold, larger type, boxed, similar.  [IIRC the poster also did not like the number of datasheet pages -- wouldn't such emphasis take more space/more pages?]

 

My response at that time was for that poster to list for a datasheet section the information that was >>not<< important, and should thus not be emphasized.  The air waves became strangely quiet...

 

-- A datasheet chapter subsection is devoted to the gory details, and this subsection is linked in Cliff's quoted excerpt above.  Newbie or veteran, if there are questions about [in this case] an AVR peripheral subsystem I'd expect a good reading of the pertinent chapter.

I guess the first paragraph isn't dire enough to catch anyone's attention.  Not even phrases like "not able"?

 

Yes, as I dug out in the other thread Cliff mentioned, the claimed highlighting of near-perfect combinations seems to have been lost over the years in AVR8 datasheets.  But haven't we learned here that OP never looked at those tables anyway?

 

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

My first encounter with UARTs was at a time before micros were very popular, the UART was being clocked by CMOS logic and the data (switches status) was selected in with gates and latches.

 

This run Westmead hospital in western Sydney, (the largest in the southern hemisphere at that time) for decades, I guess the stuff may have upgraded by now cheeky.

 

So I learned the hard(ware) way about serial comms.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Lee, usually I'd agree completely and say that a datasheet is just to present the facts and not attempt to act as a tutorial but on this occasion just one sentence about the 2% limit could have prevented massive numbers of support queries.

 

(how Freudian, my word predicting keyboard on this tablet had typed "prevent" rather than "present" above. It must know Atmel datasheets!) 

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

clawson wrote:
just one sentence about the 2% limit could have prevented massive numbers of support queries.  

But only if people bothered to read it ...

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

clawson wrote:
but on this occasion just one sentence about the 2% limit could have prevented massive numbers of support queries.

Didn't I post a paragraph warning of gross discrepancies?

 

And there is a detailed section that follows that paragraph, with the math.

 

And...

awneil wrote:
But only if people bothered to read it ...

...for those people there is a picture.

Just one sentence, eh?  Like this one (in the paragraph following the tables):

There are two possible sources for the receivers baud rate error. The Receiver’s system clock
(XTAL) will always have some minor instability over the supply voltage range and the tempera-ture range. When using a crystal to generate the system clock, this is rarely a problem, but for a
resonator the system clock may differ more than 2% depending of the resonators tolerance. The
second source for the error is more controllable. The baud rate generator can not always do an
exact division of the system frequency to get the baud rate wanted. In this case an UBRRn value
that gives an acceptable low error can be used if possible.

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.