Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Atmega wyświetlacz częstotliwości

Duch__ 08 Maj 2007 19:45 2399 8
  • #1 08 Maj 2007 19:45
    Duch__
    Poziom 31  

    Witam.
    Szukam pomocy z waszej strony. Musze napisać program na Atmege8 dla pewnego urządzenia (narazie nie zdradzę co to będzie ale napewno zamieszczę w DIY). Do uC będzie podpięty czujnik Z1 który będzie zliczał impulsy, dioda LED, i cztery przyciski S1 i S2 oraz S3 i S4. Układ ma za zadanie generować stany 0 i 1 tak by dioda LED migała. Za pomocą przycisków S1 i S2 ma być zmieniana ilość błysków na sekundę od 1 do 50, natomiast za pomocą S3 i S4 regulować czas trwania tych błysków od 0,01s do 0,1s. Po otrzymaniu przez czujnik Z1 drugiego impulsu program ma się zacząć od nowa odrazu z zapamiętaniem ustawień pozycji przycisków S1, S2, S3 i S4. Czujnik w tym wypadku ma być zastosowany aby układ wiedział kiedy ma zacząć prog od nowa.

    Macie jakieś przykłady programów na moje wymagania??

    Za wszystkie propozycje z góry dziękuje.

    0 8
  • #2 08 Maj 2007 20:42
    wader_669
    Poziom 28  

    ja ci radze zrobic to w bascomie. nauka moze ci troche zajac moze dzien ale jak nauczysz sie to ten proram napiszesz w 10 min
    kup sobie ksiazke nie powiem ze jest super ale napewno ci pomoze albo sciagnij polskiego helpa do bascoma

    0
  • #3 09 Maj 2007 12:15
    Ch.M.
    Poziom 27  

    Wieczorkiem spróbuje coś ci naskrobać (ASM), Napisz dokładnie jaki ma byc krok przy nacisnieciu przycisku (ile kroków regulacji dla czestotliwosci i długości impulsu).
    Rozumiem ze po zmianie 1 zmiennej druga musi pozostać nie zmieniona, to troszke komplikuje program, ale na p[ewno na 16bitowym PWMie można to osiągnąć.
    Pozdro

    0
  • #4 09 Maj 2007 12:50
    Duch__
    Poziom 31  

    Dobra to rezygnuje z tych przycisków od S3 i S4. Niech będzie regulowana tylko częstotliwość błysków. Częstotliwość błysków niech się zaczyna na poziomie 10/s z tym że prosił bym o zaznaczenie tego miejsca w programie przez jakiś komentarz. Przyciskami S1 chce zmniejszać częstotliwość o 1 a S2 wzwiększać o 1. No i oczywiście ten czujnik - co drugi sygnał ma rozpocząć program od nowa. Prosił bym jak byś jeszcze w formie komentarza opisał które piny w Atmedze wykorzystujesz jeśli będziesz pisał w ASM, w C nie musisz. Dzięki za zainteresowanie.

    0
  • #5 10 Maj 2007 09:05
    Ch.M.
    Poziom 27  

    Rozumiem że ma to wygladać tak:
    1) f=10-100Hz plus sto kroków nastaw ?
    czy
    2) f=10-100Hz plus 10 kroków nastaw?

    Oczywiscie rozumiem ze dodatkowe wejscie (np przycisk lub costam innego) powoduje restatr... i do tego co drugie wciśniecie ... no dobra
    ile czasu trwa ten impuls wyzwalający start/restart i co ile czasu może nastąpić?

    zaraz coś napisze
    Pozdro

    0
  • #6 10 Maj 2007 10:47
    Duch__
    Poziom 31  

    Czujnik będzie zwierny 25razy na sekunde ale restart ma być wykonywany co dwa zwarcia czujnika czyli 25/2=12,5, czyli co około 80ms. f=10-100Hz plus sto kroków nastaw.

    Pozdrawiam.

    0
  • Pomocny post
    #7 10 Maj 2007 12:53
    Ch.M.
    Poziom 27  

    No Dobra program juz prawie napisałem i głowiłem sie nad wersja ze zmiennym PWM+f... ale z tego co mi odpisałes to wnioskuję ze coś tu mi nie gra...
    A nie możnaby programowo realizować ten restart co 80ms?
    Moze napisz dokładniej co to ma być a coś doradzimy :)
    Pozdro


    No wlasnie o to chodziło by nie restartorwać tego zewnetrznie bo chyba prosciej zaimplementowac to w procesorze skoro to jest akcja cykliczna.
    a swoją droga to jest bez sensu resetować go co chwile, po to by tylko przesunąć w fazie (w czasie) moment zapalenia diody, ale rozumiem ze to wersja rozwojowa i bedziesz wzbogacał efekty :)

    .org 0x00
    rjmp Reset
    nop
    nop
    nop
    rjmp impuls

    .org 0xFF
    .include "m8def.inc"

    Reset:
    .equ wejscie = PORTC ; nazywam PORTC wejsciowym
    .equ plus_f = 0 ; Deklaruje poszczegolne wyprowadzenia nazwami symbolicznymi
    .equ minus_f = 1 ; Zmniejsza częstotliwosc sygnalu
    .equ plus_PWM = 2
    .equ minus_PWM = 3 ; zmniejsza wypełnienie (czas trwania "blysku")
    .equ costam = 4 ; odpowiedzialne za daną akcje

    ldi R16, high(RAMEND) ; Inicjuje stos (pewnie sie nie przyda ale tak NALEZY robic0
    out SPH, R16
    ldi R16, low(RAMEND)
    out SPL, R16

    ldi R16, 0b00000000 ; Ustawiam cały portC jako wejściowy ( zakładam, że przyciski
    out DDRC, R16 ; będa podciagane do plusa rezystorem, a zwarcie ich z masą
    ; będzie powodowało niski stan na wejsciu uC i przypisana akcje)
    ldi R16, 0b00000010
    out DDRB, R16 ; Ustawiam pin B1jako wyjście
    sei ; odblokowuje zezwolenie na przerwania

    rcall generator

    ;=======================================================================================
    Petla_glowna: ; |
    rcall sprawdz_przyciski ; Odwołanie do podprogramu sprawdzającego stan wejsc |
    rcall czekaj_50ms ; Oczekiwanie 50ms by wyeliminowac drgania przyciskow |
    rjmp Petla_glowna ; Skaczemy do poczatku programu glownego |
    ;=======================================================================================

    sprawdz_przyciski:

    sbis wejscie, plus_f ; Jesli dany przycisk jest w stanie wysokim, to pomijam kolejna instrukcje
    rcall zwieksz_f ; Jesli jest w stanie niskim to skacze do podprogramu zwieksz_f
    sbis wejscie, minus_f ; Zamiana sbis na sbic spowoduje odwrocenie sytuacj, tzn:
    rcall zmniejsz_f ; wyzwalanie stanem wysokim (wykonanie instrukcji zaraz po tym poleceniu)
    ; sbis wejscie, plus_PWM
    ; rcall zwieksz_PWM
    ; sbis wejscie, minus_PWM
    ; rcall zmniejsz_PWM
    sbis wejscie, costam
    rjmp reset ; mozeesz wylaczyc te 2 linie linie dwukropkiem




    ret ; Powoduje powrot z podprogramu, tzn do petli glownej


    Zwieksz_f: ; w rejestrze R20 zapisujemy aktualne wypełnienie
    inc R20 ; powodujemy zwiększenie R20
    out OCR2, R20 ; wprowadzamy zmiane do rejestru licznika
    ret ; powrot z podprogramu tzn, do sprawdz_przyciski

    Zmniejsz_f:
    dec R20 ; Kazda instrukcja DEC zmniejsza wartosc R20 o jeden
    out OCR2, R20 ; wprowadzamy zmiane do rejestru licznika
    ret

    Zwieksz_PWM: ; Jak poprzednio, ale zwiększamy wypełnienie
    inc R21
    ret

    Zmniejsz_PWM:
    dec R21
    ret

    Czekaj_50ms: ; uruchamiam timer T0 i czekam az zliczy do ok 250ms
    ; dla zegara 8MHz
    ldi R16, 0b00011000
    out TIFR, R16 ; zerujemy TIFR
    ldi R16, 0b10001000
    out OCR1AL, R16
    ldi R16, 1
    out OCR1AH, R16
    ldi R16, 0b00001101
    out TCCR1B, R16
    czekam_50ms_TIFR:
    in R16, TIFR
    sbrs R16, 4 ; czekam na ustawienie OCF1A
    rjmp Czekam_50ms_TIFR
    ldi R16, 0
    out TIFR, R16 ; wyłączamy timer
    ret

    Generator: ; odpalam T2 jako TCT (licznik zlicza az do zadanej liczby a nastepnie generuje przerwanie
    ldi R16, 0b10000000 ; zezwalamy na przerwania od timera
    out TIMSK, R16

    ldi R20, 100 ; f=1Mhz/(512*R20) czyli w twoim przypadku od 20 do 200 (100-10Kz)
    out OCR2, R20 ; licznik zlicza do zadanej R20 liczby nastepnie generuje przerwanie

    ldi R16, 0b00001110
    out TCCR2, R16
    ret

    impuls: ;generujemy stan wysoki na wybranej nozce
    sbi PORTB, 1 ; ustawia pin B1 w stan wysoki
    nop ; nop=nic, ustawiasz ile cykli zegarowych ma trwac impuls
    nop
    nop
    nop
    nop
    nop
    nop
    rcall Czekaj_50ms ; zamiast nopow :)
    nop
    cbi PORTB, 1 ; przeciwnie do sbi, ustawia stan niski
    rjmp Petla_glowna


    P.S. Niestety nie wiem czym zastąpić TAB, w AVR Studio wyglada to ładnie, ale niestety tutaj to tak sobie a nie mam całego dnia na edycje kodu html :)
    Pytaj jeśli czegos nie rozumiesz, kod oczywiscie jest do dopisania, bo zauwazyles ze zwiekszam R20 tylko o 1 i nie ma ustawionych limitow gorny (20) i dolny (200) nastawianej czestotliwości.
    jesli sobie ie poradzisz to dopisze, moze zachecilem do poznania ASM, moze nie
    Pozdro

    0
  • #8 10 Maj 2007 13:03
    Duch__
    Poziom 31  

    Ch.M. napisał:
    No Dobra program juz prawie napisałem i głowiłem sie nad wersja ze zmiennym PWM+f... ale z tego co mi odpisałes to wnioskuję ze coś tu mi nie gra...
    A nie możnaby programowo realizować ten restart co 80ms?
    Moze napisz dokładniej co to ma być a coś doradzimy :)
    Pozdro


    Miał być to efekt laserowy. Podobne rozwiązanie było pokazane w EdW pod nazwą "efekt laserowy". Skoro nie umiesz zrobić by się restartował poprzez czujnik to zrób żeby co 80ms się restartował sam automatycznie.

    0