Programowanie mikrokontrolerów AVR w języku Bascom
Timer posiada dzielnik i licznik. Podział wstępny dzielnika można wybrać, jednak nie może on posiadać dowolnej wartości, tylko jedną z ustalonych przez producenta. Tu jest wybrana wartość 256.
Licznik zlicza impulsy wstępnie podzielone. Jego pojemność jest zależna od ilości bitów. Tu prawdopodobnie jest wykorzystany licznik 8 bitowy (o pojemności 256).
Po osiągnięciu tej wartości licznik jest zerowany i generowane jest przerwanie, które zmienia wartość licznika (jak się nie mylę, to ładuje do licznika 6).
W ten sposób licznik generuje następne przerwanie po 250 impulsach z dzielnika.
W obsłudze przerwania jest także prosty licznik (dodawanie 1 do zmiennej), który zlicza wystąpienia tego przerwania i tylko raz na 125 cykli jest wykonywane zliczenie jednej sekundy.
Licznik zlicza impulsy wstępnie podzielone. Jego pojemność jest zależna od ilości bitów. Tu prawdopodobnie jest wykorzystany licznik 8 bitowy (o pojemności 256).
Po osiągnięciu tej wartości licznik jest zerowany i generowane jest przerwanie, które zmienia wartość licznika (jak się nie mylę, to ładuje do licznika 6).
W ten sposób licznik generuje następne przerwanie po 250 impulsach z dzielnika.
W obsłudze przerwania jest także prosty licznik (dodawanie 1 do zmiennej), który zlicza wystąpienia tego przerwania i tylko raz na 125 cykli jest wykonywane zliczenie jednej sekundy.
a powiedzmy że w czasie trwania danego impulsu na wejściu INT0 pozwolę licznikowi zliczać, a jak pojawi się tam stan niski to licznik zatrzymam. to jak przypisać jakiejś zmiennej wartość tego licznika w chwili jego zatrzymania?
ianczej mówiąć, jeśli pozwolę licznikowi zliczać w trakcie tej 1ms i po tym czasie zatrzymam go, to jak wartość licznika przypisać zmiennej A?
czy wystarczy napisać ?
nie wywala żadnego błędu.
ianczej mówiąć, jeśli pozwolę licznikowi zliczać w trakcie tej 1ms i po tym czasie zatrzymam go, to jak wartość licznika przypisać zmiennej A?
czy wystarczy napisać
Kod: Zaznacz cały
A=timer0nie wywala żadnego błędu.
a mam kolejne pytanie: co dzieje się z programem w pętli głównej jeśli przychodzi przerwanie z zewnątrz?
znaczy to normalne, program zostaje przerwany i następuje obsługa przerwania, ale jak to się odbija na wizualności? dajmy na to w pętli głównej mam program który obsługuje dwie diody jako stroboskopy i kilka diod jako linijkę gdzie punk świetlny się przesuwa. jak to będzie wyglądało jak program w pętli głównej zostanie przerwany i obłuży dane przerwanie? czy zauważymy przerwę w świeceniu diod?
znaczy to normalne, program zostaje przerwany i następuje obsługa przerwania, ale jak to się odbija na wizualności? dajmy na to w pętli głównej mam program który obsługuje dwie diody jako stroboskopy i kilka diod jako linijkę gdzie punk świetlny się przesuwa. jak to będzie wyglądało jak program w pętli głównej zostanie przerwany i obłuży dane przerwanie? czy zauważymy przerwę w świeceniu diod?
Program w pętli głównej zostanie na chwilkę przerwany.
Jako, że nie będzie on wykonywany, to nie będzie zmieniać stanu portów (o ile program obsługi przerwania nie zmieni portów).
Na szybko taki program:
Jeśli się nie pomyliłem, to program powinien zaświecić diody 4 LED podłączone do pinów 0-3 portu B. Będą się one nierówno świecić światłem ciągłym (ponieważ są po kolei włączane).
Wygenerowanie przerwania T1 spowoduje chwilowe świecenie się jednej z nich (procesor wtedy ,,czeka'' w przerwaniu i nie zmienia stanu LEDów).
Program nie sprawdzony praktycznie.
[ Dodano: 2009-09-28, 18:45 ]
Jeśli zmniejszysz czas czekania w przerwaniu T1 10 krotnie, a czasy w pętli głównej zwiększysz 100 krotnie, to efekt nie będzie aż tak bardzo widoczny.
Ale nadal będzie występować.
Jako, że nie będzie on wykonywany, to nie będzie zmieniać stanu portów (o ile program obsługi przerwania nie zmieni portów).
Na szybko taki program:
Kod: Zaznacz cały
Config Timer1 = Timer , Prescale = 256
Enable Interrupts
Enable Timer1
On Timer1 Czekaj
Start Timer1
Ddrb = 0 'wyjście
Do
Set Portb.0
Waitms 1
Reset Portb.0
Set Portb.1
Waitms 2
Reset Portb.1
Set Portb.2
Waitms 3
Reset Portb.2
Set Portb.3
Waitms 4
Reset Portb.3
Loop
End
Czekaj:
Waitms 250
ReturnWygenerowanie przerwania T1 spowoduje chwilowe świecenie się jednej z nich (procesor wtedy ,,czeka'' w przerwaniu i nie zmienia stanu LEDów).
Program nie sprawdzony praktycznie.
[ Dodano: 2009-09-28, 18:45 ]
Jeśli zmniejszysz czas czekania w przerwaniu T1 10 krotnie, a czasy w pętli głównej zwiększysz 100 krotnie, to efekt nie będzie aż tak bardzo widoczny.
Ale nadal będzie występować.
Witam. Jakiś czas temu zakupiłem kurs mikrokontrolerów wraz z płytką testową, która pozwala na testowanie układów według książki "Mikrokontrolery dla początkujących" autorstwa P. Góreckiego. Doszedłem to ćwiczenia, pozwalającego wykonanie prostego stopera. Oto listing;
Jednak niestety program w żadnym wypadku nie mierzy precyzyjnie czasu (robi to znacznie wolniej). Obliczyłem granicę błędu i wyszło mi, że procek pokazuje jedną sekundę w czasie około 8 sekund. Uznałem, że rezonator nie działa tak jak powinien. Kupiłem kilka rezonatorów o większych częstotliwościach, obliczałem parametry, a program wciąż działał tak samo tak jakby był taktowany czymś innym. W końcu całkowicie wyjąłem rezonator z podstawki i układ wciąż działał. Jestem amatorem, więc nie wiem gdzie robię błąd i jak sobie z nim poradzić. Pomożecie?
Kod: Zaznacz cały
'C012a Bardzo prosty stoper 0,1-sekundowy
Dim Dziesek As Byte , Sekjed As Byte , Sekdzies As Byte , Minjed As Byte
Dim 100ms As Byte , Ktorywysw As Byte , Licz As Bit
Config Portb = 255 : Portb = &B11111111 : Config Portd = &B1111100 : Portd = &B1111111
Config Timer0 = Timer , Prescale = 64 : Enable Interrupts : Enable Timer0
Dziesek = 0 : Sekjed = 0 : Sekdzies = 0 : Minjed = 0
On Timer0 Co4ms
Do : Loop : End 'to jest główny program - pusta nieskończona pętla
Co4ms: 'procedura obsługi przerwania od Timera T/C0 wykonywana co 4ms
Load Timer0 , 250 'załaduj do Timera0, żeby zliczył 250 (=256-6) impulsów
If Pind.0 = 0 Then Licz = 1 'sprawdź stan S1 i ewentualnie rozpocznij zliczanie czasu
If Pind.1 = 0 Then Licz = 0 'sprawdź stan S2 i ewentualnie zakończ zliczanie czasu
If Licz = 1 Then 'tylko wtedy, gdy stoper ma liczyć czas
Incr 100ms 'co 4ms zwiększ wartość licznika o nazwie 100ms
If 100ms = 25 Then 'skróc cykl licznika 100ms właśnie do 100ms
100ms = 0 'czyli 0,1 sekundy
Incr Dziesek 'co 0,1s zwiększ stan licznika dziesiatych części sekundy
If Dziesek = 10 Then 'ten licznik liczy do dziesieciu
Dziesek = 0 'czyli cykl trwa 1 sekundę
Incr Sekjed 'co 1 sekundę zwiększ licznik jednostek sekund
If Sekjed = 10 Then
Sekjed = 0 'co 10 sekund
Incr Sekdzies 'zwiększ stan licznika dziesiatek sekund
If Sekdzies = 6 Then 'liczy do 6 bo minuta ma 60 sekund
Sekdzies = 0
Incr Minjed 'co 60 sekund zwiększ stan licznika minut
If Minjed = 10 Then Minjed = 0 '0...9 minut
End If 'więc maksymalny stan licznika to:
End If '9 minut, 59 sekund i 9 dziesiatych sekundy
End If
End If
End If
Incr Ktorywysw : If Ktorywysw = 4 Then Ktorywysw = 0 'skróć cykl: 0...3
Portd = &B1111111 ' wygaś wyświetlacze
Select Case Ktorywysw ' obsługa wyświetlacza
Case 0: 'wyświetl zawartość licznika jednostek
Portb = Lookup(dziesek , Tabela) 'najpierw przepisz do PortB kody
Portd.3 = 0 'potem włącz T3 - wyświetlacz jednostek
Case 1: 'wyświetl zawartość licznika dziesiątek
Portb = Lookup(sekjed , Tabela) 'najpierw przepisz do PortB kody
Portb.7 = 0 'włącz punkt dziesiętny
Portd.4 = 0 'potem włącz T4 - wyświetlacz dziesiątek
Case 2: 'wyświetl zawartość licznika setek
Portb = Lookup(sekdzies , Tabela) 'przepisz do PortB kody
Portd.5 = 0 'włącz T5 - wyświetlacz setek
Case 3: 'wyświetl zawartość licznika tysięcy
Portb = Lookup(minjed , Tabela) 'przepisz do PortB kody
Portb.7 = 0 'włącz punkt dziesiętny
Portd.6 = 0 'włącz T6 - wyświetlacz tysięcy
End Select
Return 'koniec procedury obsługi przerwania
Tabela: 'potrzebna do wyświetlenia cyfr 0...9
Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
Bo pewnie jest ustawiony domyslnie na 1M wewnętrzny. Trzeba mu zadklarować odpowiedni zewnetrzny zegar i fusebity przy programowaniu ustawic.
Ostatnio zmieniony 16 lip 2010, 6:06 przez Wojtek, łącznie zmieniany 1 raz.
Mam kolejne pytanie. Otóż uczę się teraz rozdziału ósmego, poświęconego pamięci eeprom. Programy po bezbłędnym skompilowaniu i przesłaniu do procka nie wizualizują rezultatów na wyświetlaczach. Korzystam z BASCOM-AVR 1.11.8.1 oraz Avr Studio. Domyślam się, że pewnie gdzieś trzeba coś skonfigurować, a nie chcę namieszać...
PS. W Avr Studio do flash wrzucam plik z rozszerzeniem "hex", a do eeprom z rozszerzeniem eep. W drugim przypadku pojawia się napis: "Getting isp parameter.. SD=0x06 .. OKThe specified file is not a valid Intel HEX file".
PS. W Avr Studio do flash wrzucam plik z rozszerzeniem "hex", a do eeprom z rozszerzeniem eep. W drugim przypadku pojawia się napis: "Getting isp parameter.. SD=0x06 .. OKThe specified file is not a valid Intel HEX file".