Hallo,
wie sage ich dem AD-Wandler welchen Kanal er als eingang nutzen soll??
hab dazu im avr-gcc-tuto nichts gefunden.
Danke
Horsty
Hallo,
wie sage ich dem AD-Wandler welchen Kanal er als eingang nutzen soll??
hab dazu im avr-gcc-tuto nichts gefunden.
Danke
Horsty
Bei den Atmegas und Tinies wird der ADC-Kanal im ADMUX-Register in den Bits 0,1 und 2 (MUX0-2)angegeben.
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Im Tutorial auf Mikrocontroller.net ist das auch noch mal beschrieben.
Just in case dass du noch weitere infos dazu brauchst
Vielen Dank schonmal.
Hatte das überlesen.
Stimmen die einstellungen im nachfolgenden code, wenn ich nur ADC0 als eingang nutzen möchte:
greetzCode:int16_t ad () { int8_t y; int16_t x; ADMUX |= (1<<REFS0); ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADSC) | (1<<ADPS2) | (1<<ADPS0); x = ADCW; y=x/4; }
horsty[/quote]
Wenn du noch sagst für welchen Kontroller das sein soll.
ADC0 wäre schon mal richtig.
Kommentare, zumindest bei den Registeranweisungen, würden das lesen sehr erleichtern. Selbst tust du dir auch leichter wenn du das in einem Jahr wieder liest. Wenn du nicht jeden Tag so etwas schreibst weisst du nicht mehr was die Zeilen sollen.
Hi Horsty,
manchmal wundere ich mich, mit wie wenig Kommentar man auskommen kann. Bei mir ist das viel mehr Schreibarbeit *kopfschüttel*. Für eine interruptgetriebene ADC-Erfassung auf Kanal ADC3 habe ich diese beiden Routinen in Betrieb. Wenn Du ADC0 haben willst, wird ADMUX entsprechend geändert. Die Angabe der Spannungsreferenz mit REFS2..0 ist sinnvoll, wenn Du nichts angibst, dann gilt nach Datenblatt "... VCC used as Voltage Reference, disconnected from PB0 (AREF) ...". Meine Angabe REFS0 ist kommentiert, genauer stehts im Datenblatt "... External Voltage Reference at PB0 (AREF) pin, Internal Voltage Reference turned off..." - hängt halt mit meiner Controllerbeschaltung zusammen. Für eine genauere Messung habe ich eine "Statistik" und nehme den Durchschnitt (arithmetisches Mittel ā) von 12 Messungen. WENN Du ein 8bittiges Ergebnis möchtest, dann musst Du entsprechend angepasst coden. Die Variablen sind alle extern und volatile deklariert.
Viel ErfolgCode:// ================================================================================= // === Initialisierung fuer ADC mega168 MIT Interrupt ======================== // === ADC3/PC3 auf 10 Bit, Wandlung #####>>>>> Interrupt ausgelöst ============= void ADC3_10_init_irupt(void) // { ADMUX |= (1<<MUX1)|(1<<MUX0); // Wandlung mit ADC3 ADMUX |= (1<<REFS0); // Referenzspannung ist Vcc doc S 256 ADCSRA |= (1<<ADATE); // Auto Triggering Enable doc S 247 + 257 ADCSRB |= (1<<ADTS1)|(1<<ADTS0); // Triggersource = TC0 CmpA doc S 260 // es wird also mit 1/1220 getriggert ca. 0,82 ms ADCSRA |= (1<<ADIE); // ADC Interrupt Enable doc S 258 ADCSRA |= (1<<ADEN); // AD Enable ADCSRA |= (1<<ADSC); // starte gleich die erste Wandlung adc3_cnt = 0; // ADC-Wert wird x-fach aufaddiert adc3_tmp = 0; // ADC-x-fach-Speicher } // ================================================================================= // ================================================================================= // === Nicht unterbrechbare ISR für ADC3 auf Pin 26/PC3/mega168 ================== // === Routine übernimmt ADC-Wert ============================================== ISR(ADC_vect) // _VECTOR(21) { adc3_tmp = ADC; // Hole Wert adc3_sum = adc3_sum + adc3_tmp; // ADC-Werte aufsummieren adc3_cnt = adc3_cnt + 1; // Hochzählen Counter für ISR-Aufruf if (adc3_cnt > 12) // Wenn Counter >= x, dann Messwert ausrechnen { // Wenn adc3_counter < x, dann keine Aktion adc3_dat = adc3_sum / 12; // Gemittelten ADC-Wert ausrechnen adc3_sum = 0; // adc3_sum und Counter rücksetzen adc3_cnt = 1; } } // =================================================================================
Anmerkung: uuuups - da war Hubert.G wieder schneller
Ciao sagt der JoeamBerg
vielen dank für die tipps!
mittlerweile scheint es u funktionieren, aber die 7-segment an der der wert ausgegeben werden soll, zeigt nur eine null an. (verzweiflung macht sich breit =) )
hier habe ich mal das gesamte programm:
wo liegt der da der fehler?Code:#define F_CPU 16000000 #include <avr/io.h> int16_t main () { // port B und D werden als ausgang definiert DDRA = 0x00; DDRB = 0x1f; DDRC = 0x00; DDRD = 0xff; //variablen int y; int hunderter; int zehner; int einer; int16_t x; ADMUX |= (1<<REFS0); ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADSC) | (1<<ADPS2) | (1<<ADPS0); x = ADCW; // eingangswert wird der variable x übergeben y=x/4; // x wird durch 4 geteilt (von 10 auf 8 bit) // ----- ab hier wird die 8-bit zahl auseinander genommen // die hunderter stelle hunderter=y/100; hunderter=hunderter%10; switch (hunderter) { case 1: PORTD |= (1<<PD3) | (0<<PD4) | (0<<PD5) | (0<<PD6); break; case 2: PORTD |= (0<<PD3) | (1<<PD4) | (0<<PD5) | (0<<PD6); break; // abschaltung der hunderter stelle bei kleineren zahlen durch schalten auf high default : PORTD |= (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6); break; } zehner=y/10; zehner=zehner%10; // abschaltung der zehner stelle wenn hunnderter und zehner gleich 0 ist if (hunderter==0 && zehner==0) { PORTB |= (1<<PB4); PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2); } else switch (zehner) { case 0: PORTB |= (0<<PB4); PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2); break; case 1: PORTB |= (1<<PB4); PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2); break; case 2: PORTB |= (0<<PB4); PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2); break; case 3: PORTB |= (1<<PB4); PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2); break; case 4: PORTB |= (0<<PB4); PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2); break; case 5: PORTB |= (1<<PB4); PORTD |= (0<<PD0) | (1<<PD1) | (0<<PD2); break; case 6: PORTB |= (0<<PB4); PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2); break; case 7: PORTB |= (1<<PB4); PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2); break; case 8: PORTB |= (0<<PB4); PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2); break; case 9: PORTB |= (1<<PB4); PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2); break; default: PORTB |= (1<<PB4); PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2); break; } // anzeige der einer stelle einer=y%10; switch (einer) { case 0: PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3); break; case 1: PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3); break; case 2: PORTB |= (0<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3); break; case 3: PORTB |= (1<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3); break; case 4: PORTB |= (0<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3); break; case 5: PORTB |= (1<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3); break; case 6: PORTB |= (0<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3); break; case 7: PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3); break; case 8: PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3); break; case 9: PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3); break; default: PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3); break; } return(0); //ende und neustart }
greetz
horsty
Du kannst nicht die AD-Wandlung starten, und dann sofort das Ergebnis auslesen. Du musst schon warten, bis die AD-Wandlung fertig ist.Zitat von horsty
MfG
Stefan
Der Fehler liegt in der Berechnung der einzelnen Stellen. So habe ich es gelöst. https://www.roboternetz.de/phpBB2/ze...ghlight=zehner
MfG Hannes
Und welcher soll das sein? Ich kann da keinen entdecken.Zitat von 021aet04
MfG
Stefan
Lesezeichen