- LiFePO4 Speicher Test         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 23

Thema: AD Kanal bestimmen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    24.04.2007
    Alter
    32
    Beiträge
    78

    AD Kanal bestimmen

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    wie sage ich dem AD-Wandler welchen Kanal er als eingang nutzen soll??
    hab dazu im avr-gcc-tuto nichts gefunden.

    Danke
    Horsty

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    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!

  3. #3
    shedepe
    Gast
    Im Tutorial auf Mikrocontroller.net ist das auch noch mal beschrieben.
    Just in case dass du noch weitere infos dazu brauchst

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    24.04.2007
    Alter
    32
    Beiträge
    78
    Vielen Dank schonmal.

    Hatte das überlesen.

    Stimmen die einstellungen im nachfolgenden code, wenn ich nur ADC0 als eingang nutzen möchte:
    Code:
    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;
    }
    greetz
    horsty[/quote]

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    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.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    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.
    Code:
    // =================================================================================
    // ===  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;                
      }      
    }           
    // =================================================================================
    Viel Erfolg

    Anmerkung: uuuups - da war Hubert.G wieder schneller
    Ciao sagt der JoeamBerg

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    24.04.2007
    Alter
    32
    Beiträge
    78
    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:
    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
    }
    wo liegt der da der fehler?

    greetz
    horsty

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von horsty
    wo liegt der da der fehler?
    Du kannst nicht die AD-Wandlung starten, und dann sofort das Ergebnis auslesen. Du musst schon warten, bis die AD-Wandlung fertig ist.
    MfG
    Stefan

  9. #9
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.058
    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

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von 021aet04
    Der Fehler liegt in der Berechnung der einzelnen Stellen.
    Und welcher soll das sein? Ich kann da keinen entdecken.
    MfG
    Stefan

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen