Skocz do zawartości

Attiny2313, Licznik impulsów i Bascom


greg01

Pomocna odpowiedź

Witam wszystkich.

Jak w temacie celem mojego programu jest zliczenie impulsów , poprzez wejście INT0

oraz wyświetlenie wartości na LCD.

Program korzysta z timera0 który odmierza czas pomiaru.

Po przeładowaniu timera0 za każdym razem powinna być załadowana wartość 40 by w pracy z preskalerem 1024 i kwarcem 11,0592 Mhz uzyskać 20milisekund.

Ilość zliczonych impulsów pomnożona przez 50 daje nam wartość zliczoną w ciągu jednej sekundy.

Proszę o sprawdzenie kodu ponieważ program nie działają prawidło.

Przy stałej ilości impulsów program wyświetla różne wartości .

Co jest przyczyną złego działania programu.

 Config Timer0 = Timer , Prescale = 1024
     Config Pind.2 = Input

     Dim Wynik As Long

     Load Timer0 = 40

     Enable Interrupts
     Enable Timer0
     Enable Int0

     On Int0 Dodaj
     On Timer0 Przerwanie

  Do
  Loop

     Przerwanie:
        Load Timer0 = 40
        Wynik = Wynik * 50
        Lcd Wynik
        Wynik = 0
     Return

     Dodaj:
        Incr Wynik
     Return
End
Link do komentarza
Share on other sites

Co jest źródłem impulsów, i skąd wiesz, że źródło to daje stałą ich liczbę?

Dałeś niecały kod, nie znam polecenia Load Timer, wartości do timerów przypisuje się bezpośrednio Timer0=40. Wydaje mi się, że to ci się nawet nie kompiluje.

Link do komentarza
Share on other sites

Jest takie polecenie load timer, ale składnia jest inna.

Load Timer0, 40

[ Dodano: 11-02-2011, 12:27 ]

Zdaje się że one działają na odwrót. Wpisanie Load Timer0, 40 spowoduje, że po 40 impulsach timer się przepełnia. Wpisanie Timer0 = 40 powoduje, że w liczniku jest wartość 40, więc przepełni sie po 256-40=216 impulsach (dla 8 bitowego licznika).

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Wprowadziłem już zmiany.

Źródłem sygnału był generator funkcyjny, generujący na wyjściu fala prostokątna w standardzie TTL.

Sprawdzę jak sprawuje się teraz kontroler.

Jeśli ktoś posiada pomysł na zmiany w programie jestem otwarty na różne propozycje.

Link do komentarza
Share on other sites

Co do twojego kodu to brakuje ci

CONFIG INTx = LOW LEVEL | RISING | FALLING [ | CHANGE ]

gdzie:

x	numer przerwania zewnętrznego 0 lub 1, a dla AVR MEGA także 4 – 7

I moim zdaniem żeby odliczyć 1 sekundę proponuję.

Config Portb.3 = Output                        
'Konfigurujemy Portd.0 jako wyjście.
Set Portb.3

Config Timer0 = Timer , Prescale = 1024                     

On Timer0 Sekunda                          'Podprogram Sekunda dla Timer0

Dim Aa As Word

Enable Interrupts                             'Zgoda na wszystkie odblokowania.

Enable Timer0                                 'Odblokuj Timer0.
Start Timer0                                   'Start Timer0.

Do

Loop

End                                               'Koniec pętli.

Sekunda:
Timer0 = 40                                  'Wpisana wartość do Timer0, odliczy 216.
                                                   'Podprogram.
Incr Aa
If Aa = 50 Then
Aa = 0
  Toggle Portb.3                            'Zmień stan wyjścia Portb.3 na przeciwny.
End If
Return

A tak ogólnie co chciałeś zrobić.

To ma być miernik częstotliwości??

Link do komentarza
Share on other sites

Program ma służyć do zliczania impulsów z enkodera inkrementalnego o rozdzielczości 8192 na jeden pełen obrót.

Następnie ma wyświetlacz wartość obrotów na minute.

W kodzie programu pominąłem dzielenie zmiennej wynik przez 8129 dla uproszczenia oraz przemnożenie przez 60 by uzyskać minute.

Link do komentarza
Share on other sites

Już pracuje nad nowym programem tylko zastanawia mnie jak rozwiązać jeden z podprogramów.

Aktualnie nie mam dostępu do układu by przetestować to w praktyce.

Mianowice do zmiennej wartość będą "spływać" impulsy z enkodera, jeden pełny obrót to 8192 ; następnie tą ilość impulsów muszę przemnożyć przez 3000 aby uzyskać ilość obrotów na minute (50*60 zebu na sekundę a potem na minute).

Można to zrobić na 2 sposoby:

Wynik = Wynik * 60
Wynik = Wynik / 8192
Wynik = Wynik * 50 

Lub

Wynik = Wynik / 8192 
Wynik = Wynik *3000

Stąd moje pytanie czy różne sposoby obliczanie tej samej wartości mogą wpłynąć na dokładność wyniku ?

Czy jest to bardzo nieznaczny stopień.

Link do komentarza
Share on other sites

Rozwiązanie pierwsze jest lepsze, a najlepiej od razu mnożyć razy 3000, tylko jest pewno ale: przepełnienia. Proponuję zrobić tak:

unsigned long int wynik;

...

wynik = pomiar*3000;

wynik = wynik/8192;

A nawet lepiej:

wynik = pomiar*375;

wynik = wynik/1024;

Link do komentarza
Share on other sites

Twój pomysł OldSkull jest bardzo dobry.

Ciekawi mnie ten

unsigned long int wynik;
wydaje mi się że te polecenie ustala wynik jako wartość całkowitą 8 bitową.

Nauka C jest dopiero przede mną, wiec mogę się mylić.

Program ma być pisany w Bascomie wiec prawdopodobnie użyje

ROUND( wynik )-Zwraca liczbę zaokrągloną do najbliższej wartości całkowitej, albo podobnej.

Link do komentarza
Share on other sites

aa, nie zapytałem się, jakiego typu masz zmienne. Long int jest zmienną 32b (chociaż w gcc dla AVRów w rzeczywistości 23-24b, potem następuje przepełnienie). Jeśli masz zmiennoprzecinkowe to juz inna historia, ale pamiętaj, że dzielenie zmiennoprzecinkowe na procesorze bez jednostki zmiennoprzecinkowej jest bardzo czasochłonne.

Link do komentarza
Share on other sites

Co do odliczania proponuje mój program tylko zamiast zmiany stanu portu, zamienić na jaką zmienną bitową i wywoływać podprogram. A enkoder podłączyć pod jeden z pinów procesora INTx.

Po skoku do programu zatrzymać przerwanie INTx (disable)i odczytać ilość zliczonych impulsów z enkodera i zerować zmienną a nastepnie puścić go znowu(enable)

Link do komentarza
Share on other sites

Witam

Program przeszedł pewną ewolucję, wygląda teraz następująco

 Config Timer0 = Timer , Prescale = 1024
     Config Pind.2 = Input

     Dim Wynik As Long
     Dim Cc As Word
     Timer0 = 40

     Enable Interrupts
     Enable Timer0
     Enable Int0

     On Int0 Dodaj
     On Timer0 Przerwanie

  Do

  Loop

     Przerwanie:
        Timer0 = 40

        Incr Cc
        If Cc = 1024 Then

        Disable Int0
        Disable Timer0
        Wynik = Wynik * 375

        Lcd Wynik
        Waitms 500
        Wynik = 0
        Timer0 = 40
        Enable Int0
        Enable Timer0
        End If
     Return

     Dodaj:
        Incr Wynik
     Return
End

Zastosowałem kilka rad , choć nie dokończa zrozumiałem sens zerowanie zmiennej bajtowe oraz z czym ja powiązać.

Aktualnie kontroler ma kłopot z zliczanie i na wyświetlaczu pojawia się 0.

Zastanawiam się nad kolejną zmianą w programie.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.