Skip to content

Instantly share code, notes, and snippets.

@lrvdijk
Created January 30, 2011 20:06
Show Gist options
  • Select an option

  • Save lrvdijk/803189 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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