Skip to content

Instantly share code, notes, and snippets.

@lrvdijk
Created January 30, 2011 20:06
Show Gist options
  • Save lrvdijk/803189 to your computer and use it in GitHub Desktop.
Save lrvdijk/803189 to your computer and use it in GitHub Desktop.
AVR USART Example
/**
* 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;
}
@sivaram3291
Copy link

where the ADC is interrupt mode is enabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment