I already said - usual problem - as your search no doubt confirmed (if you didn't spot FAQ#3 in my sig) that is that the AVR isn't running at the speed you think. It's probably about 1MHz rather than either 8MHz or 7.3MHz
Yes IF you have set the fuses correctly and attached an 8MHz crystal and cleared the CKDIV8 fuse (if there is one) then the AVR will be running at 8MHz and your UBRRL calculation based on F_CPU 8000000UL will work correctly. But my assertion is that you may have not succeeded with one of these things and the CPU maybe itn't running at the 8MHz you think. Try writing a program to flash an LED at a known rate. If it flashes at that rate (based on an F_CPU assumption) then the problem lies elsewhere but if it flashes at some other rate it maybe indicates that you haven't yet succeeded in getting the AVR running at 8MHz. This is usually the problem when people aren't getting UART comms working as expected.
Posted by prithvithephoenix: Sun. Dec 14, 2008 - 07:17 AM
1
2
3
4
5
Total votes: 0
n00b here , and this is my first post...
Anyways , i picked up ATmega 32 for interfacing motors to MATLAB , so that I can control PWM , etc using my computer.
The problem i'm facing is that in hyperterminal , i can receive characters from the microcontroller , but i can't send anything to it.
I set F_CPU to 1Mhz (1000000UL) , and baud as 2400.
Int. Osc 1mhz 6clk+64ms is selected in the fuse bits.
I'm using the exact same code given in the tutorial with minor modifications.
#include
#define USART_BAUDRATE 2400
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main (void)
{
char ReceivedByte;
int i=0;
UCSRB |= (1 << RXEN) | (1 << TXEN); // Turn on the transmission and reception circuitry
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
for (;i<10;1++) // Loop for printing chars
{
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = 'a'+i; // print chars from a.
}
for (;;) // Loop forever
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR
ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
}
in hyperterminal , I get the output abcdefghi , but after that , any characters that I type are ignored and are not echoed back.
I've tested loopback using a wire , and it works fine for all baud rates , databits,parity , etc.
I've been trying to solve this for the last 2 days , and i'm at my wits end now .. :(
all is fine so far but how can one write texts of strings of characters and display them on a screen.
is it?
Output the following please:
"Hello world"
or is it
printf "hello world"
etc.?
I tried this recipe:
#include
#include
#include
#include
#define F 4000000 /* oscillator-frequency
in Hz */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,FC) (F/(UART_BAUD_RATE*16l)-1)
size_t strlen (const char*);
void usart_putc(unsigned char c) {
// wait until UDR ready
while(!(UCSRA & (1 << UDRE)));
UDR = c; // send character
}
That's exactly what that program, as you have written it above, should do. You set i to be 0x40 (which is 64 in decimal). You then itoa() it with a radix of 10 (so will get it converted to "64" and then you uart_puts() the generated string.
If you want "Hallo world" then given the components you have written simply use either:
uart_puts(str1);
or
uart_puts("Hallo world");
If you wanted to wire up the output for printf() to your putc() routine so you could use:
printf("Hallo world");
you need to look at the way this is done in the avr-libc manual and specifically the stdio demo program
Hi all,
I got Following AVR Tutorial on " I copy the code given in tutorial-Using the USART with AVR-GCC " and paste it in AVR Studio 4.
I comipled it & I got these Errors:-
1)../UARTtry1.c:11: error: 'UCSRC' undeclared (first use in this function)
2)../UARTtry1.c:11: error: 'URSEL' undeclared (first use in this function)
3) ../UARTtry1.c:13: error: 'UBRRL' undeclared (first use in this function)
4)../UARTtry1.c:13: error: 'F_CPU' undeclared (first use in this function)
5)../UARTtry1.c:14: error: 'UBRRH' undeclared (first use in this function)
6)../UARTtry1.c:18: error: 'UCSRA' undeclared (first use in this function)
7)../UARTtry1.c:19: error: 'UDR' undeclared (first use in this function).
I have installed- "WinAVR-20080610-install".
I am new AVR.
Please tell me how to remove these errors.
What are you doing about defining F_CPU? Do you intend to use a #define or are you going to set it under Project Configuration (which would be better)? That would get rid of (4) above
As for all the other errors, which AVR is this? Do you #include at the top of the code? Have you set the right device type under Project Configuation?
If it's one of the AVRs with numbered UARTs (e.g. mega48/88/168/162/128/etc./etc.) then what are you doing about porting the register and bit name nomenclature? They don't have UDR (for example) they have UDR0 (and possibly UDR1)
Hi Cliff,
Thanks for your Hints. Now i am able to remove all the errors. But the program is not working.
I want to transmit 'a' on UART0. I am using ATmega128 & AVR Studio4. I don't get pulses at TXD0 pin on C.R.O.
Program control is remaining in -- " while (!(UCSR0A & (1 << UDRE0)) ) {}; " loop continuously.
What could be the problem?
int main (void)
{
char ReceivedByte;
ReceivedByte='A';
UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UCSR0B |= (1 << RXEN0) | (1 << TXEN0); // Turn on the transmission and reception circuitry
UCSR0C |= (1 << UMSEL0) | (1 << UCSZ00) | (1 << UCSZ01); // Use 8-bit character sizes
for (;;) // Loop forever
{
while (!(UCSR0A & (1 << UDRE0)) ) {}; // Do nothing until UDR is ready for more data to be written to it
UDR0 = ReceivedByte; // Echo back the received byte back to the computer
}
}
clawson wrote:
What are you doing about defining F_CPU? Do you intend to use a #define or are you going to set it under Project Configuration (which would be better)? That would get rid of (4) above
As for all the other errors, which AVR is this? Do you #include at the top of the code? Have you set the right device type under Project Configuation?
If it's one of the AVRs with numbered UARTs (e.g. mega48/88/168/162/128/etc./etc.) then what are you doing about porting the register and bit name nomenclature? They don't have UDR (for example) they have UDR0 (and possibly UDR1)
/* Set frame format: 8data, 2stop bit */
UCSR0C = 0x06;
/*Disabling the interrrupts*/
}
void usart_Tx( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR0 = data;
printf("%c",data);
}
unsigned char usart_Rx( void )
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) );
/* Get and return received data from buffer */
return UDR0;
}
i have written a program for send info from atmega 64 to hyper terminal and from hyperterminal to atmega64. but it is displying junk values even i have selected 115200,8,none,1,flow control also none.wt is the proble could u tell me please.
Posted by iamdjalkaline: Sat. Jan 24, 2009 - 05:24 PM
1
2
3
4
5
Total votes: 0
Thanks very much on the tutorial, I have been trying to get my MavricIB(atmega128), to communicate for days now, and just got it. I ordered it assembled and didn't realize they set the fuses in the factory to make it work at 16mhz by default, duh. Anyways, great tutorial, I learned A LOT, very appreciated!!! :lol:
Posted by kevintshaver: Sun. Feb 1, 2009 - 06:23 AM
1
2
3
4
5
Total votes: 0
Hi. I'm using an ATMega8 with a 16 MHz external crystal. I set the SUT_CKSEL to Ext. Crystal/Resonator High Freq. and I can get the tutorial code to work. It echos back the keys I hit. Now, I'm trying to get the value of OCR1A sent to the terminal. All I get though, is a repeating ZZZZZZZZZZZZZZZ. Any ideas?
For one thing, your buff[] is not big enough to hold the largest possible integer + null terminator. Try making it larger (you're probably clobbering your stack).
Posted by kevintshaver: Sun. Feb 1, 2009 - 06:19 PM
1
2
3
4
5
Total votes: 0
Thanks for the idea. I changed buff[4] to buff[10]. Now the output is changed, but still not what I would expect. I get output that constantly changes. For example, at one point it looked pretty close to this (some letters are extended ascii with tilde, umlaut and other symbols):
Sounds like you need to back up and try something simpler to figure out if your sendStream actually works. Try feeding it some known data (ie. "hello",5).
Posted by abcminiuser: Thu. Feb 5, 2009 - 01:04 AM
1
2
3
4
5
Total votes: 0
You're printing out a fixed number of characters, but the size of the data is variable -- in your "Test" example, the length of the string is 5 characters (four letters plus the NULL terminator) but you are forcing your sendStream function to send 10 characters. Five of those characters will be garbage, which is what you are seeing.
As all strings are NULL terminated, ommit the length parameter in your sendStream function and have it print the characters in the string until a 0x00 terminator byte is reached. That way, it will automatically always print the entire string so long as the data in the string buffer is shorter than the buffer length.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Ok, it looks like you've validated your sendStream (of course you told it to print more characters than you gave it, but that's ok). Now try to validate the itoa() part, by passing a known integer, ie. 1234. You're getting closer...
while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
What is the advantage of checking UDRE instead of checking TXC if data can be sent?
Shouldnt the result be the same even if TXC is checked?
Posted by abcminiuser: Wed. Apr 1, 2009 - 12:25 PM
1
2
3
4
5
Total votes: 0
TXC indicates that the transmission is complete, and is set once the UDR buffer is empty. However, the UDR register is double buffered, so that you can stuff a new byte in while the previous byte is still being sent.
Checking UDRE allows you to take advantage of the double buffer (as it triggers when there is space in the UDR buffer) while the TXC flag does not as it only triggers when all pending bytes have been sent.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
#include
#include
#include
#include
#define F_CPU 1000000UL
#define USART_BAUDRATE 4800
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main(void)
{
char recieveddata;
/* Enable Rx and Tx */
UCSRB |= (1<<RXEN) | (1<<TXEN);
/* Set no of bits to be Transmitted/recieved = 8 */
UCSRC |= (1<<UCSZ1) | (1<<UCSZ0);
/* Set the Baud Rate in UBRR Registers */
UBRRL = BAUD_PRESCALE; /* Load the Lower Bits of BAUD_PRESCALE */
UBRRH = (BAUD_PRESCALE >> 8); /* Load the Upper 8 Bits of BAUD_PRESCALE */
while (1);{
/* Recieve Data and Store in variable called "recieveddata" */
While ( (UCSRA & (1<<RXC)) == 0 ) ;{}
recieveddata = UDR;
/* Add 1 to the last recieved byte and transmit it back */
While ( (UCSRA & (1<<TXC)) == 0 ) ;{}
UDR = recieveddata +1;
}
}
I'm using a Parallel Programmer made by following the instructions here to program a attiny2313.
I have so far tried basic I/O operations on the tiny2313 with great success.
I'm interested in trying USART communication between a PC and a tiny2313.
If i take the above code , put it in WinAvr , use this makefile , will it be possible for me to do USART communication?
I am only interested in transferring a few bytes of data for proof of concept.
I'm running my tiny2313's as they are bought without any fuse changes or anything. I just plug in the parallel port cable and transfer the program.
So , based on what i've read , my tiny2313 will be operating at 8MHz/8 = 1MHz with the RC Oscillator.
So , i've chosen a baud rate of 4800 as to get the UBRR value as ~12.0
I read in your tutorial that RC oscillators cannot be used for USART communication.
which of the two do you actually mean?
1) It works , but the chances of error are high
2) it doesnt work at all.
Please do tell me if i can procceed trying with the RC Oscillator and if anything is wrong with my code...
What happens if the function results in a non-integer?
Will the non integer be loaded into UBRR?
Exactly. And when you read the Error% column in the UART baud tables in the datasheet it's a direct consequence of this. That's why the "magic crystals" are so good for use with UART as they have frequencies that are integer divisible by 300 exactly so all the 1200,2400,4800,9600,19200... and so on are always achievable with no rounding error and no Error% - hence their Error% column is full of 0.0%
Posted by mien_noodles: Wed. Apr 15, 2009 - 10:46 PM
1
2
3
4
5
Total votes: 0
Hi there, I thought people here should much be familiar with HyperTerminal stuff that's why I am posting my question here. Sorry if I got the wrong place.
I am doing a project that interfaces an ADS1252, ATmega644p. I would like to see/validate the data I have got from ADC on the computer. ADC is read using USART_set in_SPI mode. Another USART is connected to ICL232 chip and RS232 cable.
Data can be seen on oscilloscope but I am not sure if the data is accurate. So can you please tell me how to see it on HyperTerminal or even better on Excel?
My ADC has 24bits resolution, thus I am now receiving 3 bytes of data on UDR0 (data register of usart 0) and saved as Data[0..2]. I now transfer this data to UDR1 (data register of usart 1) to be transmitted through RS232 to be read on HyperTerminal.
The setting on my HyperTerminal is : Baud 57600, Data Length 8bits, Parity NONE, Stopbit ONE, and the last one (I don't remember what) as NONE. My uC has Fcpu of 2Mhz and according to the datasheet, the %error is 8.5%. I am not sure if this will much affect whatever I should be seeing on the HyperTerminal but at the moment, I am seeing NOTHING.
Do you know what problem I am facing now? Can anyone please advice if possible?
I am assuming that by firing up the ADC and uC, the data will "automatically" be displayed on the HyperTerminal window but I am pretty sure that my concept is wrong here. Can you tell me the proper procedure? Do I have to convert my data into ASCII or HEX as what I have read on forums? HOW? Do I convert it first before transmitting or the HyperTerminal will do it for me? Also, by streaming the data directly into HyperTerminal as what I am doing now, why don't I see anything like corrupted data or something like that?
Sorry if my questions sounds stupid but I really couldn't find any tutorials or information about interfacing uC, RS232 with HyperTerminal. Many thanks in advanced!!
p/s: also, a pseudo/ list of procedures of setting up HyperTerminal will be very much helpful :) (I don't even know which key to press to get it working a.k.a NOOB).
%error is 8.5%. I am not sure if this will much affect whatever I should be seeing on the HyperTerminal but at the moment, I am seeing NOTHING
Well there's your problem right there - UART requires on both ends having clocks running at almost exactly the same rate (the A in UART stands for Asynchronous after all). The clocks can drift out a little bit but once they get any more than about -2%..+2% they are then too far apart for communications to work. An error of 8.5% is fatal.
On a 2MHz CPU (assuming that is accurate) the baud rates you can use are 2400 (0.2%), 4800 (0.2%), 9600 (0.2%), 14400 (2.1% if U2X used), 19200 (0.2% if U2X used)
Even the 14400 in that is going to be "iffy".
You didn't say whether your 2MHz was quartz or RC. If quartz then those ARE the error rates you'll get. If it's the internal RC you can "tweak" it by adjusting OSCCAL (Oscillator Calibration) to get rid of those errors all together and possibly even bring other baud rates (such as 57600) into error% range. But to calibrate it you need some form of known timing signal to calibrate against. One possibility for that is actually the width of a UART bit which you could measure by running the RXD signal to an INT0 or ICP pin.
Your problem clearly isn't with Hyperterminal - it should "just work" - the only "gotcha" is to ensure that the setup includes having hardware flow control switched off.
Posted by mien_noodles: Thu. Apr 16, 2009 - 02:31 PM
1
2
3
4
5
Total votes: 0
Hi Cliff, thanks for having the patience to reply to my basic newbie questions!
I have tried 9600 but I received nothing on HyperT as well(with everything on HyperT setup correctly, flow control-NONE).
Well, I am using a prescalar to get 2Mhz but the OSCCAL option that you suggested is a bit too complicated for me to understand so I think I would like to opt that out.
I am not sure if it is the problem with my code. I tried using synchonise mode before but I couldn’t see any waveforms coming out on the oscilloscope. So I modified my code to make it async. I don’t know if there’s something I missed out during this modification – I changed the register, added in SREG |=(1<<7) to enable interrupt as told on the datasheet so that I can use Rx, Tx, Empty enables/flag enables. I am not sure if I need any XCK clock settings for this so I omitted that. Can you spot any mistakes in doing this?
//setup usart for rs232
void Setup_Usart(void)
{
//setup global interrupt in SREG
//requirement for Rx and Tx Enable
SREG |= (1 << 7);
//disable the reciever and transmitter
UCSR1B &=
~(
USART_CSR_B_Receiver_EN |
USART_CSR_B_Transmitter_EN
);
//set the Control status register B
UCSR1B =
0;
//set the Control status register C
UCSR1C =
USART_CSR_C_USART_NumStopBits(1) |
USART_CSR_C_USART_Parity_None |
USART_CSR_C_USART_ModeSelect_ASync |
USART_CSR_C_USART_CharSize_Max8(8) |
0;
//set the baud rate register Sync
UBRR1L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRR1H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
//enable the reciever and transmitter
UCSR1B |=
(
USART_CSR_B_Receiver_EN |
USART_CSR_B_Transmitter_EN |
USART_CSR_B_Data_Register_Interrupt_Empty_EN
);
};
That was for setup. Now this is the functions I called.
//function for reading data from adc using usart spi
void USARTSPI_ReadADS1252(void)
{
//declare 8bit WatchDRDY to detect DRDY mode
unsigned char WatchDRDy;
//Watch for Data ready
WatchDRDy = (PINC & 0x02 );
//if Data ready occurs, do nothing
while (WatchDRDy == (PINC & 0x02 ))
{
//do nothing
};
// make the whole delay to 22us to pass through the DRDY mode
_delay_us ( 4);
//PORTC0 = 0
PORTC ^= (1);
//Write to data register to initiate data transfer
//flush adc
UDR0= 0;
//Wait till you've received 8 bits
//Do nothing when Receive Complete Flag is ZERO ( means when it has not yet completely received data)
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
//Read the data
//UDR0 is the 8- bit USART Data Register
Data[2] = UDR0;
//flush register
UDR0 = 0;
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
Data[1] = UDR0;
//flush register
UDR0 = 0;
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
Data[0] = UDR0;
//interfacing with rs232
void USART_RS232_Interfacing(void)
{
//formula to mask and count 8 times
int Loop = (Loop + 1) & 7;
//at the 8th count, Loop will give 0
if ( Loop == 0 )
{
//get Data[] into another variable ToUsart1[]
ToUsart1[0] = Data[0];
ToUsart1[1] = Data[1];
ToUsart1[2] = Data[2];
}
//stream location counter initialisation
int streamLoc = 0;
//stream out data from ToUsart1[0..2]
while (streamLoc < 3)
{
// Do nothing until UDR is ready for more data to be written to it by checking register empty flag
while ((UCSR1A & USART_CSR_A_Data_Register_Empty_Flag ) == 0) {};
// Send out the byte value in the variable ToUsart[0..2] to data register of Usart_RS232
UDR1 = ToUsart1[streamLoc];
// increment stream location counter 0..2
streamLoc++;
}
};
Can you see any mistakes in the data sending flow?
I have just received a 1.8432MHz oscillator (Analog Electronics) this morning and I am wondering if I should try that one. If I were to be using external oscillator, do you think it will solve the problem or was it mistakes in my code?
Exactly - the options with UART are (a) spend ages fiddling about trying to get the calibration of the internal oscillator right or (b) use quartz and you are finished.
The only "gotchas" when you start using a crystal are (a) are CKSEL fuses set to enable it, (b) is CKDIV8 disabled (to prevent it being divided by 8), (c) have you got a MAX232 (or other signal inverter) between the AVR and the PC
But as you may know 1.8432MHz is one of the so called "magic crystal" because a property of its frequency is that it can be divided down to all the commonly used UART baud rates with a 0% error. Which is nice.
Posted by mien_noodles: Thu. Apr 16, 2009 - 04:42 PM
1
2
3
4
5
Total votes: 0
Right thanks. I wil try that later as I just found some other errors on my system.
With my ADC reading, I got nice and expected waveforms on oscilloscope. This is roughly how my code looks like.
]//function for reading data from adc using usart spi
void USARTSPI_ReadADS1252(void)
{
//declare 8bit WatchDRDY to detect DRDY mode
unsigned char WatchDRDy;
//Watch for Data ready
WatchDRDy = (PINC & 0x02 );
//if Data ready occurs, do nothing
while (WatchDRDy == (PINC & 0x02 ))
{
//do nothing
};
// make the whole delay to 22us to pass through the DRDY mode
_delay_us ( 4);
//PORTC0 = 0
PORTC ^= (1);
//Write to data register to initiate data transfer
UDR0= 0;
//Wait till you've received 8 bits
//Do nothing when Receive Complete Flag is ZERO ( means when it has not yet completely received data)
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
//Read the data
//UDR0 is the 8- bit USART Data Register
Data[2] = UDR0;
UDR0 = 0;
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
Data[1] = UDR0;
UDR0 = 0;
while ((USART_CSR_A_Receive_Flag & UCSR0A) == 0)
{
}
Data[0] = UDR0;
This works fine.
But when I include this USART_RS232_interfacing function after the adc reading function, I got waveforms that shows that my ADC is not reading data at the same intervals! (Time intervals between each "sample instant" are different). I don't know what the code has done to my system. Here is the code.
]//interfacing with rs232
void USART_RS232_Interfacing(void)
{
//formula to mask and count 8 times
int Loop = (Loop + 1) & 7;
//at the 8th count, Loop will give 0
if ( Loop == 0 )
{
//get Data[] into another variable ToUsart1[]
ToUsart1[0] = Data[0];
ToUsart1[1] = Data[1];
ToUsart1[2] = Data[2];
}
//stream location counter initialisation
int streamLoc = 0;
//stream out data from ToUsart1[0..2]
while (streamLoc < 3)
{
// Do nothing until UDR is ready for more data to be written to it by checking register empty flag
while ((UCSR1A & USART_CSR_A_Data_Register_Empty_Flag ) == 0) {};
// Send out the byte value in the variable ToUsart[0..2] to data register of Usart_RS232
UDR1 = ToUsart1[streamLoc];
// increment stream location counter 0..2
streamLoc++;
}
};
Both these adc read and rs232 functions are included in an infinite loop.
Not in a tutorial about the UART - if you have an ADC question ask it in AVR Forum - the discussion in threads here is just to discuss aspects of the tutorial being presented.
Posted by mien_noodles: Thu. Apr 16, 2009 - 11:49 PM
1
2
3
4
5
Total votes: 0
Hi zoro79, the AVR that you are using are very similar to what is on the tutorial. Just read the tutorial carefully and compare all the registers he used with your AVR32 datasheet.
Is there a function simlier to print_dbg_hex to read the USART on the AVR.
I know only usart_getchar function which is able to get one char. from the buffer but I don't know a way to convert a character to number.
In the words of Sesame street - "one of these things is not like the other" ;)
I change F_CPU in mi code an it neither works, any other idea??? thank you
It'll most likely be the standard problem then.
Any other can help me???
I already said - usual problem - as your search no doubt confirmed (if you didn't spot FAQ#3 in my sig) that is that the AVR isn't running at the speed you think. It's probably about 1MHz rather than either 8MHz or 7.3MHz
I'm not undertanding you (my english is'nt the best).
If I choose 8 MHz in fuses and my Vcc is 5V, my AVR sould be working with 8MHz, doesn't it???
Yes IF you have set the fuses correctly and attached an 8MHz crystal and cleared the CKDIV8 fuse (if there is one) then the AVR will be running at 8MHz and your UBRRL calculation based on F_CPU 8000000UL will work correctly. But my assertion is that you may have not succeeded with one of these things and the CPU maybe itn't running at the 8MHz you think. Try writing a program to flash an LED at a known rate. If it flashes at that rate (based on an F_CPU assumption) then the problem lies elsewhere but if it flashes at some other rate it maybe indicates that you haven't yet succeeded in getting the AVR running at 8MHz. This is usually the problem when people aren't getting UART comms working as expected.
I don't have attached any external crystal I tougth that if I choose fuse internal clock works at selected one.
Can I use USART with my internal clock??
I'll try to program LED trying to find mi actual frecuency. Do you know any other metod more exact???
Thanks for all!
n00b here , and this is my first post...
Anyways , i picked up ATmega 32 for interfacing motors to MATLAB , so that I can control PWM , etc using my computer.
The problem i'm facing is that in hyperterminal , i can receive characters from the microcontroller , but i can't send anything to it.
I set F_CPU to 1Mhz (1000000UL) , and baud as 2400.
Int. Osc 1mhz 6clk+64ms is selected in the fuse bits.
I'm using the exact same code given in the tutorial with minor modifications.
in hyperterminal , I get the output abcdefghi , but after that , any characters that I type are ignored and are not echoed back.
I've tested loopback using a wire , and it works fine for all baud rates , databits,parity , etc.
I've been trying to solve this for the last 2 days , and i'm at my wits end now .. :(
hope you could guide me in the right direction.
Hi there,
all is fine so far but how can one write texts of strings of characters and display them on a screen.
is it?
Output the following please:
"Hello world"
or is it
printf "hello world"
etc.?
I tried this recipe:
#include
#include
#include
#include
#define F 4000000 /* oscillator-frequency
in Hz */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,FC) (F/(UART_BAUD_RATE*16l)-1)
size_t strlen (const char*);
void usart_putc(unsigned char c) {
// wait until UDR ready
while(!(UCSRA & (1 << UDRE)));
UDR = c; // send character
}
void uart_puts (char *s) {
// loop until *s != NULL
while (*s) {
usart_putc(*s);
s++;
}
}
char *str1 = "Hallo World!";
char s [7];
int16_t i=0x40;
void init(void) {
// set baud rate
UBRRH = (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F)>>8);
UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F);
// Enable receiver and transmitter; enable RX interrupt
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
//UCSRB = (1<<
//asynchronous 8N1
UCSRC = (1 << URSEL) | (3 << UCSZ0);
}
int main(void) {
init(); // init USART
//sei(); // enable interrupts
// send initial character
while (!(UCSRA & (1 << UDRE)));
itoa(i,s,10);
uart_puts(s);
return 0;
}
But i get the number 64 on the screen.
How, what, where should I write to get "hello world"?
Thanks
hallo body.
I am not the best avr freak there is I am just a newbee.
but when I read you code I wonder about the for loop.
and you get.
a-i char total 9 and you ask i to be smaller than 10
I would try to change (;i<10;1++)to maybe (;i<20;1++)
goog luck
Hey , got another atmega16 , and the code works perfect on it , doesn't work with my old microcontroller , kinda weird , right ??
That's exactly what that program, as you have written it above, should do. You set i to be 0x40 (which is 64 in decimal). You then itoa() it with a radix of 10 (so will get it converted to "64" and then you uart_puts() the generated string.
If you want "Hallo world" then given the components you have written simply use either:
or
If you wanted to wire up the output for printf() to your putc() routine so you could use:
you need to look at the way this is done in the avr-libc manual and specifically the stdio demo program
Cliff
Hi all,
I got Following AVR Tutorial on " I copy the code given in tutorial-Using the USART with AVR-GCC " and paste it in AVR Studio 4.
I comipled it & I got these Errors:-
1)../UARTtry1.c:11: error: 'UCSRC' undeclared (first use in this function)
2)../UARTtry1.c:11: error: 'URSEL' undeclared (first use in this function)
3) ../UARTtry1.c:13: error: 'UBRRL' undeclared (first use in this function)
4)../UARTtry1.c:13: error: 'F_CPU' undeclared (first use in this function)
5)../UARTtry1.c:14: error: 'UBRRH' undeclared (first use in this function)
6)../UARTtry1.c:18: error: 'UCSRA' undeclared (first use in this function)
7)../UARTtry1.c:19: error: 'UDR' undeclared (first use in this function).
I have installed- "WinAVR-20080610-install".
I am new AVR.
Please tell me how to remove these errors.
Pra_kod
What are you doing about defining F_CPU? Do you intend to use a #define or are you going to set it under Project Configuration (which would be better)? That would get rid of (4) above
As for all the other errors, which AVR is this? Do you #include at the top of the code? Have you set the right device type under Project Configuation?
If it's one of the AVRs with numbered UARTs (e.g. mega48/88/168/162/128/etc./etc.) then what are you doing about porting the register and bit name nomenclature? They don't have UDR (for example) they have UDR0 (and possibly UDR1)
Cliff
Hi Cliff,
Thanks for your Hints. Now i am able to remove all the errors. But the program is not working.
I want to transmit 'a' on UART0. I am using ATmega128 & AVR Studio4. I don't get pulses at TXD0 pin on C.R.O.
Program control is remaining in -- " while (!(UCSR0A & (1 << UDRE0)) ) {}; " loop continuously.
What could be the problem?
#define F_CPU 8000000UL
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#include
#include
#include
int main (void)
{
char ReceivedByte;
ReceivedByte='A';
UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UCSR0B |= (1 << RXEN0) | (1 << TXEN0); // Turn on the transmission and reception circuitry
UCSR0C |= (1 << UMSEL0) | (1 << UCSZ00) | (1 << UCSZ01); // Use 8-bit character sizes
for (;;) // Loop forever
{
while (!(UCSR0A & (1 << UDRE0)) ) {}; // Do nothing until UDR is ready for more data to be written to it
UDR0 = ReceivedByte; // Echo back the received byte back to the computer
}
}
https://www.avrfreaks.net/index.p...
Stealing Proteus doesn't make you an engineer.
Hello! I want to know how to send a ADC result to the UART and see the result of the ADC conversion on the PC. Thanks
Yeah? So what have you got so far?
Stealing Proteus doesn't make you an engineer.
Thanks very much on the tutorial, I have been trying to get my MavricIB(atmega128), to communicate for days now, and just got it. I ordered it assembled and didn't realize they set the fuses in the factory to make it work at 16mhz by default, duh. Anyways, great tutorial, I learned A LOT, very appreciated!!! :lol:
Hi. I'm using an ATMega8 with a 16 MHz external crystal. I set the SUT_CKSEL to Ext. Crystal/Resonator High Freq. and I can get the tutorial code to work. It echos back the keys I hit. Now, I'm trying to get the value of OCR1A sent to the terminal. All I get though, is a repeating ZZZZZZZZZZZZZZZ. Any ideas?
For one thing, your buff[] is not big enough to hold the largest possible integer + null terminator. Try making it larger (you're probably clobbering your stack).
Thanks for the idea. I changed buff[4] to buff[10]. Now the output is changed, but still not what I would expect. I get output that constantly changes. For example, at one point it looked pretty close to this (some letters are extended ascii with tilde, umlaut and other symbols):
Sounds like you need to back up and try something simpler to figure out if your sendStream actually works. Try feeding it some known data (ie. "hello",5).
Good call. I like it. Here's what I get.
I got this output by changing two lines of sendStream code to
I used 10 to make sure I didn't "clobber my stack" as suggested above.
You're printing out a fixed number of characters, but the size of the data is variable -- in your "Test" example, the length of the string is 5 characters (four letters plus the NULL terminator) but you are forcing your sendStream function to send 10 characters. Five of those characters will be garbage, which is what you are seeing.
As all strings are NULL terminated, ommit the length parameter in your sendStream function and have it print the characters in the string until a 0x00 terminator byte is reached. That way, it will automatically always print the entire string so long as the data in the string buffer is shorter than the buffer length.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Ok, it looks like you've validated your sendStream (of course you told it to print more characters than you gave it, but that's ok). Now try to validate the itoa() part, by passing a known integer, ie. 1234. You're getting closer...
Can anyone suggest me the code with hardware flow control (using RTS and CTS)???
Thank you!
What is the advantage of checking UDRE instead of checking TXC if data can be sent?
Shouldnt the result be the same even if TXC is checked?
My blog : http://iamsuhasm.wordpress.com/t...
TXC indicates that the transmission is complete, and is set once the UDR buffer is empty. However, the UDR register is double buffered, so that you can stuff a new byte in while the previous byte is still being sent.
Checking UDRE allows you to take advantage of the double buffer (as it triggers when there is space in the UDR buffer) while the TXC flag does not as it only triggers when all pending bytes have been sent.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
I'm using a Parallel Programmer made by following the instructions here to program a attiny2313.
I have so far tried basic I/O operations on the tiny2313 with great success.
I'm interested in trying USART communication between a PC and a tiny2313.
If i take the above code , put it in WinAvr , use this makefile , will it be possible for me to do USART communication?
I am only interested in transferring a few bytes of data for proof of concept.
I'm running my tiny2313's as they are bought without any fuse changes or anything. I just plug in the parallel port cable and transfer the program.
So , based on what i've read , my tiny2313 will be operating at 8MHz/8 = 1MHz with the RC Oscillator.
So , i've chosen a baud rate of 4800 as to get the UBRR value as ~12.0
I read in your tutorial that RC oscillators cannot be used for USART communication.
which of the two do you actually mean?
1) It works , but the chances of error are high
2) it doesnt work at all.
Please do tell me if i can procceed trying with the RC Oscillator and if anything is wrong with my code...
My blog : http://iamsuhasm.wordpress.com/t...
(1)
What happens if the function results in a non-integer?
Will the non integer be loaded into UBRR?
My blog : http://iamsuhasm.wordpress.com/t...
Exactly. And when you read the Error% column in the UART baud tables in the datasheet it's a direct consequence of this. That's why the "magic crystals" are so good for use with UART as they have frequencies that are integer divisible by 300 exactly so all the 1200,2400,4800,9600,19200... and so on are always achievable with no rounding error and no Error% - hence their Error% column is full of 0.0%
Cliff
Thanks for the tutorial Dean :)
Hello,
Does anyone knows how many devices could be connected on one UART Bus?
One device is the master, and the others are slaves.
Please advise!
Thanks in advance
Walid
Hi there, I thought people here should much be familiar with HyperTerminal stuff that's why I am posting my question here. Sorry if I got the wrong place.
I am doing a project that interfaces an ADS1252, ATmega644p. I would like to see/validate the data I have got from ADC on the computer. ADC is read using USART_set in_SPI mode. Another USART is connected to ICL232 chip and RS232 cable.
Data can be seen on oscilloscope but I am not sure if the data is accurate. So can you please tell me how to see it on HyperTerminal or even better on Excel?
My ADC has 24bits resolution, thus I am now receiving 3 bytes of data on UDR0 (data register of usart 0) and saved as Data[0..2]. I now transfer this data to UDR1 (data register of usart 1) to be transmitted through RS232 to be read on HyperTerminal.
The setting on my HyperTerminal is : Baud 57600, Data Length 8bits, Parity NONE, Stopbit ONE, and the last one (I don't remember what) as NONE. My uC has Fcpu of 2Mhz and according to the datasheet, the %error is 8.5%. I am not sure if this will much affect whatever I should be seeing on the HyperTerminal but at the moment, I am seeing NOTHING.
Do you know what problem I am facing now? Can anyone please advice if possible?
I am assuming that by firing up the ADC and uC, the data will "automatically" be displayed on the HyperTerminal window but I am pretty sure that my concept is wrong here. Can you tell me the proper procedure? Do I have to convert my data into ASCII or HEX as what I have read on forums? HOW? Do I convert it first before transmitting or the HyperTerminal will do it for me? Also, by streaming the data directly into HyperTerminal as what I am doing now, why don't I see anything like corrupted data or something like that?
Sorry if my questions sounds stupid but I really couldn't find any tutorials or information about interfacing uC, RS232 with HyperTerminal. Many thanks in advanced!!
p/s: also, a pseudo/ list of procedures of setting up HyperTerminal will be very much helpful :) (I don't even know which key to press to get it working a.k.a NOOB).
Mien
Well there's your problem right there - UART requires on both ends having clocks running at almost exactly the same rate (the A in UART stands for Asynchronous after all). The clocks can drift out a little bit but once they get any more than about -2%..+2% they are then too far apart for communications to work. An error of 8.5% is fatal.
On a 2MHz CPU (assuming that is accurate) the baud rates you can use are 2400 (0.2%), 4800 (0.2%), 9600 (0.2%), 14400 (2.1% if U2X used), 19200 (0.2% if U2X used)
Even the 14400 in that is going to be "iffy".
You didn't say whether your 2MHz was quartz or RC. If quartz then those ARE the error rates you'll get. If it's the internal RC you can "tweak" it by adjusting OSCCAL (Oscillator Calibration) to get rid of those errors all together and possibly even bring other baud rates (such as 57600) into error% range. But to calibrate it you need some form of known timing signal to calibrate against. One possibility for that is actually the width of a UART bit which you could measure by running the RXD signal to an INT0 or ICP pin.
Your problem clearly isn't with Hyperterminal - it should "just work" - the only "gotcha" is to ensure that the setup includes having hardware flow control switched off.
Hi Cliff, thanks for having the patience to reply to my basic newbie questions!
I have tried 9600 but I received nothing on HyperT as well(with everything on HyperT setup correctly, flow control-NONE).
Well, I am using a prescalar to get 2Mhz but the OSCCAL option that you suggested is a bit too complicated for me to understand so I think I would like to opt that out.
I am not sure if it is the problem with my code. I tried using synchonise mode before but I couldn’t see any waveforms coming out on the oscilloscope. So I modified my code to make it async. I don’t know if there’s something I missed out during this modification – I changed the register, added in SREG |=(1<<7) to enable interrupt as told on the datasheet so that I can use Rx, Tx, Empty enables/flag enables. I am not sure if I need any XCK clock settings for this so I omitted that. Can you spot any mistakes in doing this?
That was for setup. Now this is the functions I called.
Can you see any mistakes in the data sending flow?
I have just received a 1.8432MHz oscillator (Analog Electronics) this morning and I am wondering if I should try that one. If I were to be using external oscillator, do you think it will solve the problem or was it mistakes in my code?
Many many thanks!
Exactly - the options with UART are (a) spend ages fiddling about trying to get the calibration of the internal oscillator right or (b) use quartz and you are finished.
The only "gotchas" when you start using a crystal are (a) are CKSEL fuses set to enable it, (b) is CKDIV8 disabled (to prevent it being divided by 8), (c) have you got a MAX232 (or other signal inverter) between the AVR and the PC
But as you may know 1.8432MHz is one of the so called "magic crystal" because a property of its frequency is that it can be divided down to all the commonly used UART baud rates with a 0% error. Which is nice.
Right thanks. I wil try that later as I just found some other errors on my system.
With my ADC reading, I got nice and expected waveforms on oscilloscope. This is roughly how my code looks like.
This works fine.
But when I include this USART_RS232_interfacing function after the adc reading function, I got waveforms that shows that my ADC is not reading data at the same intervals! (Time intervals between each "sample instant" are different). I don't know what the code has done to my system. Here is the code.
Both these adc read and rs232 functions are included in an infinite loop.
Please advice. Thanks!
Not in a tutorial about the UART - if you have an ADC question ask it in AVR Forum - the discussion in threads here is just to discuss aspects of the tutorial being presented.
Hmmm ok sorry. I will start a new thread.
is there a similar tutorials for using the serial communication on AVR32 (EVK1100)?
Thanks
Hi zoro79, the AVR that you are using are very similar to what is on the tutorial. Just read the tutorial carefully and compare all the registers he used with your AVR32 datasheet.
Err...no..it isn't.
Unfortunately there are no tutorials for the AVR32.
Hi
I was wondering if you will be able to show me how to implement this USART Example on a AT90USB1287 device ?
Im using code vision.
Is there a function simlier to print_dbg_hex to read the USART on the AVR.
I know only usart_getchar function which is able to get one char. from the buffer but I don't know a way to convert a character to number.
Pages