logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATmega32 - Pomiar czasu między dwoma zboczami narastającymi na INT0 i INT1

67Łukasz67 23 Lis 2013 14:50 2547 13
REKLAMA
  • #1 12983475
    67Łukasz67
    Poziom 9  
    Posty: 6
    Witam jest to pierwszy post na forum więc proszę o wyrozumiałość.

    Chce zrealizować docelowo pomiar czasu pomiędzy dwoma sygnałami podawanych z generatorów o różnej częstotliwości , zaprzęgłem do tego zadania dwa przerwania zewnętrzne INT0 i INT1 ustawione by reagowały na zboczę narastające. Jeżeli pojawi się zbocze narastające z generatora na nóżce PD2 (INT0) ustawiam flagę=1 jeżeli zaś pojawi się zboczę narastające z generatora1 na nóżce PD3 (INT1) ustawiam flagę=1. Jeśli te dwie flagi się sobie równają chce zapalić diodę LED by wiedzieć czy program działa i tu jest problem. Ponieważ dioda cały czas świeci, a nie mruga tak jak przypuszczałem. Prosił bym o pomoc w rozwiązaniu problemu dorzucam kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 12983482
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    Zmienne flaga i flaga1 powinny być volatile. Poza tym przemyśl jeszcze raz ten warunek bo on aż roi się od błędów:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 12983523
    67Łukasz67
    Poziom 9  
    Posty: 6
    Faktycznie, moje niedopatrzenie bawiłem się kodem zanim go umieściłem i nie poprawiłem :)

    Zatem zmieniłem

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    aczkolwiek wprowadzone zmiany nadal powodują ciągłe się świecenie diody LED
  • REKLAMA
  • #4 12983538
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    Bo dalej masz błędy w warunku. Błędy typu & -> && i = -> == Poszukaj czym te operatory różnią się od siebie. Przemyśl też sobie
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    czy ta instrukcja na pewno gasi LEDa? A może robi jednak coś innego?
    Poza tym kto Ci powiedział że masz pisać [syntax= KOD C ] że tak uparcie to wpisujesz?
  • #5 12983564
    67Łukasz67
    Poziom 9  
    Posty: 6
    Z programowaniem w C za pan brat nie jestem i dopiero się uczę :)
    &->&& wpadłem na to po tym jak dodałem post tak to jest jeśli pierw się napisze potem pomyśli.

    Zatem warunek zmienił się na:

    if ((flaga==1) && (flaga1==1)) PORTA=(1<<PA2);

    Kod chciałem, żeby ładnie wyglądał i był przejrzysty, za bardzo nie wiedziałem jak się za to zabrać:)
  • #6 12983584
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    67Łukasz67 napisał:
    Kod chciałem, żeby ładnie wyglądał i był przejrzysty, za bardzo nie wiedziałem jak się za to zabrać

    Dobrze chciałeś ale efekt możesz sobie zauważyć - gorzej niż bez. W tym pierwszym i drugim poście to moderator Ci poprawił. Wybierasz z listy rozwijanej "c" i tyle. A jak chcesz "z palca" pisać to pisz {syntax=c}. Oczywiście nawiasy kwadratowe. Popraw jeszcze ten warunek w else.
  • REKLAMA
  • #7 12983599
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    67Łukasz67 napisał:
    Z programowaniem w C za pan brat nie jestem ...

    Z ATMega32 chyba też nie :-P

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    A producent w dokumentacji twierdzi, że ...
    Output Compare Register (OCR0) are 8-bit register
  • #8 12983616
    excray
    Poziom 41  
    Posty: 5500
    Pomógł: 739
    Ocena: 656
    Poza tym zrobiłeś zmienną volatile ale nie wiadomo jaką bo wywaliłeś typ. Przy okazji to na flagę można zadeklarować mniejszy typ niż int.
  • #9 12983645
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    excray napisał:
    ... Przy okazji to na flagę można zadeklarować mniejszy typ niż int.

    A tak właściwie to po co te zmienne, skoro M32 ma flagi sprzętowe.
    Zamiast ...
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ...można np.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    ... i obędzie się bez przerwań.
  • REKLAMA
  • #11 12987991
    67Łukasz67
    Poziom 9  
    Posty: 6
    Poprawiłem warunek else na następujący
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    zaś flagi zdeklarowałem następująco
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    co w efekcie dało cały kod następujący
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Aczkolwiek nadal nie uzyskałem pożądanego efektu.

    Jeden mierzony sygnał będzie miał stałą wartość ( bynajmniej powinien mieć) ponieważ chodzi o częstotliwość sieciową 50 Hz, drugi ma odpowiadać ilości impulsów które przekazuje enkoder 0-1500 impulsów/min czyli z tego do dobrze liczę od 0 do 40 Hz.

    Tak mogłem przeoczyć, że jest 8-bitowy bo przeniosłem go z timera1, którego jeszcze będę potrzebować.
  • #12 12989858
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Zamieniłeś sprawdzanie INTFx na sprawdzanie zmiennych flaga i flaga1.

    Jeżeli już używać przerwań, to po to, by zawierały jakieś funkcjonalności np. startu i zatrzymania timera, jego odczytu oraz ewentualnie innych istotnych zadań... itp. Wtedy pętla główna powinna zawierać tylko zawartość funkcji generator(). Reszta powinna być w przerwaniach, odpowiednio podzielona.
  • #13 13077070
    67Łukasz67
    Poziom 9  
    Posty: 6
    Całkowicie zapomniałem o temacie :) Z problemem poradziłem sobie w następujący sposób, jest to wycinek z większego programu więc coś może być źle wycięte :)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Ewentualnie jakieś pomysły na optymalizację ? Lub karygodne błędy ?:)
  • #14 13078973
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    volatile double ilosc_imp_na_s; // ilość impusów zliczonych z INT2 w ciągu 1s
    volatile double ilosc_imp_na_s1; // ilość impusów zliczonych z ICP w ciągu 1s

    ?!

Podsumowanie tematu

✨ Użytkownik forum starał się zrealizować pomiar czasu między dwoma sygnałami generowanymi przez różne źródła, wykorzystując przerwania zewnętrzne INT0 i INT1 w mikrokontrolerze ATmega32. W trakcie dyskusji zauważono, że zmienne flagi powinny być zadeklarowane jako volatile, a warunki w kodzie wymagały poprawek, aby poprawnie reagować na zbocza narastające. Użytkownik poprawił kod, zmieniając warunki logiczne oraz typy zmiennych, co doprowadziło do lepszego działania programu. Wskazano również na możliwość wykorzystania flag sprzętowych zamiast zmiennych programowych. Ostatecznie użytkownik rozwiązał problem, implementując dodatkowe funkcjonalności w przerwaniach.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA