- Labornetzteil AliExpress         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 13 von 13

Thema: ADC-Werte mit Codeschnipsel

  1. #11
    Neuer Benutzer Öfters hier
    Registriert seit
    27.07.2006
    Beiträge
    15
    Anzeige

    E-Bike
    komischerweise hatten die defines mit channel 1 also pin0 wunderbar alleine funktioniert.

    Naja mein neuer Code is jetzt:

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <avr/signal.h>
    #include <string.h>
    #include <compat/deprecated.h>
    #include <inttypes.h>
    #include <myheader.h>
    
    #define SYSCLK 16000000
    
    
    void init(void);
    
    // Initialisierung
    void init(void)
    {
       DDRD= (1<<PD4) | (1<<PD5);   // PWM Pins als ausgang
       DDRC= (1<<PC6) | (1<<PC7);   // 6=Motor 1 Kanal 1    7= Motor 1 Kanal 2
       DDRB= (1<<PB0) | (1<<PB1);   // 0=Motor 2 Kanal 1    1= Motor 2 Kanal 2
       TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10);
       // 10 Bit Pwm, invertierend
       TCCR1B = (1<<CS11) | (1<<CS10);      // Prescaler 64
       OCR1A=1;         // Mindestzeit für PWM1
       OCR1B=1;         // Mindestzeit für PWM2
    
    }
    
    void warte(unsigned int ms) // Wartet um x ms
    { 
       unsigned int zaehler; 
        
       while (ms) 
       { 
          zaehler = SYSCLK / 20000; 
          while (zaehler) 
          { 
             asm volatile ("nop"); 
             zaehler--; 
          } 
          ms--; 
       } 
    }
    
    void R_Motor_r() // Rechter Motor rückwärts
    {
    sbi(PORTC,6);
    cbi(PORTC,7);
    }
    
    void R_Motor_v() // Rechter Motor vorwärts
    {
    sbi(PORTC,7);
    cbi(PORTC,6);
    }
    
    void R_Motor_s() // Rechter Motor stop
    {
    cbi(PORTC,7);
    cbi(PORTC,6);
    }
    
    void L_Motor_r() // Linker Motor rückwärts
    {
    sbi(PORTB,0);
    cbi(PORTB,1);
    }
    
    void L_Motor_v() // Linker Motor vorwärts
    {
    sbi(PORTB,1);
    cbi(PORTB,0);
    }
    
    void L_Motor_s() // Linker Motor stop
    {
    cbi(PORTB,1);
    cbi(PORTB,0);
    }
    
    uint16_t readADC(uint8_t channel) //Funktion um ADC-Wert auszulesen an Pin channel
    {
    	uint8_t i;
    	uint16_t result = 0;
    	
    	// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
    	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
    
    	// Kanal des Multiplexers waehlen
    	ADMUX = channel;
    	// Interne Referenzspannung verwenden (also 2,56 V)
    	ADMUX |= (1<<REFS1) | (1<<REFS0);
    	
    	// Den ADC initialisieren und einen sog. Dummyreadout machen
    	ADCSRA |= (1<<ADSC);
    	while(ADCSRA & (1<<ADSC));
    	
    	// Jetzt 3x die analoge Spannung and Kanal channel auslesen
    	// und dann Durchschnittswert ausrechnen.
    	for(i=0; i<3; i++) {
    		// Eine Wandlung
    		ADCSRA |= (1<<ADSC);
    		// Auf Ergebnis warten...
    		while(ADCSRA & (1<<ADSC));
    		
    		result += ADCW;
    	}
    	
    	// ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	
    	result /= 3;
    	
    	return result;
    }
    
    int main(void) // Main-Funktion, d.h. dass was der Roboter macht!
    {
    init();
    warte(2000);
    
    unsigned int r; // ADC-Wert für rechten Sensor
    unsigned int l; // ADC-Wert für linken Sensor
    
    for(;;)
    {
    
    r = readADC(0);	//Auslesen der analogen Spannungen an Pin 0
    l = readADC(1); //Auslesen der analogen Spannungen an Pin 1
    
    if (r>0 && r<32) // wenn schwarzer Untergrund
    R_Motor_v();
    
    if (r>=32) // wenn weißer Untergrund
    R_Motor_r();
    
    
    if (l>0 && l<32) // wenn schwarzer Untergrund
    L_Motor_v();
    
    if (l>=32) // wenn weißer Untergrund
    L_Motor_r();
    
    warte(10);
    }
    
    
    return 0;
    }

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Bei 16MHz solltest Du den Prescaler auf 128 stellen, also am Ende der Zeile noch ein | (1 <<ADPS0) dazu, sonst läuft der ADC zu schnell, er sollte unter 200kHz kommen.

    so schauts dann aus:
    Code:
       // Den ADC aktivieren und Teilungsfaktor auf 128 stellen
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1 <<ADPS0);

  3. #13
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Er hat mit Channel 1 begonnen auf Channel 2 geschaltet und konnte dann nicht mehr zurück.
    Dein Prog hat nur den Schönheitsfehler das du, wenn noch weiterer Code dazukommt, aufgrund der Warteschleifen timingprobleme bekommen wirst. Versuche mit Interrupts zu arbeiten und Timer, auch wenn es so jetzt klaglos funktioniert.

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

12V Akku bauen