Reputation: 486
I'm trying to send a character 'a' with termite to my AVR via a USB-to-serial cable. This has worked before, but after a while atmel studio didn't show the controller as a device, I had to update atmel studio to a later version to recognize the controller. I probably changed the code somewhere along the way to try so I'm not sure if the code is correct anymore.
It's a really simple program for receiving the first char that arrives:
#include <avr/io.h>
#include "initialize.h"
#include "constantComfort.h"
char receivedchar;
void USART_receive_char(void){
/* wait for data to be received */
while( !(UCSR0A & (1<<RXC0)) );
receivedchar = UDR0;
}
int main(void)
{
init(0.5); //0.5 for interruptcycle in seconds
USART_receive_char();
writeLong(receivedchar,1);
}
The write-long can write 'a' as the ascii-code 97 if I insert it directly, but when I try to receive 'a' or other chars it just shows 0.
The initialization of the AVR looks like this, and I am pretty sure I have set the termite-program accordingly. 9600 BAUD, 8 data-bits, 1 stop-bit, no parity.
//USART (for Serial connection to computer)
#define F_CPU 1000000
#define BAUDRATE 9600 // 9600 bits/sec
#define BAUD ((F_CPU)/(BAUDRATE*16UL)-1) // from formula
/* enable USART0 module */
PRR = (0<<PRUSART0);
/* set baud rate to defined baudrate*/
UBRR0H = (BAUD>>8);
UBRR0L = (BAUD);
/* enable receiver and transmitter */
UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
/* set frame format: 8 data bits, 1 stop bit (always 1 start bit)*/
UCSR0C |= (0<<USBS0)|(3<<UCSZ00);
I am rather sure that this is all the code that affects this problem. I have gone through the manual for register names so I believe the initialization is correct.
Anyone have an idea what to do with this problem?
Upvotes: 2
Views: 1338
Reputation: 486
atmega169p has 8 MHz clock-frequency
I had read that in "low power consumption" mode the avr will have a clock-frequency of 1 MHz and somehow thought it was the default.
By default atmega169p has 8 MHz clock frequency without prescaling, so the baud calculation is wrong and I assume the avr didn't read fast enough because of this, thereby receiving '0'.
Correct code snippet:
//USART (for Serial connection to computer)
#define F_CPU 8000000 //>>>>>>>>>> THIS ONE! <<<<<<<<<<<<
#define BAUDRATE 9600
#define BAUD ((F_CPU)/(BAUDRATE*16UL)-1)
Changing to 8 MHz like in this code snippet solved my problem.
Thanks for the help with other potential problems in my code!
Upvotes: 1
Reputation: 9422
the code seems to be correct except
PRR = (0 << PRUSART0); // i think this does not work
instead try this
PRR &= ~(1 << PRUSART0);
then to enable the USART receive interrupt try this
#include <avr/interrupt.h>
#include <inttypes.h>
sei(); //global interrupt enable
UCSR0B |= (1 << RXCIEn); //USART receive interrupt enable (datasheet page 195)
ISR(USART_RXCn) (datasheet page 57)
{
//LED_on switch ON or OFF one of your leds if the receive interrupt is triggered by incoming data from termite
}
for the BAUD rate try this (datasheet page 176)
UBRRH0 = (unsigned char)(BAUD>>8);
UBRRL0 = (unsigned char)BAUD; // the type-casting to unsigned char
Upvotes: 2