logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega8][C][ADC]Dziwne błędy przetwornika ADC

ranger46 06 Lip 2009 19:51 2904 2
REKLAMA
  • #1 6746002
    ranger46
    Poziom 10  
    Mam problem z tym kodem (napisany przeze mnie więc przepraszam za ewentualne błędy estetyczne):
    /*
    1.Przyłóż czarny.
    2.Naciśnij przycisk 1.
    3.Przyłoż biały.
    4.Naciśnij przycisk 1.
    5.Jeśli chcesz skalibrować naciśnij przycisk 2.
    */
    #include <avr/io.h>
    #define F_CPU 1000000
    #include <util/delay.h>
    #include <avr/sleep.h>
    
    #define LED1_ON PORTB |= _BV(0)
    #define LED1_OFF PORTB &= ~(_BV(0))
    
    #define LED2_ON PORTB |= _BV(1)
    #define LED2_OFF PORTB &= ~(_BV(1))
    
    #define LED3_ON PORTB |= _BV(2)
    #define LED3_OFF PORTB &= ~(_BV(2))
    
    #define LED4_ON PORTB |= _BV(3)
    #define LED4_OFF PORTB &= ~(_BV(3))
    
    #define LED_OFF PORTB = 0
    
    #define wait _delay_ms
    
    
    int main(void){
    
    	// zmienne
    	
    	char L; // lewy sensor
    	char M; //srodkowy sensor
    	char R; //prawy sensor
    	
    	unsigned int licznik; // Zmienna do zliczania obiegów pętli
    	
    	unsigned int pomiarL; // Zmienna do przechowywania wyniku pomiaru
    	unsigned int pomiarM; // Zmienna do przechowywania wyniku pomiaru
    	unsigned int pomiarR; // Zmienna do przechowywania wyniku pomiaru
    	
    	unsigned int kalibracja; // zmienna do przechowywania sredniej z kalibracji
    	unsigned int pomiarK1; // pomiar do kalibracji
    	unsigned int pomiarK2; // ...
    	
    	DDRC=0x00; // Port jako wejścia
    	PORTC=0x00; // Wejścia bez podciągania
    	
    	DDRB=0xFF; // Port jako wyjścia 
    	PORTB=0x00; // Wyjścia w stanie wysokim
    	
    	DDRD = 0xFF; // zasilanie
    	PORTD = 0x05; // zasilanie
    		
    	// Wybranie wewnętrznego żródła napięcia odniesienia	
    	ADMUX |= _BV(REFS0);		
    	ADMUX |= _BV(REFS1);
    	//	Wybranie sposobu zapisu wyniku z wyrównaniem do lewej (osiem starszych bitów wyniku w rejestrze ADCH)	
    	ADMUX |= _BV(ADLAR);		
    	// Zezwolenie na konwersję	
    	ADCSRA |= _BV(ADEN);		
    	// Wybranie częstotliwości dla taktowania przetwornika   
    	ADCSRA |= _BV(ADPS0);	 
    	ADCSRA |= _BV(ADPS1);	
    	
    	for(;;){//pętla nieskończona
    	
    		while(bit_is_set(PINB, 6)){} // zabezpieczenie przed dublowaniem
    		
    		while(bit_is_clear(PINB, 6)){} // ...	
    		
    		if(bit_is_set(PINB, 6)){ // kalibracja czarnego
    		
    			// Ustaw do kalibracji czujnik nr.2		
    			LED1_ON; // zasygnalizuj diodą
    			wait(100); // wyeliminuj drgania styków
    			LED_OFF; // zresetuj port diód
    			
    			ADCSRA |= _BV(ADSC);     		    // Rozpoczęcie przetwarzania
    			while(bit_is_set(ADCSRA,ADSC)){};	 // Oczekiwanie na zakończenie przetwarzania
    			pomiarK1=ADCH;					     // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej
    			LED_OFF; // zresetuj port diód
    		}
    		
    		while(bit_is_set(PINB, 6)){} // zabezpieczenie przed dublowaniem
    		
    		while(bit_is_clear(PINB, 6)){} // ...
    		
    		if(bit_is_set(PINB, 6)){ // kalibracja bialego
    
    			LED2_ON; // zasygnalizuj diodą
    			wait(100); // wyeliminuj drgania styków	
    			
    			ADCSRA |= _BV(ADSC);     		    // Rozpoczęcie przetwarzania
    			while(bit_is_set(ADCSRA,ADSC)){};	 // Oczekiwanie na zakończenie przetwarzania
    			pomiarK2=ADCH;					     // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej
    			LED_OFF; // zresetuj port diód
    		}
    		
    		kalibracja=(pomiarK1+pomiarK2)/2; // oblicz wartosc dla sprawdzania koloru
    		
    		while(bit_is_set(PINB, 6)){} // zabezpieczenie przed dublowaniem
    		
    		// sprawdzanie czujników
    		
    		while(bit_is_clear(PINB, 7)){ // dopoki nie nacisnieto przycisku drugiego sprawdzaj kolor
    		
    			licznik++;
    			//***Lewy sensor***
    			if(licznik==100){
    				ADMUX &=~(_BV(0));
    				ADMUX &=~(_BV(1));
    				ADMUX &=~(_BV(2));
    				
    				ADCSRA |= _BV(ADSC);     		    // Rozpoczęcie przetwarzania
    				while(bit_is_set(ADCSRA,ADSC)){};	 // Oczekiwanie na zakończenie przetwarzania
    				pomiarL=ADCH;					     // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej
    			}
    			
    			//***Srodkowy sensor***
    			if(licznik==200){
    				ADMUX |=_BV(0);
    				ADMUX &=~(_BV(1));
    				ADMUX &=~(_BV(2));
    
    				ADMUX=0x40;
    				ADMUX=0x40 | 1; // ustaw na wejscie 2 pin portu
    				ADCSRA |= _BV(ADSC);     		    // Rozpoczęcie przetwarzania
    				while(bit_is_set(ADCSRA,ADSC)){};	 // Oczekiwanie na zakończenie przetwarzania
    				pomiarM=ADCH;					     // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej
    			}
    			
    			//***Prawy sensor***
    			if(licznik==300){
    				ADMUX &=~(_BV(0));
    				ADMUX |=~(_BV(1));
    				ADMUX &=~(_BV(2));
    
    				ADMUX=0x40;
    				ADMUX=0x40 | 2; // ustaw na wejscie 3 pin portu
    				ADCSRA |= _BV(ADSC);     		    // Rozpoczęcie przetwarzania
    				while(bit_is_set(ADCSRA,ADSC)){};	 // Oczekiwanie na zakończenie przetwarzania
    				pomiarR=ADCH;					     // Zapisanie starszych 8 bitów wyniku konwersji do zmiennej
    				licznik=0; // zerowanie licznika
    			}
    			
    			// wyświetlanie wyników na diodach
    			
    			//***Lewy sensor***
    			if(pomiarL>kalibracja){LED1_ON;} //jeśli sygnał zapal diodę
    			if(pomiarL<kalibracja-kalibracja/4){LED1_OFF;} //jeśli tło zgaś diodę
    			
    			//***Srodkowy sensor***
    			if(pomiarM>kalibracja){LED2_ON;} //jeśli sygnał zapal diodę
    			if(pomiarM<kalibracja-kalibracja/4){LED2_OFF;} //jeśli tło zgaś diodę
    			
    			//***Prawy sensor***
    			if(pomiarR>kalibracja){LED3_ON;} //jeśli sygnał zapal diodę
    			if(pomiarR<kalibracja-kalibracja/4){LED3_OFF;} //jeśli tło zgaś diodę
    		}
    		
    		LED_OFF;
    		LED1_ON;LED2_ON;LED3_ON;LED4_ON;
    		wait(200);
    		LED_OFF;
    	}
    }

    Gdy testuje program na sensorach podczerwieni (dioda i fototranzystor) działa dopiero oświetlony światłem latarki (ale pojawiają się przekłamania i czasami nie działa), nie reaguje na czarną linie. Z jednym sensorem program działał. Co może być powodem błędu?
  • REKLAMA
  • #2 6746336
    ZbeeGin
    Poziom 39  
          //***Srodkowy sensor*** 
             if(licznik==200){ 
                ADMUX |=_BV(0); 
                ADMUX &=~(_BV(1)); 
                ADMUX &=~(_BV(2)); 
    
                ADMUX=0x40; 
                ADMUX=0x40 | 1; // ustaw na wejscie 2 pin portu

    A cóż to za dziwactwo z ADMUX. Zastanów się co będzie w ADMUX po wykonaniu ostatniej instrukcji...
  • #3 6748054
    ranger46
    Poziom 10  
    Czyli powinno być tak?
    //***Srodkowy sensor***
             if(licznik==200){
                ADMUX |=_BV(0);
                ADMUX &=~(_BV(1));
                ADMUX &=~(_BV(2));
    

    edit:
    Mimo poprawek program dalej nie działa. 2 sensory jakby nie reagują, a 3 steruje wszystkimi.
REKLAMA