Skocz do zawartości

Przetwornik A/C


Gohan

Pomocna odpowiedź

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ą.

Link do komentarza
Share on other sites

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 😋

Link do komentarza
Share on other sites

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) )
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.