przechwytywanie w BASCOMIE

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
hubertp
-
Posty: 25
Rejestracja: 30 paź 2007, 16:01
Lokalizacja: mińsk maz.

przechwytywanie w BASCOMIE

Post autor: hubertp » 14 gru 2007, 20:27

Czy da się i w jaki sposób zmierzyc częstotliwośc przebiegu podawanewgo na któreś z wejśc komparatora analogowego AVR.Jak to zrobic w BASCOMIE lub innym języku chociażby nawet assemblerze :?:Jak skonfigurowac komparator analogowy i timer do takich pomiarów?

ZbeeGin

Post autor: ZbeeGin » 16 gru 2007, 12:11

Prolog.

Sprawa mierzenia częstotliwości przebiegu przez komparator w połączeniu z przechwytywaniem przez licznik Timer1 jest w pewnym sensie trudna. Dlaczego? Ponieważ będzie potrzebny mechanizm rozpoznawania kiedy jeden półokres przebiegu się zaczyna, a kiedy kończy. Zatem występują tu dwa aktywne zbocza sygnału pochodzącego z wyjścia komparatora mogące wyzwolić licznik: opadający i narastający.
Teraz w zależności od założeń co do postaci sygnału i sposobu jego doprowadzenia do wejść komparatora (czy dodatnie, czy ujemne wejście) wypada przyjąć, że:
- opadający rozpoczyna pomiar jednego półokresu, a narastający kończy,
- narastający rozpoczyna pomiar jednego półokresu, a opadający kończy.
Wiąże sie to z określeniem z czym komparator ma porównywać doprowadzony do niego sygnał, tu: napięcie odniesienia przekładające się na próg zadziałania. I do którego wejścia (jak wyżej) jest to napięcie odniesienia doprowadzone.

W uproszeniu mamy zatem dwa rozwiązania. Zajmijmy się jednym.

Założenia.

Niech narastające zbocze sygnału z komparatora będzie rozpoczęciem pomiaru a opadające niech kończy pomiar. Będziemy mierzyć czas tylko takich "dodatnich" połówek sygnału, gdyż szybka rekonfiguracja komparatora jak i licznika byłaby niemożliwa do zrealizowania. Zatem wynik pomnożymy razy dwa i otrzymamy mniej więcej czas jednego pełnego okresu przebiegu. A z przeliczeniem tych milisekund lub mikrosekund na częstotliwość raczej problemu nie będzie.

Aby umożliwić pomiar, będziemy musieli:
1. Umożliwić komparatorowi możliwość rozpoczynania pracy licznika, oraz włączyć opcję sterowania przechwytywaniem. Zatem bez przerwań i procedur jego obsługi się nie obejdzie.
2. Skonfigurować licznik jako zliczający czas (sygnał zegarowy) z możliwością przechwytywania, ale do czasu wystąpienia narastającego zbocza powinien on być zatrzymany (Stop Timer1).

Jak by to mniej więcej skonfigurować?

Jeśli chodzi o komparator to sprawa jest dość prosta:

Kod: Zaznacz cały

Config ACI = On, Compare = On, Trigger = Rising
I już komparator jest włączony i przygotowany do sterowania licznika - wtedy to sygnał wewnętrzny ACO zastępuje sygnał z końcówki ICP1. Dodatkowo układ komparatora generuje przerwania które wykorzystamy do włączania zliczania. Będą one generowane jeśli stan wyjścia komparatora zmieni się z niskiego na wysoki.

Do pełni szczęścia będzie potrzebny nam jeszcze licznik Timer1:

Kod: Zaznacz cały

Config Timer1 = Timer, Prescale = 8, Capture Edge = Falling
I już licznik nam ładnie zlicza, z podstawą czasu jako sygnał taktujący procesor podzielony przez 8. Dodatkowo zmiana stanu flagi ACO (stan wyjścia komparatora) z wysokiego na niski będzie wywoływać przechwycenie.
Oczywiście musimy go wyzerować i zatrzymać przed całą akcją:

Kod: Zaznacz cały

Stop Timer1
Timer1 = 0
W zależności od zakładanej, bądź przypuszczalnej częstotliwości przebiegu mierzonego trzeba podjąć decyzję o częstotliwości pracy procesora i wartości jej podziału. Przy taktowaniu 8MHz i preskalerze ustawionym na clk/8 jednostką czasu będzie 1µs. Zatem zliczenie przez licznik 20 jednostek będzie równoznaczne częstotliwości przebiegu 50kHz.

Dodatkowo potrzebne będą przerwania:

Kod: Zaznacz cały

Enable ACI                       'by startować licznik przez przerwanie z 
                                 'komparatora
Enable Capture1                  'by po przechwyceniu zatrzymać licznik i 
                                 'wyzerować jego zawartość dla następnego cyklu
Enable Interrupts                'by wogóle działały przerwania :-)

On ACI _Start_konwersji_         'by uruchomić licznik - np. poprzez Start Timer1
On Capture1 _Stop_konwersji_     'by zatrzymać licznik - np. Stop Timer1 i 
                                 'odczytać okres ze zmiennej Capture1

Epilog.

Na koniec wypadałoby wspomnieć o tym, by pomiar okresu wykonać dwukrotnie albo nawet trzykrotnie i pomiary uśrednić. Wiadomo chwilowe wachania częstotliwości powinny być wyeliminowane.
Jeśli chodzi o BASCOM to jego dodatkowe operacje jak ładowanie czego się da na stos podczas przerwania będą nam niestety przeszkadzać. Zatem należy dokonać korekty czasu lub przerwania pisać całe w asemblerze i skorzystać z opcji NoSave.

Cały opis nie wyczerpuje drobnych niuansów, ale pozwoli na wykonanie choćby szkieletu programu. Do rozpatrzenia pozostały:
Co zrobić by komparator nie wyzwalał nowego przerwania do końca pomiaru? Co będzie jak licznik się przepełni, a przechwycenie nie nastąpi? Jak dobrać częstotliwośc rezonatora i podział przeskalera? Jaki wybrać poziom odniesienia dla komparatora by nie mierzyć drobnych "szpilek" z niestabilnych generatorów?
Ostatnio zmieniony 16 gru 2007, 17:47 przez ZbeeGin, łącznie zmieniany 1 raz.

hubertp
-
Posty: 25
Rejestracja: 30 paź 2007, 16:01
Lokalizacja: mińsk maz.

Post autor: hubertp » 16 gru 2007, 17:16

Dziękuję za odpowiedź.Nie ma takiego parametru jak:Capture = On. Napisałeś:
Config ACI = On, Capture = On, Trigger = Rising. Po tym BASCOM zgłasza błąd.
Może chciałeś napisac COMPARE=ON?

ZbeeGin

Post autor: ZbeeGin » 16 gru 2007, 17:47

No tak. Ma być COMPARE = ON. :oops: Poprawiono.

ODPOWIEDZ