Last update: 19.08.2006 | © 2024 Julian von Mendel | Datenschutz
/*
(C) 2010.08 jInvent Sofware Development (prog@jinvent.de)
License: LGPL3
ATMEGA168, 18.432 MHz, 9600 baud UART
Interface to ADC values
*/
#define F_CPU 18432000UL
#define BAUDRATE 9600
#define UART_UBRR_CALC(BAUD_, FREQ_) ((uint16_t)rround((FREQ_) / \
((BAUD_ / 2) * 16L) - 1, 0))
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <math.h>
float rround(float val, uint8_t digits) {
float v[] = { 1, 10, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8 };
return floor(val * v[digits] + 0.5) / v[digits];
}
uint8_t mutex = 0;
uint16_t steps = 0, flashes = 0, delay = 0, delay_steps = 0;
inline void time_init(void) {
TCCR2A = 0; /* normal operation mode */
TCCR2B = (1 << CS22); /* prescaler: clk/64 */
TIMSK2 = (1 << TOIE2); /* enable overflow interrupt */
}
#define TIMER_MSFACTOR (F_CPU / 64 / 256) / 1000
ISR (TIMER2_OVF_vect) {
if (++steps >= delay_steps) {
steps = 0;
mutex = 1;
}
if (++flashes >= 500 * TIMER_MSFACTOR) {
flashes = 0;
PORTD ^= (1 << PD4);
}
}
inline void uart_putchar(unsigned char character) {
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = character;
}
inline void uart_puts(char *data) {
while (*data) {
uart_putchar(*data);
data++;
}
}
inline inline void uart_puti(uint16_t integer) {
char buffer[6];
uart_puts(utoa(integer, buffer, 10));
}
inline unsigned char uart_getchar(void) {
if (!(UCSR0A & (1 << RXC0))) return 0;
return UDR0;
}
uint16_t adc(uint8_t admux) {
ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0);
ADMUX = admux;
ADMUX |= (1 << REFS1) | (1 << REFS0);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
uint16_t val = ADCW;
ADCSRA &= ~(1 << ADEN);
return val;
}
char channel = '1'; /* '1' to '6' on atmega168 */
inline void measurement(void) {
uart_puts("adc ");
uart_putchar(channel);
uart_puts(": ");
uart_puti(adc(channel - '1'));
uart_putchar('\n');
}
void setdelay(uint16_t d) {
delay_steps = (delay = d) * TIMER_MSFACTOR;
uart_puts("delay set to ");
uart_puti(delay);
uart_puts(" milliseconds.\n");
}
int main(void) {
uint8_t automeasure = 0;
char c;
/* UART */
UBRR0H = (uint8_t)(UART_UBRR_CALC(BAUDRATE, F_CPU) >> 8);
UBRR0L = (uint8_t)UART_UBRR_CALC(BAUDRATE, F_CPU);
UCSR0A = (1 << UDRE0) | (1 << U2X0);
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
/* LED */
DDRD = (1 << PD4);
/* timer */
time_init();
sei();
/* welcome */
uart_puts("adc measurement module (help with 'h')\n");
uart_puts(" (C) 2010 jInvent Software Development (prog@jinvent.de)\n");
setdelay(500);
while (1) {
/* user interface */
_delay_ms(1);
switch ((c = uart_getchar())) {
case 0: case 10: break;
case '1': case '2': case '3': case '4': case '5': case '6':
channel = c;
uart_puts("set channel: ");
uart_putchar(channel);
uart_putchar('\n');
break;
case 32: /* space key */
measurement();
break;
case 'a':
if ((automeasure = 1 - automeasure))
uart_puts("auto measurement activated.\n");
else
uart_puts("auto measurement deactivated.\n");
mutex = 0;
break;
case 'A': setdelay(5); break;
case 'B': setdelay(20); break;
case 'C': setdelay(50); break;
case 'D': setdelay(100); break;
case 'E': setdelay(200); break;
case 'F': setdelay(500); break;
case 'h':
default:
uart_puts("help:\n");
uart_puts(" 1 - 6: choose adc channel\n");
uart_puts(" space key: measure\n");
uart_puts(" a: toggle auto measurement\n");
uart_puts(" A - F: choose delay for auto measurement\n");
uart_puts(" 5ms -- 20ms -- 50ms -- 100ms -- 250ms -- 500ms\n");
}
/* auto measurement */
if (automeasure && mutex) {
mutex = 0;
measurement();
}
}
return 0;
}
© 2009 Julian von Mendel (http://derjulian.net) | Datum: 15.10.2024