The attiny2313 has a built in UART for serial communication. You
need a few outside parts to allow it to communicate with a PC over a
serial connection. The attiny2313 uses TTL signals. You have to convert
them to true RS232 signals using an external converter. For this
example I will use a MAX232.
The AVR has an internal RC oscillator. The Atmel data sheet says
this oscillator is calibrated to within +- 10%. You may be able to get
a serial connection to work, but because of the margin of error it is
best to have your chip use an external watch crystal instead of the
internal RC oscillator. I have been successful in getting serial
communication to work using only the internal RC oscillator but your
mileage may vary.
Parts list:
1 MAX232IN ( mouser 595-MAX232IN)
4 16V 10uF capacitors ( mouser 140-MLRL16V10-RC)
1 3.6846 cyrstal
2 20pf capacitors
1 DB9 female serial connector
Below is the wireing schematic:
To get the AVR to use the external 3.6846 crystal instead of the
internal RC oscillator I had to burn the fuses. I am using linux and
avrdude, so I ran this command:
avrdude -p attiny2313 -P /dev/parport0 -c dt006 -u -U lfuse:w:0xed:m
Now the avr will only run with the external crystal.
First we look at the data sheet see what UBRRL needs to be set for
our baud rate and crystal. We will be transmitting at 2400 baud.
On the PC side I will be using minicom on a linux PC. Set minicom
(or hyperterminal on windows) to 2400 baud, 8N1. Minicom gave me a few
problems when it would first connect to the AVR. To get around this, I
would start minicom, then AFTER minicom was running, I would power up
the AVR. I am not sure why this happened. If I started minicom after
the AVR was powered up, I would get some garbage characters only.
This sample program will have the Avr listen for a character, then
transmit back the next highest character. So if you type in the letter
“B”, the avr will send be the letter “C”. (This program is written C
and should would with the gcc compiler)
The code may be downloaded here.
Code:
#include <avr/io.h>;
#include <avr/interrupt>;
/* Prototypes */
void InitUART (unsigned char baudrate);
unsigned char ReceiveByte (void);
void TransmitByte (unsigned char data);
/* --------------------------------------------------------------
Main - program that recieves a character then transmits back the next character.
An example would be if you send in an A, the chip will return a B
---------------------------------------------------------------- */
int main (void)
{
unsigned char i;
InitUART (95); /* Set the baudrate to
2400 bps using a 3.6846MHz crystal */
while (1)
{
TransmitByte (ReceiveByte () + 1);
/* Echo the received character + 1. Example send in A then send out B */
for (i = 0; i < 200; i++);
}
}
/* Initialize UART */
void
InitUART (unsigned char baudrate)
{
/* Set the baud rate */
UBRRL = baudrate;
/* Enable UART receiver and transmitter */
UCSRB = (1 << RXEN) | (1 << TXEN);
/* set to 8 data bits, 1 stop bit */
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
}
/* Read and write functions */
unsigned char
ReceiveByte (void)
{
/* Wait for incomming data */
while (!(UCSRA & (1 << RXC)));
/* Return the data */
return UDR;
}
void
TransmitByte (unsigned char data)
{
/* Wait for empty transmit buffer */
while (!(UCSRA & (1 << UDRE)));
/* Start transmittion */
UDR = data;
}
Resources used to make this howto:
http://www.booksbybibin.blogspot.com/ (has a great free ebook on AVR programming)
Avrfreaks design note #026 (also includes an alternate way to convert from ttl to rs232) http://avrfreaks.net/modules/FreaksFiles/files/405/DN_026.pdf
This artical is a copy of http://www.windmeadow.com/node/25 page.
need a few outside parts to allow it to communicate with a PC over a
serial connection. The attiny2313 uses TTL signals. You have to convert
them to true RS232 signals using an external converter. For this
example I will use a MAX232.
The AVR has an internal RC oscillator. The Atmel data sheet says
this oscillator is calibrated to within +- 10%. You may be able to get
a serial connection to work, but because of the margin of error it is
best to have your chip use an external watch crystal instead of the
internal RC oscillator. I have been successful in getting serial
communication to work using only the internal RC oscillator but your
mileage may vary.
Parts list:
1 MAX232IN ( mouser 595-MAX232IN)
4 16V 10uF capacitors ( mouser 140-MLRL16V10-RC)
1 3.6846 cyrstal
2 20pf capacitors
1 DB9 female serial connector
Below is the wireing schematic:
To get the AVR to use the external 3.6846 crystal instead of the
internal RC oscillator I had to burn the fuses. I am using linux and
avrdude, so I ran this command:
avrdude -p attiny2313 -P /dev/parport0 -c dt006 -u -U lfuse:w:0xed:m
Now the avr will only run with the external crystal.
First we look at the data sheet see what UBRRL needs to be set for
our baud rate and crystal. We will be transmitting at 2400 baud.
On the PC side I will be using minicom on a linux PC. Set minicom
(or hyperterminal on windows) to 2400 baud, 8N1. Minicom gave me a few
problems when it would first connect to the AVR. To get around this, I
would start minicom, then AFTER minicom was running, I would power up
the AVR. I am not sure why this happened. If I started minicom after
the AVR was powered up, I would get some garbage characters only.
This sample program will have the Avr listen for a character, then
transmit back the next highest character. So if you type in the letter
“B”, the avr will send be the letter “C”. (This program is written C
and should would with the gcc compiler)
The code may be downloaded here.
Code:
#include <avr/io.h>;
#include <avr/interrupt>;
/* Prototypes */
void InitUART (unsigned char baudrate);
unsigned char ReceiveByte (void);
void TransmitByte (unsigned char data);
/* --------------------------------------------------------------
Main - program that recieves a character then transmits back the next character.
An example would be if you send in an A, the chip will return a B
---------------------------------------------------------------- */
int main (void)
{
unsigned char i;
InitUART (95); /* Set the baudrate to
2400 bps using a 3.6846MHz crystal */
while (1)
{
TransmitByte (ReceiveByte () + 1);
/* Echo the received character + 1. Example send in A then send out B */
for (i = 0; i < 200; i++);
}
}
/* Initialize UART */
void
InitUART (unsigned char baudrate)
{
/* Set the baud rate */
UBRRL = baudrate;
/* Enable UART receiver and transmitter */
UCSRB = (1 << RXEN) | (1 << TXEN);
/* set to 8 data bits, 1 stop bit */
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
}
/* Read and write functions */
unsigned char
ReceiveByte (void)
{
/* Wait for incomming data */
while (!(UCSRA & (1 << RXC)));
/* Return the data */
return UDR;
}
void
TransmitByte (unsigned char data)
{
/* Wait for empty transmit buffer */
while (!(UCSRA & (1 << UDRE)));
/* Start transmittion */
UDR = data;
}
Resources used to make this howto:
http://www.booksbybibin.blogspot.com/ (has a great free ebook on AVR programming)
Avrfreaks design note #026 (also includes an alternate way to convert from ttl to rs232) http://avrfreaks.net/modules/FreaksFiles/files/405/DN_026.pdf
This artical is a copy of http://www.windmeadow.com/node/25 page.
4 comments:
It is easy to see that you are passionate about your writing.
Thank you for this tutorial it was really help full I used it in an atmega32p with small tweeks to enable dual USART communications at two different speeds. Interrupt driven usart routines will be also very helpful!. Xon/Xoff flow control is something that it been driving me nuts!, do you know where can i get a sample code? or where can i get a better idea of how to implement at Cool Gadgets?
i haven't used Xon/Xoff and thus don't have much idea. Please post the link to the artical that you found helpful for reference.
Such a great post. I have been reading and looking for some information and it is amazing and disturbing how many blogs related to the topic. Anyway your inputs for this subject are very interesting. Thank you for sharing this with us.
Post a Comment