| Author |
Message |
|
|
Posted: Sep 29, 2009 - 09:34 AM |
|

Joined: Feb 22, 2008
Posts: 64
|
|
|
|
|
|
|
Posted: Sep 29, 2009 - 09:39 AM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
magarcan wrote:
Anyone can help me??
OK, fix this:
Code:
// The chip is factory set to run on internal
// oscillator at 4 MHz so the value is 4000000UL
A piece of quartz will only cost you about $0.50
Failing that calibrate OSCCAL |
_________________
|
| |
|
|
|
|
|
Posted: Sep 30, 2009 - 12:38 AM |
|

Joined: Feb 22, 2008
Posts: 64
|
|
Price is not the problem. In my town is impossible to buy it, so I hace to buy througth Internet.
How can I calibrate OSCCAL??
Thank you very, very much. |
|
|
| |
|
|
|
|
|
Posted: Sep 30, 2009 - 09:10 AM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
How can I calibrate OSCCAL??
Well start by searching your datasheet for that term and see what it tells you about factory calibration and the values in the signature row that you can pick up and later program into OSCCAL to make the first step towards more accuracy. |
_________________
|
| |
|
|
|
|
|
Posted: Oct 15, 2009 - 11:49 PM |
|

Joined: Jun 14, 2009
Posts: 20
|
|
Hello,
First off, thanks for this wonderful tutorial. Here is the problem I'm having. I have an ADC pin reading a value and converting it to an 8 bit number. It is going in the variable ADCH I'm assuming. I'm then taking this value and using it for 8 bit PWM modulation, OCR2 = ADHC. That part of the program is working great. However, I have in my code
UDR = ADCH;
The output onto HyperTerminal is extremely precise, yet inaccurate. When the sensor seems to be reading a certain value (as I can tell from PWM output of an LED), it always outputs the same symbols to HyperTerminal, however it doesn't output a number between 1 and 255 which is what I want it to do. So I think its working correctly, I just don't know how to tell it to output an actual number instead of these ascii symbols? Anyone know? Thanks
-apc
Code:
OCR2 = ADCH;
if ( (UCSRA & (1 << UDRE))) // UDRE slot== 1 when the buffer is empty
{
UDR = ADCH;
}
Also,
I saw a great post by Clawson on page 5 I believe of this tutorial talking about how to print out characters. Just saying thanks for that post. I plan on using it for doing something like "The value of the sensor is X" in the future |
|
|
| |
|
|
|
|
|
Posted: Oct 15, 2009 - 11:52 PM |
|


Joined: Jan 23, 2004
Posts: 9830
Location: Trondheim, Norway
|
|
You're trying to print out the ASCII values associated with each ADC reading. Sending "34" by loading 34 into the UDR will actually send the character associated with decimal value 34 from the ASCII table (see www.asciitable.com). You need to use the "itoa" function in the avr-libc library to convert your decimal value into it's ASCII string equivelent, and then load each of those string bytes into the UDR register in turn.
- Dean  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Oct 16, 2009 - 01:28 AM |
|

Joined: Jun 14, 2009
Posts: 20
|
|
Thanks Dean, appreciate it.
You wouldn't happen to have any good references, i.e. as good as your tutorials, would you? |
|
|
| |
|
|
|
|
|
Posted: Oct 16, 2009 - 01:31 AM |
|

Joined: Nov 17, 2004
Posts: 13846
Location: Vancouver, BC
|
|
|
Quote:
You wouldn't happen to have any good references, i.e. as good as your tutorials, would you?
No need for a tutorial, just use itoa(). |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Oct 16, 2009 - 10:00 AM |
|


Joined: Jan 23, 2004
Posts: 9830
Location: Trondheim, Norway
|
|
Specifically:
The itoa function (Integer to ASCII) takes in three parameters; the input integer value, the output buffer and the radix (the number base - 16 for HEX and 10 for decimal). All you need to do is create a buffer large enough to hold the largest number of bytes the function will produce, plus one for the terminator.
Since you're loading only a 8-bit register into it, you've got an input range of 0 to 255. That means you'll need a buffer that can hold 4 bytes - three for the digits (up to 999) and one for the null terminator (so that you know where the end of the string is when you use the standard C string functions).
Code:
char buffer[4];
itoa(ADCH, buffer, 10); // Convert ADCH to an ASCII string, in decimal
char* bufferPos = &buffer[0]; // Make a pointer to our string
while (*bufferPos != 0x00) // Loop until null terminator found
{
while(!(UCSRA & (1 << UDRE))); // Wait until buffer empty
UDR = *bufferPos; // Load next string byte into the USART data register
bufferPos++; // Advance pointer to next string byte
}
That's not the best way of doing things (since the code blocks while the string is being sent) -- a better way would be to load the converted string bytes into a ring buffer, so that you can send them in order later as the USART becomes ready for each new byte. Still, that'll get you started.
- Dean
} |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Oct 16, 2009 - 04:37 PM |
|

Joined: Oct 16, 2009
Posts: 1
|
|
hello everybody, im working in serial transmision using a keyboard 4x4, i have this code and i have proved it in proteus but it doesnt work, it compiles perfectly in avrstudio 4. I still dont know what the problem is, if someone can help me to figure out. the keyboard routine works perfectly using a LCD, but it doesnt work using serial transmision...What is happening?.....im working with atmega 16
[code]
#include <avr/io.h>
#include <stdio.h>
#define USART_BAUDRATE 2400
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define F_CPU 1000000
#define teclado_PORT_OUT PORTB
#define teclado_PORT_IN PINB
#include <util/delay.h>
void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8 );
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR = data;
}
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
int main(void)
{
USART_Init(BAUD_PRESCALE);
unsigned char upperNibble, codigotecla, Tecla, i;
while(1)
{
upperNibble = 0xff;
for(i=0; i<4; i++)
{
_delay_ms(1);
teclado_PORT_OUT = ~(0x01 << i);
_delay_ms(1); //delay for port o/p settling
upperNibble = teclado_PORT_IN | 0x0f;
if (upperNibble != 0xff)
{
_delay_ms(20); //key debouncing delay
upperNibble = teclado_PORT_IN | 0x0f;
if(upperNibble == 0xff) goto OUT;
codigotecla = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));
while (upperNibble != 0xff)
upperNibble = teclado_PORT_IN | 0x0f;
_delay_ms(20); //key debouncing delay
switch (codigotecla)
{
case (0xee): Tecla = '0';
break;
case (0xed): Tecla = '1';
break;
case (0xeb): Tecla = '2';
break;
case (0xe7): Tecla = '3';
break;
case (0xde): Tecla = '4';
break;
case (0xdd): Tecla = '5';
break;
case (0xdb): Tecla = '6';
break;
case (0xd7): Tecla = '7';
break;
case (0xbe): Tecla = '8';
break;
case (0xbd): Tecla = '9';
break;
case (0xbb): Tecla = 'A';
break;
case (0xb7): Tecla = 'B';
break;
case (0x7e): Tecla = 'C';
break;
case (0x7d): Tecla = 'D';
break;
case (0x7b): Tecla = 'E';
break;
case (0x77): Tecla = 'F';
break;
default : Tecla = 'X';
}
USART_Transmit(Tecla);
OUT:;
}
}
}
} |
|
|
| |
|
|
|
|
|
Posted: Dec 09, 2009 - 06:02 PM |
|

Joined: Apr 27, 2009
Posts: 33
Location: Villa Alemana (Chile)
|
|
hi there, i copied the program to make the eco with the PC, i had to do some changes 'cause i was using the MEGA168, and when i compile the file , show me the next error:
avr-gcc -mmcu=atmega128 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT first.o -MF dep/first.o.d -c ../first.c
../first.c: In function 'main':
../first.c:27: error: 'ReceivedByte' undeclared (first use in this function)
../first.c:27: error: (Each undeclared identifier is reported only once
../first.c:27: error: for each function it appears in.)
make: *** [first.o] Error 1
Build failed with 3 errors and 0 warnings...
someone now what it means, i have to declare something ???
Atte.
Mánuel. |
|
|
| |
|
|
|
|
|
Posted: Dec 09, 2009 - 06:18 PM |
|

Joined: Apr 27, 2009
Posts: 33
Location: Villa Alemana (Chile)
|
|
Plop, i get the problem seeing another tutorial about interrupts XD!!! I just put below int main ... char ReceivedByte, but i don't get why wasn't working???
Atte.
Mánuel. |
|
|
| |
|
|
|
|
|
Posted: Dec 25, 2009 - 05:36 PM |
|

Joined: Sep 09, 2009
Posts: 4
|
|
Hello everyone,
I am able to send characters from AVR to Terminal but I have a problem sending it from PC to AVR when I try to echo the character. I don't know what's going wrong. Please can someone help me.
Code:
#include <avr/io.h>
void USART_Init(unsigned int baudrate) // UBRR Value not baudrate
{
// Set baud rate
UBRR0H = (unsigned char)(baudrate>>8);
UBRR0L = (unsigned char)baudrate;
// Enable receiver and transmitter
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);
}
void Usart_Tx(char data)
{
while (!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
char Usart_Rx(void)
{
while (!(UCSR0A & (1<<RXC0)));
return UDR0;
}
int main(void)
{
char c;
USART_Init(51); // Baud rate = 9600bps, 8MHZ, u2x=0
for (;;) // Main loop
{
c=Usart_Rx();
Usart_Tx(c);
} //End Main loop
return 0;
}
|
|
|
| |
|
|
|
|
|
Posted: Dec 25, 2009 - 05:41 PM |
|

Joined: Sep 09, 2009
Posts: 4
|
|
Also I am using ATmega1281 AVR to communicate with the PC. So the register configurations are done accordingly.
Thanks in advance. |
|
|
| |
|
|
|
|
|
Posted: Jan 24, 2010 - 01:02 PM |
|

Joined: Feb 16, 2008
Posts: 75
|
|
I have an oscillator that is 7.128Mhz. I am using an AtMega8. The table of baud rates and UBRR settings does not have an entry for this frequency. However, if I use the formula in the ATMega8 data sheet for determining error calculation:
Quote:
% Error = [(Baud Rate that matches most closely/Baud Rate) - 1] * 100
For 7.128Mz, closest matching baud rate is 9684.78 - I found this value on this site.
Plugging the values into the error calculation formula, I get a percentage error of approx 0.88%. It seems like that would be within the 2 -3% margin of error noted in this thread - given that my purpose it to experiment with Dean's tutorial.
Am I doing this calculation correctly? |
_________________ Russ
|
| |
|
|
|
|
|
Posted: Jan 24, 2010 - 01:46 PM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
I agree with your result. The calculation according to the datasheet is:
UBRR = ((fosc/(16 * baud)) - 1 ; for U2X=0
UBRR = ((fosc/(8 * baud)) - 1 ; for U2X=1
I make this:
(7128000/(16 * 9600)) - 1
(7180000/153600) - 1
45.40625 (U2X=0)
(7128000/(8 * 9600)) - 1
(7180000/76800) - 1
91.8125 (U2X=1)
So the closest you get is UBRR=45 (and the error comes from .40625) or UBRR=92 (and error comes from 0.1875)
Now work those values backwards through:
baud = fosc/(16or8 * (UBRR + 1))
baud = 7128000/(16 * (45 + 1))
or
baud = 7128000/(8 * (92 + 1))
baud = 7128000/736
baud = 7128000/744
baud = 9684.78 ; U2X=0
baud = 9580.65 ; U2X=1
So your 9684.78 calculated result is correct. To work out the error percentage the datasheet also gives the formula:
Err% = (close_baud/desired_baud - 1) * 100%
So:
Err% = (9685/9600 - 1) * 100% = 0.89% ; U2X=0
Err% = (9581/9600 - 1) * 100% = -0.20% ; U2X=1
Cliff |
_________________
|
| |
|
|
|
|
|
Posted: Jan 24, 2010 - 02:31 PM |
|

Joined: Feb 16, 2008
Posts: 75
|
|
To follow up, I am not sure that I follow the error calculation discussed by microcarl above:
microcarl wrote:
The only thing I would like to add is that, unless the microcontroller XTAL1, XTAL2 frequency is one of those "Magic Numbers", the final BaudValue will be a mixed number and be rounded down as, the final value of BaudValue must be an integer - the remainder will be lost.
If an XTAL value is used that produces a value of say, 48.1, the error produced by the trunkation of the fractional part, I.E. 0.1, will produce a Baud rate error just slightly greater then 2%. This error may well work without USART timing issues.
But, an XTAL frequency producing a final BaudValue of say, 48.2 or greater, will produce a BAUD rate timing error of more then 4%, which is outside of the +/-3% error margin specified by Atmel.
If 48.1 is rounded down to 48, doesn't that result in an % error of 0.2% rather than 2%? Similarly, wouldn't 48.2 -> 48 yield a 0.4% error, rather than 4%? |
_________________ Russ
|
| |
|
|
|
|
|
Posted: Jan 24, 2010 - 06:05 PM |
|

Joined: Nov 17, 2004
Posts: 13846
Location: Vancouver, BC
|
|
| Yes, it would be 0.2%, not 2%. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Feb 18, 2010 - 04:22 PM |
|

Joined: Dec 08, 2007
Posts: 25
Location: Sault Ste Marie, ON
|
|
I have followed this thread from page 1. It's been a great learning experience to see the potential pitfalls before I actually started to try using the USART feature of my AVR. I do have a problem that I haven't figured out yet. Maybe someone might see something that I am not seeing. Transmitting one character results in a different character being received. The received character does not change unless the transmitted character is changed. I'm sure this has to be a timing issue of some sort.
My board uses a 16.000MHz crystal. This AVR has no internal oscillator. Pages 36-44 in the ATMega128 reference manual describe clock divisors and such, but none are programmed in my case. The JTAG connector is removed after programming so as not to interfere with the USART operation.
All I am attempting to do is get my AVR to communicate like a loopback connector to HyperTerminal in Windows. I am using an ATMega128 (MAVRIC IIb board) with an Atmel JTAGICE MKII programmer. The code used is based on the examples provided in this thread. I believe the registers are correctly adjusted for the ATMega128.
There is a DB9 connector attached to the AVR as follows:
DB9 Pinout
Pin 2 (RD) to TX0 of AVR
Pin 3 (TD) to RX0 of AVR
Pins 4-6 (DTR-DSR)
Pin 5 (GND) to GND of AVR
Pins 7-8 (RTS-CTS)
HyperTerminal and the USB COM Port of my PC are configured to 38400 baud, 8N1 (8 bits / No Parity / 1 Stop bit).
When pin 2 and 3 of the USB COM Port are connected together in a loop-back fashion, the characters typed do echo back.
From HyperTerminal, in a full loopback form using the AVR as the loopback:
When 'f' is sent, '6' is looped back.
Then if I program the AVR as transmit only to HyperTerminal:
When '0' (zero) is sent, the omega character is returned.
The code shown has the receive section removed for now until I know I can reliably transmit a character from the AVR to HyperTerminal.
Code:
// Includes to make the code work
#include <avr/io.h>
// Defines / Declarations
#define F_CPU 16000000UL
#define USART_BAUDRATE 38400UL
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main (void)
{
// char ReceivedByte;
// Turn on the transmission and reception
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);
UBRR0L = BAUD_PRESCALE;
UBRR0H = (BAUD_PRESCALE >> 8);
for (;;) // Loop forever
{
// while ((UCSR0A & (1 << RXC0)) == 0)
// {
// };
// ReceivedByte = UDR0;
while ((UCSR0A & (1 << UDRE0)) == 0)
{
};
UDR0 = '0'; // This is hard coded for now
}
}
This should be very straight-forward. Any ideas on what I am overlooking? |
|
|
| |
|
|
|
|
|
Posted: Feb 18, 2010 - 06:23 PM |
|


Joined: Dec 30, 2005
Posts: 2327
Location: Fort Collins, CO USA
|
|
| Although it is not necessary (usually), if you are trying to initialize something like a USART, you should always do:
Code:
// Turn on the transmission and reception
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
instead of your
Code:
// Turn on the transmission and reception
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);
My way guarantees that the "unset" bits are all 0. Once you have done the first initialization, it makes more sense to do changes your way.
I also would do
Code:
UDR0 = 'U'; // This is hard coded for now
If you happen to have a scope, then this generates a square wave with the width of a half-wave equal to your baud rate.
-----------------------------------
You have already done some of the things below, but I will give you the standard "how to debug a UART" lecture:
1 - Check to be sure you have the right clock running. Run a simple "blink the LED" program where you have an expected delay - does the LED blink at the rate that you expect? If not, check the crystal and Clock fuses to be sure they are set correctly. This is the most common failure!
1.5: If you are running on the internal clock, you will have serious baud rate problems. The internal oscillator has a 10% accuracy (meaning it can be off by as much as 10%), while RS-232 must be under 2%. Not that the baud rate des not matter - if the internal oscillator is off, it is off and a slower baud rate won't help.
At anything over 38400 baud, you should use a crystal with a "magic" frequency (14.7456 MHZ, ...) that is evenly divisible by 2 to your baud rate. You cannot run 57600 baud with a 16 MHz crystal, at least not reliably.
2 - Check your output connections. Run a simple UART output program (no interrupts!) that sets up 8-bits, no parity, 1 stop bit, and sends a constant string of "U"s. A string of ASCII "U" will give you a square wave output with the bit width equal to your baud rate. Check the square wave with a scope - is it right? If you have an RS-232 converter, check both the inputs and outputs of the converter. If you can tie the output to a terminal emulator and you see the string of U's coming out, you're good.
3 - Check your input connections. Send a string of characters to the processor and run a simple program that simply toggles an LED when a character is received. Again, check the signal at the input to the processor - is it there? After that works, do another simple program that simply echoes characters back.
By the time you are through this procedure, you have gotten rid of 95% of the teething problems with UARTs.
Stu |
_________________ Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.
Newbie? Be sure to read the thread Newbie? Start here!
|
| |
|
|
|
|
|