BASCOM


Poniżej pokazałem, w jaki sposób można sprawdzić, ile wynosi cykl zegarowy procesora w aktualnie budowanym przez nas urządzeniu.
Ponadto, sprawdzimy, jak długo trwał impuls wysłany z procesora nazwanego Nadajnikiem impulsu.
W przybliżeniu miał trwać ok. 30mS, bo wpisaliśmy polecenie Witms 30.
Impuls można pobrać z Portb.1 i b.2, natomiast w Portd.7 możemy go usłyszeć.
Gdy już mamy urządzenie do wysyłania impulsu, zobaczmy teraz, jak sprawdzić jego dokładny czas trwania.
Udajmy się do Odbiornika impulsu.


Nadajnik impulsu.

Odbiornik impulsu.


Program nadajnika impulsu.

'IleCzasuTrwaImpuls_Nadajnik.bas

'Program na emisję impulsu. Czas impulsu ustawiony na ok. 30mS (Waitms 30).

'Ton sygnału odbieramy z Portd.7 i Portb.1, impulsy z Prtb.2.

'Przycisk startu w Portb.0 (podajemy 0).

'Procesor: Atmega8.

'Fusebit u stawiony na generator wewnętrzny 0100.

'Opracował Henryk Wydmuch.

'Zapełnienie pamięci 5%.

 

$regfile = "m8def.dat"                                      'Dyrektyway dla kompilatora.

 $crystal = 8000000                                         'Zastosujemy generator wewnętrzny 8MHz.

 

 Config Pind.7 = Output                                     'Konfigurujemy Portd.7 jako wyjście sygnału do głośnika.

  Set Portd.7                                               'Ustawiamy poziom wysoki w Portd.7.

 Config Pinb.0 = Input                                      'Konfigurujemy Portb.0 jako przycisk.

   Set Portb.0                                              'Ustawiamy poziom wsoki w Portb.0.

 Config Pinb.1 = Output                                     'Konfigurujemy Portb.1 jako wyjście tonu.

   Set Portb.1                                              'Ustawiamy poziom wysoki w Portb.1.

 Config Pinb.2 = Output                                     'Konfigurujemy Portb.2 jako wyjście impulsów.

   Set Portb.2                                              'Ustawiamy poziom wysoki w Portb.2.

 

Config Timer0 = Timer , Prescale = 8                        'Timer0 jako czasomierz z podziałem wstępnym przez 8 (oscyluje ton).

 

Stop Timer0                                                 'Zatrzymaj Timer0.

 

On Timer0 Ton                                               'Podprogram Ton dla Timer0.

 

Dim Czas As Byte                                            'Deklarujemy 1 bajt pamięci dla zmiennej przechowującej przepełnienia Timer0.

Czas = 0                                                    'Zerujemy zmienną.

 

Enable Interrupts                                           'Zgoda na wszystkie odblokowania.

Enable Timer0                                               'Odblokuj przerwanie od przepełnienia Timer0.

 

   Do                                                       'Start pętli.

    If Pinb.0 = 0 Then                                      'Jeśli naciśnięto przycisk.

     Start Timer0                                           'Nadawanie "s"

     Reset Portb.2                                          'Poziom niski w Portb.2

     Waitms 30                                              'Czekaj 30mS (czas impulsu).

     Stop Timer0                                            '

     Set Portb.2                                            'Poziom wysoki w Portb.2

     Wait 5 .                                               'Czekaj 5 sek.

    End If                                                  'Koniec warunku.

   Loop                                                     'Powtórz.

   End                                                      'Koniec pętli.

 

Ton:                                                        'Podprogram dla Timer0 (częstotliwość tonu telegrafii).

   Load Timer0 , 255                                        'Odliczy od 100 do 255, zmieniając wysokość tonu.

   Incr Czas                                                'Po cyklu powiększ liczbę przepełnień w zmiennej Czas.

   If Czas = 1 Then                                         'Jeśli liczba przepełnień jest większa niż 1, to...

   Czas = 0                                                 'Wyzeruj zmienną.

   Toggle Portd.7                                           'Zmień stan wyjścia Portd.0 na przeciwny (głośnik).

   Toggle Portb.1                                           'Zmień stan wyjścia Portb.1 na przeciwny (wyjście tonu).

   End If                                                   'Koniec warunku.

   Return                                                   'Wróć do programu.




Tu jest Odbiornik impulsu oraz cały tok myślenia i liczenia. 'IleCzasuTrwaImpuls

Program odbiornika impulsu.

'IleCzasuTrwaImpuls.bas

'Tym programem możemy sprawdzić jak długo trwał poziom niski w porcie wejściowym Portd.2..

'Timer0 jest oscylatorem. Wyjściem oscylacji jest Portb.1.

'Timer1 liczy impulsy Timera0 w czasie poziomu niskiego w Portd.2.

'Wejściem Timer1 jest Portd.5.

'Tak więc, ilość zliczonych impulsów jest zależna od czasu otwarcia Portd.2.

'Fusebit ustawiony na kwarc zewnętrzny: External XTAL 1110.

'Procesor: ATMEGA8.

'Opracował Henryk Wydmuch

'Patrz sch. 131205 oraz Atmega8.png.

'Pamięć zajęta w 35%.

 

'Obliczenia:

'Do Portb.1 dołączamy miernik częstotliwości, otrzymujemy 16028KHz.

'Sprawdzamy w Interfejsie "Czasy.exe" jaki to czas częstotliwość 16028KHz. Jest to czas 62,39uS.

'Aby wykonać Toggle Portb.1, to 62,39uS jest połową okresu sinusoidy.

'Trzeba ten czas podzielić przez 2: 31,195uS.

'Ponieważ Timer0 przepełnia się po 250 cyklach (bo Timer0 = 6), należy 31,195uS podzielić przez 250.

'Więc: 31,195 / 250 = 124,78nS. W tym układzie cykl zegarowy wynosi 124,78nS.

'Odpowiedź brzmi: jeden cykl zegarowy, wynosi tu 124,78nS.

 

'Zwracamy teraz uwagę na podprogram: Zlicz_przep_tim1.

'Incr Lczba_przep_tim1 mówi nam, że po zapełnieniu licznika do końca,

'czyli po zliczeniu 65536 impulsów przez Timer1, zmienna powiększy się o 1 i zostanie wyzerowana.

'W pętli Do widzimy, że Timer1 wystartuje w momencie początku impulsu na wejściu, czyli w Portd.2.

'Zmienna Wynik_pomiaru będzie zawierała pełną wartość Timera1 * ilość przepełnień + resztę w Timer1.

'Te wszystkie dane zbiorą się w czasie, gdy będzie trwał impuls na wejściu Portd.2.

'Gdy impuls się skończy, nastąpi Stop Timer1 i wyświetlenie wyniku.

 

'Lcd.

'Impuls na wejściu Portd.2 spowodował (przykład) wyświetlenie liczby 513.

'Jest to liczba przepełnień Timer1.

'513przepełnień * 65536impulsów = 33619968. Zostało zliczonych ponad 33 miliony impulsów.

'Jak wcześniej liczyliśmy, impuls = 124,78nS.  33619968 * 124,78nS = 4195099607nS.

'Ponieważ są to nS, to zamienimy je na mS. Spoglądamy do interfejsu "Zamiana czasów".

'Otrzymujemy wynik: 419,5mS..

'Odpowiedź: impuls trwał 419,5mS.

 

$regfile = "m8def.dat"                                      'Informacja dla kompilatora.

$crystal = 10000000                                         'Też dla kompilatora,zastosujemy kwarc zewnętrzny 10MHz.

 

Config Lcd = 16 * 2

Config Lcdpin = Pin , Db4 = Portd.7 , Db5 = Portb.0 , Db6 = Portd.4 , Db7 = Portd.6 , E = Portd.1 , Rs = Portd.0

                                        'Informacja na jakich Pinach będzie Lcd.

 Config Timer0 = Timer , Prescale = 1                       'Timer0 jako Timer z podziałem przez jeden.

 Config Timer1 = Counter , Edge = Rising                    'Timer1 jako licznik działający od zbocza opadającego.

 Config Pind.5 = Input                                      'Konfiguruj Portd.5 jako wejście frekwencji z Timer0.

   Set Portd.5                                              'Dołącz rezystor podciągający.

 Config Pinb.1 = Output                                     'Konfigurujemy Portb.1 jako wyjście frekwencji.

   Portb.1 = 1                                              'Ustaw 1 w Portb.1.

 

 On Timer0 Odmierz_1s                                       'Podprogramdla Timera0 o nazwie Odmierz_1s.

 On Timer1 Zlicz_przep_tim1                                 'Podprogram dla Timera1.

 

 Dim Liczba_przerwan_tim0 As Word                           ' Tu załadujemy liczbę przerwań Timera0.

 Dim Lczba_przep_tim1 As Word                               ' Tu załadujemy liczbę przerwań Timera1.

 Dim Wynik_pomiaru As Long                                  ' Tu znajdzie się wynik pomiaru.

 

 Enable Interrupts                                          'Zezwalaj na wszystkie przerwania.

 Enable Timer0                                              'Odblokowujemy przerwanie Timera0.

 Enable Timer1                                              'Odblokowujemy przerwanie Timera1.

 

 Wynik_pomiaru = 0                                          'Zerujemy zmienną Wynik_pomiaru.

 Liczba_przerwan_tim0 = 0                                   'Zerujemy zmienną zawierającą liczbę przerwań Timera0.

 Lczba_przep_tim1 = 0                                       'Zerujemy zmienną zawierającą liczbę przerwań Timera1.

 

 Timer1 = 0                                                 'Zerujemy Timer1

 Start Timer0                                               '

 Cls                                                        'Czyść Lcd.

 Stop Timer1                                                'Zatrzymujemy Timer1.

 

 Do                                                         'Start pętli głównej.

 Home                                                       'Utrzymujemy stabilność wyświetlania na Lcd.

  If Pind.2 = 0 Then                                        'jeśli jest początek impulsu.

  Start Timer1                                              '

  Wynik_pomiaru = 65536 * Lczba_przep_tim1                  'Zmienną Liczba_przep_tim1 pomnóż przez 65536, a wynik wstaw do zmiennej Wynik_pomiaru.

  Wynik_pomiaru = Wynik_pomiaru + Timer1                    'Wynik powyższego działania dodaj do zawartości Timera1 i ten wynik wpisz do Wynik_pomiaru.

  Else                                                      'W przeciwnym razie...

  Stop Timer1                                               '

  Lcd Wynik_pomiaru                                         'Pokaż wynik.

  End If                                                    'Koniec warunku.

 Loop                                                       'Powtórz pętlę.

 End                                                        'Koniec pętli.

 

 Odmierz_1s:                                                'Podprogram dla Timera0.

  Timer0 = 6                                                'Do Timera0 dodaj sześć (zliczy 250).

  Incr Liczba_przerwan_tim0                                 'Liczbę przerwań Timera0 powiększ o jeden.

  Toggle Portb.1                                            'Zmień stan poziomu Portb.1.

 Return                                                     'Wróć do programu.

 

 Zlicz_przep_tim1:                                          'Podprogram Timer1.

  Incr Lczba_przep_tim1                                     'Zwiększaj zmienną o 1.

  If Lczba_przep_tim1 = 1 Then                              'Jeśli zawartość Timer1 będzie 65536, to...

  Lczba_przep_tim1 = 0                                      'Zeruj zmienną.

  End If                                                    'Koniec warunku.

 Return                                                     'Wróć do programu.