Created
May 14, 2019 10:51
-
-
Save avr-programmierung/cc691ae9c56206b7630685cd5de027b0 to your computer and use it in GitHub Desktop.
ATmega88 @ 1MHz Tastenfeld
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
/* tastenfeld_01.c ATmega88 @ 1MHz */ | |
#include <avr/io.h> | |
#include <util/delay.h> | |
#include <avr/interrupt.h> // Einbinden der Headerdatei für Interrupts | |
/* ADC-Wertebereiche zu den gedrückten Tasten zuordnen */ | |
#define Taste_1 ((ADC_Wert >=168) && (ADC_Wert <=174)) | |
#define Taste_2 ((ADC_Wert >=89) && (ADC_Wert <=95)) | |
#define Taste_3 ((ADC_Wert >=0) && (ADC_Wert <=3)) | |
#define Taste_4 ((ADC_Wert >=185) && (ADC_Wert <=191)) | |
#define Taste_5 ((ADC_Wert >=113) && (ADC_Wert <=119)) | |
#define Taste_6 ((ADC_Wert >=22) && (ADC_Wert <=28)) | |
#define Taste_7 ((ADC_Wert >=202) && (ADC_Wert <=208)) | |
#define Taste_8 ((ADC_Wert >=131) && (ADC_Wert <=137)) | |
#define Taste_9 ((ADC_Wert >=46) && (ADC_Wert <=52)) | |
#define Taste_10 ((ADC_Wert >=218) && (ADC_Wert <=224)) | |
#define Taste_11 ((ADC_Wert >=150) && (ADC_Wert <=156)) | |
#define Taste_12 ((ADC_Wert >=70) && (ADC_Wert <=76)) | |
void Init_ADC (void) // Funktion zur Initialisierung der AD-Wandlung | |
{ | |
uint8_t x; | |
DDRC &= ~(1<<PC5); // PC5 = Eingang (ADC5) | |
ADCSRA |= (1<<ADEN); // ADC aktivieren | |
ADCSRA |= (1<<ADPS0)|(1<<ADPS1); // Prescaler = 8 | |
ADMUX |= (1<<REFS0)|(1<<REFS1); // Uref = Internal 1,1V | |
ADMUX |= (1<<MUX2)|(1<<MUX0); // ADC5 (PIN PC5) = ADC channel | |
ADMUX |= (1<<ADLAR); // Ausgabe linksbündig | |
DIDR0 |= (1<<ADC5D); // Digital Kanal ADC3 deaktivieren (spart Strom) | |
ADCSRA |= (1<<ADSC); // Start 1. ADC-Wandlung zum "Warmlaufen" des ADC | |
while (ADCSRA & (1<<ADSC)); // Auf Abschluss der Konvertierung warten | |
x = ADC; // Ergebnis der 1. AD-Wandlung in x speichern und verwerfen | |
} | |
void Init_INT0 (void) // Funktion zur Initialisierung von Interrupt 0 | |
{ | |
DDRD &= ~(1<<PD2); // PD2 = Eingang (INT0) | |
EICRA |= (1<<ISC01); // Int0 wird durch eine fallende Flanke ausgelöst | |
EIMSK |= (1<<INT0); // Ext. Int0 aktivieren | |
sei(); // Alle Interrupts aktivieren | |
} | |
volatile uint16_t ADC_Wert; | |
int main(void) | |
{ | |
DDRB |= 0xFF; // PORTB = Ausgang | |
Init_ADC(); // Funktion Init_ADC() aufrufen | |
Init_INT0(); // Funktion Init_INT0() aufrufen | |
while(1) | |
{ | |
/* Tasten zuordnen und Tastenwert am PORTB ausgeben */ | |
if (Taste_1) PORTB = 1; | |
else if (Taste_2) PORTB = 2; | |
else if (Taste_3) PORTB = 3; | |
else if (Taste_4) PORTB = 4; | |
else if (Taste_5) PORTB = 5; | |
else if (Taste_6) PORTB = 6; | |
else if (Taste_7) PORTB = 7; | |
else if (Taste_8) PORTB = 8; | |
else if (Taste_9) PORTB = 9; | |
else if (Taste_10) PORTB = 10; | |
else if (Taste_11) PORTB = 11; | |
else if (Taste_12) PORTB = 12; | |
else PORTB = 0; // Wenn nichts zutrifft... | |
ADC_Wert = 0; // ADC_Wert zurücksetzen | |
} | |
} | |
ISR (INT0_vect) // Einsprung der ISR für den ext. Int0 | |
{ | |
/***** 1. AD-Wandlung durchführen *****/ | |
ADCSRA |= (1<<ADSC); // Start ADC-Wandlung | |
while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten | |
ADC_Wert += ADCH; // Inhalt von ADCH in ADC_Wert aufsummieren | |
/***** 2. AD-Wandlung durchführen *****/ | |
ADCSRA |= (1<<ADSC); // Start ADC-Wandlung | |
while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten | |
ADC_Wert += ADCH; // Inhalt von ADCH in ADC_Wert aufsummieren | |
/***** 3. AD-Wandlung durchführen *****/ | |
ADCSRA |= (1<<ADSC); // Start ADC-Wandlung | |
while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten | |
ADC_Wert += ADCH; // Inhalt von ADCH in ADC_Wert aufsummieren | |
ADC_Wert = ADC_Wert / 3; // ADC Mittelwert von 3 Messungen bilden | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment