Created
January 30, 2011 20:06
-
-
Save lrvdijk/803189 to your computer and use it in GitHub Desktop.
AVR USART Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Voltmeter based on atmega168, sends Analog2Digital conversion | |
* results over RS232 to the connected computer | |
* | |
* Created by Lucas van Dijk | |
* http://www.return1.net | |
*/ | |
#ifndef F_CPU | |
#define F_CPU 8000000 | |
#endif | |
#define FOSC 8000000 | |
#define BAUDRATE 9600 | |
#define UBRR (FOSC/(BAUDRATE<<4))-1 | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#include <stdint.h> | |
/** | |
* Called when USART completes receiving data | |
* | |
* It checks if there's no error, and if the character r is received, | |
* and ADC conversion is started | |
*/ | |
ISR(USART_RX_vect) | |
{ | |
// Called when data received from USART | |
// Read UDR register to reset flag | |
unsigned char data = UDR0; | |
// Check for error | |
if((UCSR0A & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) == 0) | |
{ | |
// No error occured | |
if(data == 'r') | |
{ | |
// Start ADC Conversion | |
ADCSRA = (1 << ADSC); | |
} | |
} | |
} | |
/** | |
* Called when the data register accepts new data | |
* | |
* When this occurs, we can write new data through the USART, | |
* and in this case we write the ADCH value. | |
*/ | |
ISR(USART_UDRE_vect) | |
{ | |
// Write ADC value | |
UDR0 = ADCH; | |
// Disable this interrupt | |
UCSR0B &= ~(1 << UDRIE0); | |
} | |
/** | |
* Called when the ADC completes a conversion. | |
* | |
* It enables the USART Data register empty interrupt, | |
* so when ready, the uC can send this value back to the computer | |
*/ | |
ISR(ADC_vect) | |
{ | |
static uint8_t i = 0; | |
UCSR0B |= (1 << UDRIE0); | |
i++; | |
if(i < 6) | |
{ | |
// Start a new conversion | |
ADCSRA = (1 << ADSC); | |
} | |
else | |
{ | |
i = 0; | |
} | |
} | |
void usart_init(uint16_t ubrr_value) | |
{ | |
UBRR0 = ubrr_value; | |
// 9600-8-E-1 | |
// That is, baudrate of 9600bps | |
// 8 databits | |
// Even parity | |
// 1 stopbit | |
UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0); // And enable interrupts | |
UCSR0C = (1 << UPM01) | (1 << UCSZ01) | (1 << UCSZ00); | |
} | |
void adc_init() | |
{ | |
// Setup ADC | |
// Enable left adjust a resolution of 8 bits is enough | |
// and select first ADC channel | |
ADMUX = (1 << ADLAR); | |
// Enable the ADC unit, and use a prescaler | |
// of 64 which gives us a fadc of 125kHz | |
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); | |
} | |
int main() | |
{ | |
// Setup USART | |
usart_init(UBRR); | |
// Setup ADC | |
adc_init(); | |
// Enable interrupts | |
sei(); | |
while(1) | |
{ | |
// Nothing to do here | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
where the ADC is interrupt mode is enabled.