Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

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

67Łukasz67 23 Nov 2013 14:50 2427 13
  • #1
    67Łukasz67
    Level 9  
    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:

    Code: c
    Log in, to see the code
  • #2
    excray
    Level 40  
    Zmienne flaga i flaga1 powinny być volatile. Poza tym przemyśl jeszcze raz ten warunek bo on aż roi się od błędów:
    Code: c
    Log in, to see the code
  • #3
    67Łukasz67
    Level 9  
    Faktycznie, moje niedopatrzenie bawiłem się kodem zanim go umieściłem i nie poprawiłem :)

    Zatem zmieniłem

    Code: c
    Log in, to see the code


    aczkolwiek wprowadzone zmiany nadal powodują ciągłe się świecenie diody LED
  • #4
    excray
    Level 40  
    Bo dalej masz błędy w warunku. Błędy typu & -> && i = -> == Poszukaj czym te operatory różnią się od siebie. Przemyśl też sobie
    Code: c
    Log in, to see the code
    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
    67Łukasz67
    Level 9  
    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
    excray
    Level 40  
    67Łukasz67 wrote:
    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.
  • #7
    zumek
    Level 39  
    67Łukasz67 wrote:
    Z programowaniem w C za pan brat nie jestem ...

    Z ATMega32 chyba też nie :-P

    Code: c
    Log in, to see the code

    A producent w dokumentacji twierdzi, że ...
    Output Compare Register (OCR0) are 8-bit register
  • #8
    excray
    Level 40  
    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
    zumek
    Level 39  
    excray wrote:
    ... 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 ...
    Code: c
    Log in, to see the code

    ...można np.
    Code: c
    Log in, to see the code
    ... i obędzie się bez przerwań.
  • #11
    67Łukasz67
    Level 9  
    Poprawiłem warunek else na następujący
    Code: c
    Log in, to see the code

    zaś flagi zdeklarowałem następująco
    Code: c
    Log in, to see the code

    co w efekcie dało cały kod następujący
    Code: c
    Log in, to see the code


    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
    dondu
    Moderator on vacation ...
    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
    67Łukasz67
    Level 9  
    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 :)
    Code: c
    Log in, to see the code


    Ewentualnie jakieś pomysły na optymalizację ? Lub karygodne błędy ?:)
  • #14
    BlueDraco
    MCUs specialist
    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

    ?!