Hallo,
nachdem nun mein LCD mit Peter Fleurys LCD libary läuft möchte ich gerne die Tasten des RN_Control an PINA7 abfragen und die Werte des ADC ausgeben. Die Ergebnisse sind aber unsinnig. Was ist falsch die Umwandlung oder die Bestimmung des Wertes?
und die Erhebung des Werts:Code:unsigned int taste = 0; char tastestr[5]; for(;;) { while(taste == 0) {taste = Tastenabfrage();} Soundirq (500,2000); lcd_clrscr(); itoa(taste,tastestr,5); lcd_puts (tastestr); Sleep (2000); Sleep (2000); taste = 0; }
kann jemand helfen?Code:unsigned int Tastenabfrage (void) { unsigned char i; unsigned char Tasternr = 0; unsigned int Tasteradc = 0; PORTA |= (1<<PA7); /* internen Pull-Up an PA7 aktivieren */ /* ADCSRA (ADC Control and Status Register ) Bit 7 6 5 4 3 2 1 0 ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA Read/Write R/W R/W R/W R/W R/W R/W R/W R/W Initial Value 0 0 0 0 0 0 0 0 ADEN enabeld (aktiviert) die AD- Wandlung ADSC (ADC Start Conversion) Mit diesem Bit wird ein Messvorgang gestartet. In der frei laufenden Betriebsart muss das Bit gesetzt werden, um die kontinuierliche Messung zu aktivieren. Wenn das Bit nach dem Setzen des ADEN-Bits zum ersten Mal gesetzt wird, führt der Controller zuerst eine zusätzliche Wandlung und erst dann die eigentliche Wandlung aus. Diese zusätzliche Wandlung wird zu Initialisierungszwecken durchgeführt. Das Bit bleibt nun so lange auf 1, bis die Umwandlung abgeschlossen ist, im Initialisierungsfall entsprechend bis die zweite Umwandlung erfolgt ist und geht danach auf 0. ADFR (ADC Free Running Select)(ADATE: ADC Auto Trigger Enable) Mit diesem Bit wird die Betriebsart eingestellt. Eine logische 1 aktiviert den frei laufenden Modus. Der ADC misst nun ständig den ausgewählten Kanal und schreibt den gemessenen Wert in das ADC Data Register. ADIE (ADC Interrupt Enable) Wenn dieses Bit gesetzt ist und ebenso das I-Bit im Statusregister SREG, dann wird der ADC-Interrupt aktiviert. ADPS2 bis ADPS0 Der Frequenzvorteiler kennt die Bits ADPS0 bis ADPS2 Dabei sollte die Frequenz für AD-Wandlung zwischen 50Hz und 200HZ liegen. Um den richtigen Vorteiler zu bestimmen teilt man die Freuquenz des Quarzes durch die gewünschte AD-Wandler Frequenz und setzt die Bits ADPS0 bis ADPS2. */ ADCSRA = (1<<ADEN) | (1<<ADPS2)| (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler hier: 128 /* ADMUX ADC Multiplexer Select Register Mit diesem Register wird der zu messende Kanal ausgewählt. Beim MEGA16/32 kann jeder Pin von Port A als ADC-Eingang verwendet werden (=8 Kanäle). (PA 0 bis PA7 und ADC0 bis ADC7) Das Register ist wie folgt aufgebaut: Bit 7 6 5 4 3 2 1 0 REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 Name - - - - - MUX2 MUX1 MUX0 R/W R R R R R R/W R/W R/W Initialwert 0 0 0 0 0 0 0 0 REFS1 REFS0 Diese Bits stellen die Spannungsreferenz für die ADC ein. Wenn diese Bits während der Umwandlung verändert werden, wird die Umwandlung nicht durchgeführt bis die Einstellung abgeschlossen ist (ADIF in ADCSRA is set). Die Einstelungsmöglichkeiten für die internen Refernzspannungen sollten nicht benutzt werden, wenn eine externe Refernzspannungen am AREF pin angelgt ist. REFS1 REFS0 Voltage Reference Selection 0 0 AREF, Internal Vref turned off 0 1 AVCC with external capacitor at AREF pin 1 0 Reserved 1 1 Internal 2.56V Voltage Reference with external capacitor at AREF pin Bit 5 – ADLAR: ADC Left Adjust Result Das ADLAR bit beeinflusst die Darstellung presentation des ADC Ergebnisser im ADC Datenregister. Wenn 1 in das ADLAR geschrieben wird, wird das Ergebnis linksbündig eingetragen. Ansonsten wird das Ergebnis rechtsbündig geschrieben. Die Veränderung des ADLAR Bits beinflusst das ADC Data Register sofort, ohne auf die laufende Umwandlung zu beachten. ADLAR = 0 Bit 15 14 13 12 11 10 9 8 – – – – – – ADC9 ADC8 ADCH ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 ADCL ADLAR = 1 Bit 15 14 13 12 11 10 9 8 ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADCH ADC1 ADC0 – – – – – – ADCL Mux4..0 Die Werte dieser Bits selects which combination of analog inputs are connected to the ADC. These bits also select the gain for the differential channels. See Table 84 for details. If these bits are changed during a conversion, the change will not go in effect until this conversion is complete (ADIF in ADCSRA is set). Die Bits MUX2...MUX0 werden für die einzelumwandlung Verwendet Mit diesem 3 Bits wird der zu messende Kanal bestimmt. Es wird einfach die entsprechende Pinnummer des Ports eingeschrieben. Wenn das Register beschrieben wird, während dem eine Umwandlung läuft, so wird zuerst die aktuelle Umwandlung auf dem bisherigen Kanal beendet. Dies ist vor allem beim frei laufenden Betrieb zu berücksichtigen. Meine Empfehlung ist deswegen klar diese, dass der frei laufende Betrieb nur bei einem einzelnen zu verwendenden Analogeingang verwendet werden sollte, wenn man sich Probleme bei der Umschalterei ersparen will. */ ADMUX = (0<<MUX4) |(0<<MUX3) |(1<<MUX2) | (1<<MUX1) | (1<<MUX0); /* Kanal waehlen hier Kanal 7 als single conversion */ ADMUX &= (0<<ADLAR); // Standard Ausrichtung ADMUX &= (0<<REFS1) & (0<<REFS0); // Referenzspannung an AREF nutzen /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */ ADCSRA |= (1<<ADSC); // eine ADC-Wandlung while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten /* Nun wird die eigentliche Messung durchgeführt */ /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ for(i=0;i<4;i++) { ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten Tasteradc += ADCW; // Wandlungsergebnisse aufaddieren /* ADCL,ADCH ADC Data Register Wenn eine Umwandlung abgeschlossen ist, befindet sich der gemessene Wert in diesen beiden Registern. Von ADCH werden nur die beiden niederwertigsten Bits verwendet. Es müssen immer beide Register ausgelesen werden und zwar immer in der Reihenfolge: ADCL, ADCH. Der effektive Messwert ergibt sich dann zu: x = ADCL; // mit uint16_t x x += (ADCH<<8); // in zwei Zeilen (LSB/MSB-Reihenfolge und C-Operatorprioritaet sichergestellt) oder x = ADCW; // je nach AVR auch x = ADC (siehe avr/ioxxx.h) */ } ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2) Tasteradc /= 4; // Summe durch vier teilen = arithm. Mittelwert return Tasteradc; }
Dnke
Gruß
Stefan
PS die Komentare stammen aus einem Tutorial das ich zum lernen und anpssen verwendet habe....







Zitieren

Lesezeichen