Skip to content

Instantly share code, notes, and snippets.

@avr-programmierung
Created May 14, 2019 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avr-programmierung/cc691ae9c56206b7630685cd5de027b0 to your computer and use it in GitHub Desktop.
Save avr-programmierung/cc691ae9c56206b7630685cd5de027b0 to your computer and use it in GitHub Desktop.
ATmega88 @ 1MHz Tastenfeld
/* 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