Skocz do zawartości

Przetwornik A/C


Pomocna odpowiedź

Napisano

Witam.

Zabawę z robotyką zaczęłam niedawno (z góry przepraszam, jeśli napiszę tu jakieś głupoty) i natknęłam się na problem z przetwornikiem A/C.

Używam Atmegi32A.

Do portów PA4 - PA7 mam podłączone czujniki IR. Chcę, aby robot jechał do przodu, a gdy czujnikami podłączonymi pod PA6-PA7 coś zobaczy, ma się zatrzymać. Jednak się nie zatrzymuje.

Jeśli jest to możliwe, to byłabym wdzięczna, za sprawdzenie fragmentów kodu za to odpowiedzialnych, bo nie mam pomysłu, co może być nie tak:

int Wart_IR[4] = {0};
/* 
.
.
.
*/
void ADC_init(void)
{
ADMUX |=  _BV(REFS0); // bo AREF podłączony przez kondensator do masy
ADMUX |= _BV(ADLAR); 
ADCSRA |= _BV(ADPS2) | _BV(ADPS1); //prescaler 64
ADCSRA |= _BV(ADEN); // uruchomienie przetwornika 
}
//Odczytanie wartości

unsigned int ADC_read(unsigned char channel)
{
ADMUX &= ~0x07;

ADMUX |= channel;

ADCSRA |= _BV(ADSC);

while(!(ADCSRA & _BV(ADIF)));

ADCSRA |= _BV(ADIF);

return ADC;
}
//
void zalacz_czujniki(void)
{
PORTC |= _BV(PC6);
_delay_us(125);
}
void wylacz_czujniki(void)
{
PORTC &= ~_BV(PC6);
}
void Odczyt_IR(void)
{
Wart_IR[0]=-ADC_read(4);
Wart_IR[3]=-ADC_read(5);
Wart_IR[1]=-ADC_read(7);
Wart_IR[2]=-ADC_read(6);

zalacz_czujniki();
Wart_IR[0] += ADC_read(4);
Wart_IR[3] += ADC_read(5);
Wart_IR[1] += ADC_read(7);
Wart_IR[2] += ADC_read(6);
wylacz_czujniki();
}

i plik main:

int main(void)
{
inicjalizacja_portow();
timer_init();
ADC_init();

   while(1)
   {
	Odczyt_IR();
	if(Wart_IR[1]<200 && Wart_IR[2]<200)
	{
       	PORTC |= _BV(Lewy_Przod) | _BV(STBY) | _BV(Prawy_Przod);
       	PORTC &= ~_BV(Lewy_Tyl) & ~_BV(Prawy_Tyl);

       	PWM_lewy = 50;
       	PWM_prawy = 50;
	}		
	else
	{
		PWM_lewy = 0;
		PWM_prawy = 0;
	}		
return(0);
   }
}

Efekt jest taki, że silniki się ruszają, ale na czujniki nie reagują i nie stopują.

Spróbuj ustawić ADLAR na 0.

INT jest 16 bitowy, a pomimo tego, że rejestr ADC jest 10 bitowy to z justowaniem w lewo, najmłodsze bity (od 0 do 5) nadpisywane są domyślnie zerami. Z justowaniem w prawo, wyzerowane bity od 10 do 15 nie będą miały wtedy znaczenia. Tak przynajmniej mi się zdaje 😋

W kodzie wszystko chyba jest ok. Zastanawia mnie tylko czy ta linia jest potrzebna:

ADCSRA |= _BV(ADIF);

Flaga i tak jest zerowana sprzętowo po zakończeniu konwersji. Wpisywanie tam jedynki już jest nie potrzebne (czyli kończenie aktualne trwającej konwersji).

Może jeszcze to:

Zamiast

if(Wart_IR[1]<200 && Wart_IR[2]<200)

dodać nawiasy:

if( (Wart_IR[1]<200) && (Wart_IR[2]<200) )

Wykluczyłaś problemy sprzętowe? Sprawdź miernikiem czy sygnał na wyjściu czujników faktycznie się zmienia i w jakim zakresie.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...