- posted
19 years ago
[AVR-GCC] przetwornik AC
- Vote on answer
- posted
19 years ago
Użytkownik BT napisał:
Wyciąłem co nieco... ale powiedz: wychodzi z tego, że w przerwaniu zatrzymujesz wykonywanie programu na 0.5s ? A watchdoga nie wyłączyłeś? Ogólnie: NIE wolno w procedurze obsługi przerwania dawać żadnych sleep'ow (to nie system operacyjny w ktorym sleep() oddaje do niego kontrolę ;) ) Ja bym zrobił to tak:
int diode_is_on(void) { // wczytaj ten bit na ktorym dioda wisi - nie mam manuala pod reka
}void diode_on(void) { sbi(DDRD,4); cbi(PORTD,4); }
void diode_off(void) { sbi(DDRD,4); sbi(PORTD,4); }
void sleep(int ms) { for (int l=0;l<ms;l++) { _delay_loop_2(4000); } }
SIGNAL(SIG_ADC) { if (!diode_is_on) diode_on; }
int main(void) {
outp(0,ADMUX); outp((1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE),ADCSR); sei();
int i;
while(1) { if (!diode_is_on) i=50; if (i==0) diode_off; i--; // tu reset WD sleep(10); };
}Czyli jak się program gdzieś wykrzaczy, to nie wróci do main i nastąpi reset. TO nie jest precyzyjny ;J pomiar czasu, jeśli chcesz precyzji to musisz wykorzystac timer. Nie mam pod ręką mana do gcc, ale ja bym tak to napisał :J
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
Dnia czw 10. czerwca 2004 19:59 BT napisał(a):
- Co zapala diodę: cbi czy sbi? Tzn. czy podpiąłeś anodą czy katodą do portu?
- Brakuje mi opóźnienia na sbi, żeby dioda miała mrugać im razy.
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
hmm, mój mózgowy kompilator i egzekutor zapala diodę na 0.5 sekundy następnie wyłącza na ok. 500ns (zależy od taktu), a następnie znowu ją załącza. Nie wierzę, że uda ci się wyłączyć LEDa bezproblemowo na 500ns. Czyli dioda świeci się cięgiem.
Waldek
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
Użytkownik BT napisał:
Pan Krzok ma rację !!! (że też sam na to nie wpadłem wcześniej...)
eL eS
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
Dnia czw 10. czerwca 2004 22:22 BT napisał(a):
Nie denerwuj się. Urzekła mnie twoja historia ;-) i od jakiegoś czasu wpatruję się w twój kod, ale na razie nic nie wypatrzyłem. Zaraz wrzucę w gcc i popatrzymy na kod wynikowy.
Jeśli podejrzewasz przetwornik, możesz spróbować odczytu bez przewań, tzn.:
ADMUX = 0; //0x00 - nap. odniesienia: AVCC, PRZETW. KAN. 0
cli(); ADCSR|=_BV(ADSC); //poczatek konwersji while((ADCSR&(_BV(ADSC)))); //poczekaj na wynik
I tu wstaw sobie mrugnięcie.
Pozdrawiam
- Vote on answer
- posted
19 years ago
Dnia czw 10. czerwca 2004 22:43 Marcin Stanisz napisał(a): <ciach>
Szczerze mówiąc to skompilowało i kod wynikowy nie zawiera jakichś oczywistych zonków :-(
Wektor przerwań dobrze ustawiony: 1c: 1f c0 rjmp .+62 ; 0x5c [...]
0000005c <__vector_14>:SIGNAL(SIG_ADC) { 5c: 1f 92 push r1 5e: 0f 92 push r0 60: 0f b6 in r0, 0x3f ; 63 62: 0f 92 push r0 64: 11 24 eor r1, r1 66: 0f 90 pop r0 68: 0f be out 0x3f, r0 ; 63 6a: 0f 90 pop r0 6c: 1f 90 pop r1 6e: 18 95 reti }
[...]0000009e <main>:
int main(void) { 9e: cf e5 ldi r28, 0x5F ; 95 a0: d4 e0 ldi r29, 0x04 ; 4 a2: de bf out 0x3e, r29 ; 62 a4: cd bf out 0x3d, r28 ; 61 outp(0,ADMUX); a6: 17 b8 out 0x07, r1 ; 7 outp((1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE),ADCSR); a8: 88 ed ldi r24, 0xD8 ; 216 aa: 86 b9 out 0x06, r24 ; 6 sei(); ac: 78 94 sei
diode(); ae: ec df rcall .-40 ; 0x88 while(1); b0: ff cf rjmp .-2 ; 0xb0
Czyli w mainie też jakby dobrze. Nie mam, niestety, megi8. Za jakieś 2 dni będę składał coś na 32, to jeszcze sprawdzę.
Kompilowane: [mstanisz@cita /]$ avr-gcc -v Reading specs from /usr/local/avr/lib/gcc-lib/avr/3.3.2/specs Configured with: ../configure --prefix=/usr/local/avr --target=avr
--enable-languages=c --disable-nls Thread model: single gcc version 3.3.2
A twoje gcc w której wersji?
Pozdrawiam i życzę powodzenia
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
W artykule <cac81s$r08$ snipped-for-privacy@nemesis.news.tpi.pl> BT napisal(a):
Musisz włączyć wewnętrzne źródło napięcia odniesienia (ca. 2,56V) lub AVCC
- patrz w manualu ustawienia rejestru ADMUX.
Marcin Stanisz
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
W artykule <caccjp$drb$ snipped-for-privacy@atlantis.news.tpi.pl> BT napisal(a):
Aha. ADEN. No tak. Za dużo masła ;-)
Marcin Stanisz
- Vote on answer
- posted
19 years ago
BTW: Nie używaj outp/inp ani cbi/sbi bo te makra są już "deprecated" i w następnej wersji avr-gcc mogą po prostu zniknąć. Zamiast tego lepiej napisać (i IMHO dużo bardziej wygodnie):
ADMUX = 0; ADCSR = (1<<ADEN) | (1<<ADSC) | (1<<ADIF) | (1<<ADIE);
A makra _BV nie polecam, bo ani ono ładne, ani wygodne.