| Author |
Message
|
mateo19851 Poziom 15

Joined: 19 May 2003 Posts: 234 Location: Kraków
|
#1
19 Feb 2010 17:21 [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Nie za bardzo mogę ogarnąć przetwornik A/C w ATmega8.
Zrobiłem układ jak na schemacie. Chciałem żeby dioda zapalała się powyżej
1V napięcia na potencjometrze, a do 1V była zgaszona.
Napięciem odniesienia dla mnie miało być AVCC.Korzystam z 8 bitów ADCL.
Konwersja wyzwalana int0.
Program wygląda nastepująco:
Załanczam standartowe biblioteki dla avr (przerwania, delay,io)
Schemat :
Kod:
| Code: |
#define F_CPU 1000000
int main(void){
inicjalizacja();
while(1){
}
}
ISR(INT0_vect){
_delay_ms(80);//eliminuj drgania ze styków
ADMUX|=_BV(ADSC);//start konwersji
_delay_ms(100);//czekaj na wynik
if(ADCL<=0xCC){
PORTB&=~_BV(0);
}
else{
PORTB|=_BV(0);
};
}
void inicjalizacja(void){
//ustawienie portów
DDRB|=_BV(0);
DDRC&=~_BV(0);
DDRD&=~_BV(2);
PORTD|=_BV(2);//pull-up
//ADC
ADMUX|=(_BV(REFS0));
ADMUX&=~(_BV(REFS1)|_BV(ADLAR)|_BV(MUX0)|_BV(MUX1)|_BV(MUX2)|_BV(MUX3));
ADCSRA|=(_BV(ADEN)|_BV(ADSC)|_BV(ADPS));//zapoczątkowanie konwersji
ADCSRA&=~(_BV(ADPS1)|_BV(ADPS0));//preskaler CLK/16 (żeby bylo 50kHz)
//przerwanie INT0
SREG|=_BV(7);//globalna maska przerwan
MCUCR|=_BV(ISC01);
MCUCR&=~_BV(ISC00);
GICR|=_BV(INT0);//maska dla INT0
_delay_ms(100);//czekaj na pierwszą konwersję
}
|
Układ jednak nie działa ,dioda wogóle nie świeci ... Co robię źle ?
|
|
| Back to top |
|
 |
Google

|
#
19 Feb 2010 17:21 |
|
|
|
|
|
| Back to top |
|
 |
morson Poziom 10

Joined: 26 Jun 2006 Posts: 45
|
#2
19 Feb 2010 17:48 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Robisz kilka podstawowych błędów
1. Po resecie odpowiednie rejestry procesora mają ustalone wartości (z reguły 0x00) i nie musisz im ustawiać ponownie bitów na 0 (patrz Datasheet).
2. Używanie _delay_ms w przerwaniu to pomyłka, blokuje Ci możliwość odebrania kolejnego przerwania.
3. Jeśli już koniecznie chcesz używać przerwań do odczytu ADC, to używaj przerwania dotyczącego zakończenia konwersji, a nie zaprzęgaj do tego licznika.
| Code: |
ISR(ADC_vect)
{
int wartosc = ADC;
// tu porównywania ewentualnie zmiana wejścia z którego będzie mierzone napięcie
ADCSRA |= (1<<ADSC); // start kolejnej konwersji
}
|
Nie zapomnij aktywować zezwolenia na przerwanie.
4. przerwania aktywuje się wygodniej sei() niż zapisywaniem do SREG.
5. Dopiero odczytanie ADCH, pozwala na zapisanie do rejestrów przez mikrokontroler nowej wartości z aktualnego przetwarzania.
6. Przy przetworniku niema czegoś takiego jak eliminacja drgań zestyków :)
|
|
| Back to top |
|
 |
Google

|
#
19 Feb 2010 17:48 |
|
|
|
|
|
| Back to top |
|
 |
mateo19851 Poziom 15

Joined: 19 May 2003 Posts: 234 Location: Kraków
|
#3
19 Feb 2010 17:57 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Drgania zestyków chciałem wyeliminować od przerwania INT0 wyzwalanego przyciskiem zwierającym do masy. Faktycznie zaglądłem jeszcze raz do datasheeta. Czyli to wszystko przez to,że nie odczytuje ACDH - jeśli bym wyrównał wynik do lewej to będzie chulać ? Schemat jest prawidłowo złożony ?
|
|
| Back to top |
|
 |
Google

|
#
19 Feb 2010 17:57 |
|
|
|
|
|
| Back to top |
|
 |
morson Poziom 10

Joined: 26 Jun 2006 Posts: 45
|
#4
19 Feb 2010 18:13 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Na schemacie (nie przyglądałem się mu wcześniej) masz błąd ARef to wyjście lub wejście napięcia referencyjnego, nie możesz go zewrzeć do masy bo uszkodzisz wewnętrzne źródło, jeśli korzystasz z wewnętrznego do powinien tam być kondensator 100nF do masy. A jeśli korzystasz z zewnętrznego źródła to podpina się je właśnie tam.
Jeśli wyrównasz do lewej to powinno działać, po odczytaniu ADCH.
|
|
| Back to top |
|
 |
mateo19851 Poziom 15

Joined: 19 May 2003 Posts: 234 Location: Kraków
|
#5
20 Feb 2010 16:16 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Przetwornik ruszył . Jednak pojawiło się jeszcze jedno pytanie:
ADC obsługuję w przerwaniu . Używam komendy :
Gdzie zmienna wynik jest typu "volatile uint16_t"(globalna).
I z tym poleceniem działa prawidłowo. Gdy stworzyłem funkcję :
| Code: |
volatile uint8_t Low,High;
volatile uint16_t wynik;
void sprawdz(void){
Low=ADCL;
High=ADCH;
High=wynik&0x03;
wynik=wynik | High;
wynik=wynik<<8;
wynik=wynik | Low
}
|
Przetwornik dziwnie sie zachowuje , rozpoznaje tylko dwa poziomy napięcia.
Czy kod jest napisany prawidłowo ?
|
|
| Back to top |
|
 |
Google

|
#
20 Feb 2010 16:16 |
|
|
|
|
|
| Back to top |
|
 |
morson Poziom 10

Joined: 26 Jun 2006 Posts: 45
|
#6
20 Feb 2010 16:35 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
| mateo19851 wrote: |
Przetwornik ruszył . Jednak pojawiło się jeszcze jedno
| Code: |
volatile uint8_t Low,High;
volatile uint16_t wynik;
void sprawdz(void){
Low=ADCL;
High=ADCH;
High=wynik&0x03; // tu chyba chciałeś High=High&0x03; ?
wynik=wynik | High; // niepotrzebnie do starego wyniku dodajesz logicznie nowy wynik, powiniwneś dać wynik = High;
wynik=wynik<<8;
wynik=wynik | Low
}
|
|
Wartość ADCH nigdy nie będzie większa niż 0x03 jeśli wyrównujesz do prawej, więc niewiem po co to sprawdzasz
ps.
Niewiem czemu komplikujesz sobie życie i zwiększasz ilość kodu
|
|
| Back to top |
|
 |
mateo19851 Poziom 15

Joined: 19 May 2003 Posts: 234 Location: Kraków
|
#7
20 Feb 2010 16:57 Re: [C][ATmega8] Przetornik ADC - pierwsze starcie |
|
|
|
Faktycznie tam chodziło mi o High=High&0x03.
Już tłumaczę czemu komplikuje sobie życie - wolę znać różne warianty rozwiązania zadania , jakbym zapomniał jeden zawsze będę znał inny :)
Z poprawkami już działa .
Dzięki morson za cierpliwość :)
Temat można uznać za zamknięty .
Pozdrawiam
|
|
| Back to top |
|
 |