Poprzedni temat «» Następny temat
Programowanie mikrokontrolerów AVR w języku Bascom
Autor Wiadomość
snow 
AVR, AVR-GCC


Wiek: 34
Dołączył: 16 Sty 2007
Posty: 735
Skąd: lubelskie
Wysłany: 2009-09-27, 15:07   

Jak nie wyjdzie 1?
 
 
     
matrix 



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2009-09-27, 15:08   

Cytat:
Jak nie wyjdzie 1?

no wychodzi 100. wynikiem jest 100
 
 
     
snow 
AVR, AVR-GCC


Wiek: 34
Dołączył: 16 Sty 2007
Posty: 735
Skąd: lubelskie
Wysłany: 2009-09-27, 15:11   

To dzielenie daje równo 1. 8000000/256/250/125 daje 1
 
 
     
matrix 



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2009-09-27, 15:14   

snow napisał/a:
To dzielenie daje równo 1. 8000000/256/250/125 daje 1

przepraszam. rzeczywiście 1. liczyłem na telefonie a mi się klawisze zacinają i dodało mi dwa zera. policzyłem na kompie i zgadza się. jeszcze raz przepraszam. dobra, pomijając ten fakt, to skąd to się wzięło i jak to liczyć?
 
 
     
Ertew 
-.^



Wiek: 26
Dołączył: 03 Lip 2005
Posty: 1347
Skąd: Leszno
Wysłany: 2009-09-27, 15:18   

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



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2009-09-27, 16:18   

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ć
Kod:
A=timer0
?
nie wywala żadnego błędu.
 
 
     
snow 
AVR, AVR-GCC


Wiek: 34
Dołączył: 16 Sty 2007
Posty: 735
Skąd: lubelskie
Wysłany: 2009-09-27, 16:19   

Raczej A=tcnt0
 
 
     
matrix 



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2009-09-27, 18:21   

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?
 
 
     
snow 
AVR, AVR-GCC


Wiek: 34
Dołączył: 16 Sty 2007
Posty: 735
Skąd: lubelskie
Wysłany: 2009-09-27, 20:05   

Przerwania zawsze mają nadrzędny priorytet nad samym programem, dlatego należy w obsłudze przerwania unikać opóźnień.
 
 
     
matrix 



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2009-09-27, 20:51   

snow napisał/a:
Przerwania zawsze mają nadrzędny priorytet nad samym programem, dlatego należy w obsłudze przerwania unikać opóźnień.

no tak ale czy wizualnie bedzie widac przeerwe w dzialaniu programu głównego czyli w miganiu diod?
 
 
     
Ertew 
-.^



Wiek: 26
Dołączył: 03 Lip 2005
Posty: 1347
Skąd: Leszno
Wysłany: 2009-09-28, 17:41   

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:
Kod:
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
Return

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ć.
 
 
     
mopeqq 
Nowy na forum


Dołączył: 28 Mar 2010
Posty: 6
Skąd: BCN
Wysłany: 2010-07-15, 14:18   

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;

Kod:

'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


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?
 
     
Wojtek 



Dołączył: 04 Sie 2002
Posty: 2511
Skąd: --
Wysłany: 2010-07-15, 16:53   

Bo pewnie jest ustawiony domyslnie na 1M wewnętrzny. Trzeba mu zadklarować odpowiedni zewnetrzny zegar i fusebity przy programowaniu ustawic.
  
 
     
matrix 



Wiek: 39
Dołączył: 15 Mar 2006
Posty: 1583
Skąd: Sochaczew
Wysłany: 2010-07-15, 21:09   

najpewniej fusy. pewnie masz ustawioną funkcję podziału zegara przez 8?
 
 
     
mopeqq 
Nowy na forum


Dołączył: 28 Mar 2010
Posty: 6
Skąd: BCN
Wysłany: 2010-07-31, 12:47   

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".
 
     
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  


Powered by phpBB modified by Przemo © 2003 phpBB Group
Strona wygenerowana w 0,07 sekundy. Zapytań do SQL: 10