also ich hab die berechnung der einzelnen stellen mit einer konstanten ausprobiert und sie funktioniert tadellos!
aber wie warte ich denn auf die konvertierung?
also ich hab die berechnung der einzelnen stellen mit einer konstanten ausprobiert und sie funktioniert tadellos!
aber wie warte ich denn auf die konvertierung?
in etwa so:
while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}
okay, danke an euch alle!!
ich habe den fehler gefunden! ich hatte ADATA im register gesetzt.
nun läufts.
Danke
Horsty
nabend euch allen,
heute war mal wieder bastelstunde, weil ich die letzten tage nicht so viel zeit hatte.
mit dem angepassten code funktionierte das ganze gut, allerdings nur einmal...
also das ganze dann irgendwie in eine schleife packen...
hier das ergebnis:
Kompiler sagt:Code:#define F_CPU 16000000UL #include <avr/io.h> #include <stdint.h> uint8_t y; int main(){ // port B und D werden als ausgang definiert DDRB = 0x1f; DDRD = 0xff; uint16_t AD(); if (y>=0){ uint8_t LED(); } else main(); } uint16_t AD(void) { //variablen uint16_t x; ADMUX |= (1<<REFS0); //AVCC als Referenzspannung wählen //Prescaler auf 128 einstellen und ADC aktivieren ADCSRA = (1<<ADPS0) | (1<<ADPS2) | (1<<ADEN); ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)){ ;//Konvertierung abwarten } x=ADC; // eingangswert wird der variable x übergeben y=x/4; // x wird durch 4 geteilt (von 10 auf 8 bit) } uint8_t LED(void){ int hunderter; int zehner; int einer; // ----- 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; } main(); //ende und neustart }
aber ich bekomm trotzdem nur 3 nullen angezeigt...Code:Build succeeded with 0 Warnings...
greetz horsty[/code]
Dein Controllertyp ist vermutlich (immer noch) geheim! ?
Bei meinen Atmelcontrollern gibts die Möglichkeit, den ADC gleich mit 8 Bit auszulesen. Das Stichwort heißt ADLAR.Zitat von horsty
Da lohnt es sich weiterzulesen.Zitat von Meine Doku
Hmmm, WENN Dein ADC auf Port B oder D liegt, dann liest Du über einen Ausgang ein. Darüber solltest Du nachdenken.Zitat von horsty
Ciao sagt der JoeamBerg
Das mit der Endlosschleife solltest du dir noch mal ansehen, die funktioniert so nicht.
Was rufst du mit main(); auf?
Ein else kannst du nicht alleine stehen lassen, da passiert nichts.
Für 8bit ADLAR verwenden und nur ADCH auslesen, hat "oberallgeier" ja schon geschrieben.
mein Controller ist ein Atmega32.
Mit main(); rufi ich am ende des programms wieder diese funktion auf.
Quasi eine Endlosschleife.
Und das mit dem ADLAR werde ich dann mal ausprobieren.
Ist das Programm denn sonst so korrekt?
greetz
horsty
Ob Dir mein Beispiel unten hilft, weiß ich nicht. Es läuft korrekt, aber eben NICHT auf einem m32 - ausserdem mit 10 bit (daher NICHT mit ADLAR), dummerweise auch noch mit einer Triggersource aus einer "fremden" Interruptquelle. Es sind zwei Bruchstücke: Initialisierung des Ports im main, initialisierung des ADC und die zugehörige ISR.
Viel ErfolgCode:/* >> Sicherung 10Okt09 1810 ..\C2\D01-3_40\D01-3_40x23.c =================================================================================== Target MCU : ATmega328 ... */ ... // ================================================================================= // === HAUPTProgramm ============================================================== // ================================================================================= int main(void) { ... // Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren // A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp ..... DDRC = 0b01110000; // PC3 ist ADC3, PC0 .. 6 , kein PC7-Pin bei m168 PORTC = 0b00000111; // Beachte für ADC: PC3 ist ADC-Eingang ##>> OHNE Pullup !! .... // ================================================================================ ----- o ----- o ----- o ----- o ----- o ----- o ----- o ----- o ----- o ----- /* >> Sicherung 15Sep09 2150 .\C2\D01-3_40\D01-3_40_gpd_x21.c ###>>> noch nicht =================================================================================== Target MCU : M168 .... ================================================================================ */ // ================================================================================= // === 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 } // ================================================================================= // ================================================================================= // === 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_sum += ADC; // Werte aufsummieren für Durchschnitt 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; PORTC ^= (1<<PC4); // Zeitmessung: Port PC4 toggeln } } // ================================================================================= // ================================================================================= // ===== ENDE Subroutinen ===================================================== // =================================================================================
Ciao sagt der JoeamBerg
Das geht so nicht. Das ist keine Endlosschleife, sondern eine Endlosrekursion, die den Stack überlaufen lässt.Zitat von horsty
War dir eine normale Schleife nicht cool genug?
MfG
Stefan
hallo,
das mit ADLAR war ein guter tipp!! danke
das ganze funktioniert jetzt auch soweit, allerdings wieder nur jeweils einmal. anscheinend funktioniert die schleife nicht....
Code:#define F_CPU 16000000UL #include <avr/io.h> #include <stdint.h> int main(){ //variablen int y; int hunderter; int zehner; int einer; // port B und D werden als ausgang definiert DDRB = 0x1f; DDRD = 0xff; ADMUX |= (1<<REFS0) | (1<<ADLAR); //AVCC als Referenzspannung wählen //Prescaler auf 128 einstellen und ADC aktivieren ADCSRA = (1<<ADPS0) | (1<<ADPS2) | (1<<ADEN); while (1){ ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)){ ;//Konvertierung abwarten } y=ADCH; // eingangswert wird der variable y übergeben // ----- 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; } } }
Lesezeichen