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.

89cxx51 - problem z programem (assembler)

MooNTER 15 Cze 2006 14:14 1470 18
  • #1 15 Cze 2006 14:14
    MooNTER
    Poziom 12  

    w programie chodzi o to,ze:
    - powinien oczekiwac na zero logiczne na p1.3
    - jesli pojawi sie to "0" powinien odmierzyc czas i po tym czasie wykonac procedure (***), chyba ze na /t0 zostana podane dwa impulsy, wtedy ma nic nie wlaczyc i czekac az na p1.3 pojawi sie "1" i od nowa program
    - przy 1 na p1.3 powinien sprawdzac, czy na /int nie pojawil sie impuls, jesli sie pojawil ma sie wlaczyc procedura (***)

    procedura (***) polega na czasowym wlaczaniu i wylaczaniu pinu p1.4 (kilka takich cykli po czym koniec)

    oto moj program:

    Code:

    ORG 000H
    LJMP START                 ;IDZ DO START
    ORG 000BH            ;PRZERWANIE OD T0
    LJMP PRZERW_T0
    ORG 001BH             ;PRZERWANIE OD T1
    LJMP PRZERW_T1
    ORG 0013H            ;PRZERWANIE OD INT1
    LJMP PRZERW_INT1

    START:
    LICZNIK EQU 0

    LICZ_ALARM EQU 0
    SETB ET0                  ;ODBLOKUJ T0
    SETB ET1                   ;ODBLOKUJ T1
    SETB EX1            ;ODBLOKUJ /INT1
    SETB EA                    ;ODBLOKUJ PRZERWANIA
    CLR P1.4                      ;WYLACZ TO CO JEST NA P1.4
    CLR P1.3
    LJMP PETLA_OTWARCIA
    PETLA_OTWARCIA:               ;SPRAWDZA CZY JEST SYGNAL ("0") NA P1.3
    JB P1.3,PETLA_OTWARCIA        ;JESLI 1 TO PETLA W KOLO

    MOV  TMOD,#00010110B         ;USTAW T0 W TRYB ZLICZ IMP.          ;WEJSC,T1-ODMIERZA CZAS



             ;A TERAZ WLACZAMY T0:
    MOV TH0,#0FEh              ;FEh=256-2=254 CZYLI ZLICZA 2             ;IMPULSY
    MOV TL0,TH0            ;konieczne!
    SETB TR0            ;WLACZA LICZNIK T0

    LJMP TAJMER
    TAJMER:

             ;TERAZ WLACZAMY T1:
    MOV TH1,#03CH      ;DLA KWARCU 6MHz 600 PRZEPELNIEN TO             ;5S
    MOV TL1,#0B0H      ; 1 PRZEPELNIENIE CO 8,(3)ms

    LJMP TAJMERSTART
    TAJMERSTART:

    SETB TR1      ;WLACZA T1




    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;TU JEST PRZERWANIE LICZNIKA CZASU ;;




    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



    PRZERW_T1:
    INC LICZNIK
    LJMP WKOLO
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;TU JEST GLOWNY PROGRAM;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    WKOLO:

    MOV A,#00H
    MOV A,LICZNIK
    CJNE A,#064h,NEXT      ;CZY LICZNIK SIE ZAPELNIL
    ZAMK:
    CLR TR1         ;ZATRZYMAJ T1
    MOV LICZNIK,#0      ;JEZELI LICZNIK SIE ZAPELNI WYZERUJ
    INC LICZ_ALARM      ;ZWIEKSZ LICZ_ALARM O 1

    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#01H,DWA
    SETB P1.4
    LJMP TAJMERSTART

    NEXT:
    JB P1.3,ZAMK   ;JESLI ZAMKNIETO SKOCZ
    LJMP WKOLO

    DWA:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#02H,TRZY
    LJMP TAJMERSTART

    TRZY:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#03H,CZTERY
    CLR P1.4
    LJMP TAJMERSTART

    CZTERY:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#04H,PIEC
    LJMP TAJMERSTART

    PIEC:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#05H,SZESC
    SETB P1.4
    LJMP TAJMERSTART

    SZESC:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#06H,SIEDEM
    LJMP TAJMERSTART

    SIEDEM:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#07H,OSIEM
    CLR P1.4
    LJMP TAJMERSTART

    OSIEM:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#08H,DZIEWIEC
    LJMP TAJMERSTART

    DZIEWIEC:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#09H,DZIESIEC
    SETB P1.4
    LJMP TAJMERSTART

    DZIESIEC:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#0AH,JEDENASCIE
    LJMP TAJMERSTART

    JEDENASCIE:
    MOV A,00H
    MOV A,LICZ_ALARM
    CJNE A,#0BH,POZOSTALE
    CLR P1.4
    MOV LICZ_ALARM,#00H   ;ZERUJ LICZ_ALARM
    WAIT:
    JB P1.3,TRALALA
    LJMP WAIT

    POZOSTALE:
    MOV LICZ_ALARM,#00H   ;ZERUJ LICZ_ALARM

    RETI



    PRZERW_T0:
    LJMP PRZERWANIE

    PRZERWANIE:
    MOV LICZ_ALARM,00H   ;USTAW LICZ_ALARM NA ZERO
    CLR P1.4      ;WYLACZ TO CO JEST NA P1.4
    LJMP CZEKAJ
    CZEKAJ:
    JNB P1.3,CZEKAJ       ;CZEKAJ NA "1" NA P1.3
    LJMP START      ;JAK NIE MA TO DALEJ CZEKAJ

    RETI

    PRZERW_INT1:

    LJMP ZAMK   ;SKOCZ DO ZAMK W PRZERW_T1

    RETI

    TRALALA:
    LJMP START



    END


    teraz pytanie: co w nim namieszalem???

    0 18
  • #2 15 Cze 2006 14:39
    GienekS
    Poziom 32  

    To ty najlepiej wiesz co namieszałeś. A nic nie napisałeś jakie masz objawy, program na pewno chodzi dobrze to z reguły namiesza programista.

    0
  • #3 15 Cze 2006 14:46
    MooNTER
    Poziom 12  

    Troche zle zadalem pytanie: generalnie interesuje mnie tylko czy nie mieszam cos przy ustawieniu zegara, czy czegos tam zle nie ustawiam (moze cos trzeba dopisac??)
    Rozumiem ze od technicznej strony jesli na nozke podam +5V to mam "1" logiczna, jesli odlacze to mam "0"?

    0
  • #4 15 Cze 2006 15:02
    zumek
    Poziom 39  

    Wybacz przyjacielu ;) , ale ten kod to "obraz nędzy i rozpaczy" i ma się nijak do Twoich założeń , a tym bardziej do zasad programowania 51-ek :(

    MooNTER napisał:

    Code:

    CLR P1.3  ;zerujesz P1.3 ???
    LJMP PETLA_OTWARCIA
    PETLA_OTWARCIA:       ;SPRAWDZA CZY JEST SYGNAL ("0") NA P1.3   

    ;ano jest "0" , bo sam je tam wpisałeś

    JB P1.3,PETLA_OTWARCIA        ;JESLI 1 TO PETLA W KOLO
    ...

    LJMP TAJMERSTART
    TAJMERSTART:

    SETB TR1      ;WLACZA T1

    ;teraz "włazisz z buciorami" , do procedury przerwania T1


    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;TU JEST PRZERWANIE LICZNIKA CZASU ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



    PRZERW_T1:

    ;należało by zachować używane rejestry na stosie

    INC LICZNIK
    LJMP WKOLO                                                ; po co ??????
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;TU JEST GLOWNY PROGRAM;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;
    WKOLO:

    MOV A,#00H                    ;zapisujesz 0 do akumulatora , tylko po co ??
    MOV A,LICZNIK
    ...
    MOV A,00H   ; a tu zapisujesz do akumulatora zawartość komórki o adresie 0 - po co ??
    MOV A,LICZ_ALARM
    ...
    LJMP TAJMERSTART ;tu beztrosko "wyskakujesz" do "normalnego" programu !!!

    itd. itp.



    teraz pytanie: co w nim namieszalem???

    Zastanów się i napisz to od nowa :(

    Piotrek

    0
  • #5 15 Cze 2006 19:57
    vedy1
    Poziom 15  

    Cytat:
    w programie chodzi o to,ze:
    - powinien oczekiwac na zero logiczne na p1.3

    Nie lepiej podpiąć pod naóżke p3.2, p3.3 ze względu na przerwania??
    Cytat:

    - jesli pojawi sie to "0" powinien odmierzyc czas i po tym czasie wykonac procedure (***), chyba ze na /t0 zostana podane dwa impulsy,
    Czy aby na pewno masz programowo wyzwalać timer t0, czy może tak jak wyżej czyli przerwania na portach??
    Cytat:

    wtedy ma nic nie wlaczyc i czekac az na p1.3 pojawi sie "1" i od nowa program
    - przy 1 na p1.3 powinien sprawdzac, czy na /int nie pojawil sie impuls, jesli sie pojawil ma sie wlaczyc procedura (***)

    Reszte w miare zrozumiałem.
    Cytat:

    Rozumiem ze od technicznej strony jesli na nozke podam +5V to mam "1" logiczna, jesli odlacze to mam "0"?

    Jak podłączysz +5V to masz "1" ale jak odłączysz (czytaj nie masz nic wiecej podłączone) to masz w zależności czy ustawiałeś na porcie "1" czy "0" będziesz miał to co ustawiłeś.
    Sprecyzuj swoje pytanie.

    0
  • #6 15 Cze 2006 20:13
    zumek
    Poziom 39  

    vedy1 napisał:

    Jak podłączysz +5V to masz "1" ale jak odłączysz (czytaj nie masz nic wiecej podłączone) to masz w zależności czy ustawiałeś na porcie "1" czy "0" będziesz miał to co ustawiłeś...

    Nie polecam podłączać bezpośrednio +5V do pinu , na który procek wystawił "0" :D

    Piotrek

    0
  • #7 16 Cze 2006 19:33
    MooNTER
    Poziom 12  

    vedy1 napisał:

    Nie lepiej podpiąć pod naóżke p3.2, p3.3 ze względu na przerwania??


    moze i lepiej by bylo

    Cytat:
    Czy aby na pewno masz programowo wyzwalać timer t0, czy może tak jak wyżej czyli przerwania na portach??


    chcialbym zeby tymer wyzwalal sie programowo, gdy zmieni sie stan na jednej z nozek

    Cytat:

    Jak podłączysz +5V to masz "1" ale jak odłączysz (czytaj nie masz nic wiecej podłączone) to masz w zależności czy ustawiałeś na porcie "1" czy "0" będziesz miał to co ustawiłeś.
    Sprecyzuj swoje pytanie.


    chodzi mi o wykrywanie zmiany stanu danego pinu. Chyba jednak faktycznie przerzuce sie na int0/int1 i obsluze to przerwaniem.

    Program napisalem od nowa i teraz mam pytanie: przy asemblacji wyskakuje "Zdublowany kod programu w obszarze 27..29 z obszarem 19..274" (asembler to Turbo) Czego to jest przyczyna? kursor zatrzymal sie na
    Code:
    ORG 001BH             ;PRZERWANIE OD T1
    , ale w tym przerwaniu dalem LJMP gdzies dalej wiec nie wiem o co chodzi?? Czy to dlatego ze wybrany jest procesor 8051 i wystarczy wylaczyc sprawdzanie dublowania kodu czy moze jest jakis blad??

    0
  • Pomocny post
    #8 16 Cze 2006 20:00
    zumek
    Poziom 39  

    MooNTER napisał:

    ...
    Program napisalem od nowa i teraz mam pytanie: przy asemblacji wyskakuje "Zdublowany kod programu w obszarze 27..29 z obszarem 19..274" (asembler to Turbo) Czego to jest przyczyna?

    To przypatrz się coś napisał w 1-szym poście (komentarze usunąłem) :D
    Code:

    ORG 000H
    000H,001H,002H  LJMP START           
    ORG 000BH           
    00BH,00CH,00DH LJMP PRZERW_T0
    ORG 001BH           
    01BH,01CH,01DH LJMP PRZERW_T1
    ORG 0013H           
    013H,014H,015H  LJMP PRZERW_INT1

    START:
    LICZNIK EQU 0
    LICZ_ALARM EQU 0
    016H   SETB ET0                 
    017H   SETB ET1                 
    018H   SETB EX1           
    019H   SETB EA             
    01AH   CLR P1.4             
    01BH   CLR P1.3   ;i tu już diabli wzięli LJMP PRZERW_T1

    01CH,01DH,01EH   LJMP PETLA_OTWARCIA

    PETLA_OTWARCIA:   
    01FH   JB P1.3,PETLA_OTWARCIA       
    ...

    Włazi czy nie :?:

    Piotrek

    PS
    Jak powyłączasz ostrzeżenia , to możesz do emerytury nie skończyć tego programiku :D
    Zamień miejscami 2 ostatnie ORG-i i będzie git ;)

    0
  • #9 16 Cze 2006 21:25
    MooNTER
    Poziom 12  

    dzieki, czegos sie nauczylem, program jednak dalej nie dziala :/
    oto on:

    Code:

    ORG 000H
    LJMP START                 ;IDZ DO START
    ORG 000BH            ;PRZERWANIE OD T0
    LJMP PRZERW_T0
    ORG 0013H            ;PRZERWANIE OD INT1
    LJMP PRZERW_INT1
    ORG 001BH             ;PRZERWANIE OD T1
    LJMP PRZERW_T1
    ORG 003BH         ;PRZERWANIE OD INT0
    LJMP PRZERW_INT0

    START:
    LICZNIK EQU 0
    LICZNIK_JEDEN EQU 0
    LICZNIK_IMPULSOW EQU 0
    SETB ET0                  ;ODBLOKUJ T0
    SETB ET1                   ;ODBLOKUJ T1       
    SETB EX1            ;ODBLOKUJ /INT1   
    SETB EA                    ;ODBLOKUJ PRZERWANIA
    CLR P1.4                      ;WYLACZ PIN 1.4
    SETB IT1
    SETB IT0
    PAUZA:
    LJMP PAUZA


    PRZERWANIE_INT0:

    MOV  TMOD,#00010110B         ;USTAW T0 W TRYB ZLICZ IMP.          ;WEJSC,T1-ODMIERZA CZAS


             ;TERAZ WLACZAMY T1: 5)
    MOV TH1,#03CH      ;DLA KWARCU 12MHz             
    MOV TL1,#0B0H      ; 1 PRZEPELNIENIE CO 0,05S
    SETB TR1      ;WLACZA T1


             ;A TERAZ WLACZAMY T0:  6)
    MOV TH0,#0FEh              ;FEh=256-2=254 CZYLI ZLICZA 2             ;IMPULSY
    MOV TL0,TH0            ;konieczne!
    SETB TR0            ;WLACZA LICZNIK T0



    NIE:                   ;SPRAWDZA CZY JEST 1 NA 3.2 7)
    JB P3.2,LICZ_IMPULSOW       ;JESLI NIEZAMKNIETO IDZ DALEJ JESLI ZAMKNIETO SKOCZ
    TUTAJ:
    MOV A,#00H      ; 8)
    MOV A,#LICZNIK
    CJNE A,#064h,NIE   ;JESLI LICZNIK SIE NIE ZAPELNIL SKOCZ DO NIE
             ;JESLI SIE ZAPELNIL SPRAWDZ LICZNIK_IMPULSOW


    LICZ_IMPULSOW:      ;ZAMKNIETO OBUDOWE W 7)
    MOV A,#00H      ; 9)
    MOV A,#LICZNIK_IMPULSOW
    CJNE A,#01H,WLACZ_JEDEN   ;JEZELI LICZNIK_IMPULSOW SIE ZAPELNIL IDZ DALEJ
             

    KONCOWKA:
    MOV LICZNIK_JEDEN,#00H   ;ZERUJ LICZ_JEDEN
    CLR TR1         ;ZATRZYMAJ T1
    MOV LICZNIK,#00H
    CLR P1.4
    LJMP PAUZA





    WLACZ_JEDEN:      ; 10) I 11)
    CLR TR1         ;ZATRZYMAJ T1   
    MOV TH1,#03CH      ;DLA KWARCU 12MHz             
    MOV TL1,#0B0H      ; 1 PRZEPELNIENIE CO 0,05S
    MOV LICZNIK,#00H
    INC LICZNIK_JEDEN

    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#01H,DWA
    SETB P1.4      ;URUCHOM PIN 1.4
    SETB TR1      ;START LICZNIKA
    LJMP TUTAJ

    DWA:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#02H,TRZY
    CLR P1.4
    SETB TR1
    LJMP TUTAJ

    TRZY:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#03H,CZTERY
    SETB P1.4
    SETB TR1
    LJMP TUTAJ

    CZTERY:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#04H,PIEC
    CLR P1.4
    SETB TR1
    LJMP TUTAJ

    PIEC:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#05H,SZESC
    SETB P1.4
    SETB TR1
    LJMP TUTAJ

    SZESC:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#06H,SIEDEM
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
          

    SIEDEM:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#07H,OSIEM
    SETB P1.4
    SETB TR1
    LJMP TUTAJ

    OSIEM:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#08H,DZIEWIEC
    CLR P1.4
    SETB TR1
    LJMP TUTAJ

    DZIEWIEC:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#09H,DZIESIEC
    SETB P1.4
    SETB TR1
    LJMP TUTAJ

    DZIESIEC:
    MOV A,#00H
    MOV A,#LICZNIK_JEDEN
    CJNE A,#0AH,JEDENASCIE
    CLR P1.4
    SETB TR1
    LJMP TUTAJ

    JEDENASCIE:
    LJMP KONCOWKA
    RETI



    PRZERWANIE_T1:
    INC LICZNIK      ;14)
    CLR TR1         ;15)
    MOV TH1,#03CH      ;DLA KWARCU 12MHz             
    MOV TL1,#0B0H      ; 1 PRZEPELNIENIE CO 0,05S
    SETB TR1      ;15)
    LJMP TUTAJ      ;16)
    RETI

    PRZERWANIE_T0:
    INC LICZNIK_IMPULSOW    ;18)
    LJMP TUTAJ      ;19)
    RETI

    PRZERW_T1:      ;13)
    LJMP PRZERWANIE_T1


    PRZERW_T0:      ;17)
    LJMP PRZERWANIE_T0

    PRZERW_INT1:      ; 20)
    LJMP WLACZ_JEDEN   ;21)
    RETI

    PRZERW_INT0:
    LJMP PRZERWANIE_INT0

    END


    wiem ze te skoki na koncu sa niepotrzebne ale tez nic nie szkodza, to pozostalosci po kombinowaniu z dublowaniem...

    a oto algorytm pod jaki pisalem ten program:

    START
    ODBLOKUJ PRZERWANIA
    WYLACZ PIN 1.4
    PETLA W KOLO (NIC NIE ROBIACA)
    KONIEC


    PRZERWANIE OD T1:
    ZWIEKSZ LICZNIK O 1
    USTAW TH1 TL1
    IDZ DO TUTAJ
    RETI

    PRZERWANIE OD T0:
    ZWIEKSZ LICZNIK IMPULSOW O 1
    IDZ DO TUTAJ
    RETI

    PRZERWANIE OD INT0:
    URUCHOM TIMER1 NA CZAS, T0 NA IMPULSY
    SPRAWDZ CZY JEST 1 NA P3.2 JESLI NIE:
    SPRAWDZ CZY LICZNIK ODLICZYL CZAS
    JESLI TAK: SPRAWDZ CZY LICZNIK IMPULSOW ODLICZYL IMPULSY
    JESLI LICZNIK POWYZEJ ODLICZYL CZAS SKOCZDO SPRAWDZANIA LICZNIKA IMPULSOW JESLI NIE ZAPETL DO SPRAWDZANIA CZY JEST 1 NA P3.2
    JESLI LICZNIK IMPULSOW SIE ZAPELNIL IDZ DO POCZATKU PROGRAMU
    JESLI NIE (***) PODAWAJ NA WYJSCIE P1.4 RAZ 1 RAZ 0 (CO JAKIS CZAS OKRESLONY TIMEREM), PO 11 CYKLACH ZAKONCZ PROGRAM
    RETI

    PRZERWANIE OD INT1:
    IDZ DO (***)
    RETI

    Teraz wymyslilem ze nie moge (?) skoczyc z przerwania do procedury z innego przerwania?
    z gory dzieki wszystkim za pomoc!

    0
  • #10 16 Cze 2006 22:39
    zumek
    Poziom 39  

    MooNTER napisał:
    dzieki, czegos sie nauczylem ...

    Chyba raczej nie :cry:
    Popełniasz szkolne błędy i chyba nie korzystasz z żadnej "pomocy".
    Code:

    ORG 003BH         ;PRZERWANIE OD INT0
    LJMP PRZERW_INT0

    To na pewno dobry adres :?:
    Code:

    START:
    LICZNIK EQU 0   
    LICZNIK_JEDEN EQU 0
    LICZNIK_IMPULSOW EQU 0

    Trzy "zmienne" pod tym samym adresem :?:
    Code:

    MOV A,#00H      ;to jest raczej niepotrzebne
    MOV A,#LICZNIK  ;zapisz w akumulatorze adres zmiennej LICZNIK
    ;powinn być
    MOV A,LICZNIK  ;zapisz w akumulatorze zawartość zmiennej LICZNIK

    Przecież to 2 takie same instrukcje , gdyż LICZNIK EQU 0 :!:
    Popraw się , bo będzie źle :D

    Piotrek

    0
  • #11 16 Cze 2006 23:04
    MooNTER
    Poziom 12  

    zumek napisał:

    ORG 003BH

    To na pewno dobry adres :?:


    NIE, juz sie poprawiam
    Cytat:

    Code:

    START:
    LICZNIK EQU 0   
    LICZNIK_JEDEN EQU 0
    LICZNIK_IMPULSOW EQU 0

    Trzy "zmienne" pod tym samym adresem :?:


    ja to rozumialem tak, ze musze na poczatku zdefiniowac typ zmiennej i jej wartosc (zmienna EQU wartosc). Po equ mam podac adres gdzie ma siedziec ta zmienna ??
    Cytat:

    Code:

    MOV A,#00H      ;to jest raczej niepotrzebne[/quote]
    no w sumie tak
    [quote]
    MOV A,#LICZNIK  ;zapisz w akumulatorze adres zmiennej LICZNIK
    ;powinn być
    MOV A,LICZNIK  ;zapisz w akumulatorze zawartość zmiennej LICZNIK

    Piotrek


    ok dzieki :)[/quote]

    0
  • #12 17 Cze 2006 11:51
    MooNTER
    Poziom 12  

    dobra, poszukalem lepszego wytlumaczenie, bo z tego co mialem niewiele mozna bylo sie dowiedziec...
    to tak: EQU to stala, ktorej nie mozna zmienic w programie
    jezeli zamienie EQU na DS i dam zmienna DS 1 to zarezerwuje 1 bajt dla tej zmiennej.
    nastepnie po deklaracji wpisalem zera do tych zmiennych:

    Code:
    MOV LICZNIK,#00H  ;itd...
    


    powinno juz zadzialac? cos dalej nie chodzi...

    0
  • #13 17 Cze 2006 15:29
    zumek
    Poziom 39  

    MooNTER napisał:
    ...powinno juz zadzialac? cos dalej nie chodzi...

    Tak napisałeś program , że nie może działać.
    Np. jeśli procek dojdzie do tego miejsca (wykona obsługę INT0)...
    Code:

    PAUZA:
    LJMP PAUZA
    ...
    PRZERWANIE_INT0:
    ...
    NIE:                   ;SPRAWDZA CZY JEST 1 NA 3.2 7)
    JB P3.2,LICZ_IMPULSOW       ;JESLI NIEZAMKNIETO IDZ DALEJ JESLI ZAMKNIETO SKOCZ
    ;tej pętli nie przerwie nic , poza ustawieniem P3.2 na "1"
    ;timery pracują pełną parą , ale nie wykonują sie przerwania od nich
    ;bo procek nadal obsługuje przerwanie o najwyższym priorytecie i mimo ;przepełnień timera , LICZNIK nie zwiększa swojej wartości
    TUTAJ:
    MOV A,#00H      ; 8)
    MOV A,LICZNIK
    CJNE A,#064h,NIE   ;JESLI LICZNIK SIE NIE ZAPELNIL SKOCZ DO NIE
             ;JESLI SIE ZAPELNIL SPRAWDZ LICZNIK_IMPULSOW


    LICZ_IMPULSOW:      ;ZAMKNIETO OBUDOWE W 7)
    MOV A,#00H      ; 9)
    MOV A,#LICZNIK_IMPULSOW
    CJNE A,#01H,WLACZ_JEDEN   ;JEZELI LICZNIK_IMPULSOW SIE ZAPELNIL IDZ DALEJ
             

    KONCOWKA:
    MOV LICZNIK_JEDEN,#00H   ;ZERUJ LICZ_JEDEN
    CLR TR1         ;ZATRZYMAJ T1
    MOV LICZNIK,#00H
    CLR P1.4
    ;jeśli "dojdzie" do poniższego miejsca , to klapa na całej linii , wsystkie ;przerwania , łącznie z INT0 są zablokowane , przez brak rozkazu RETI.
    LJMP PAUZA

    W Twoim kodzie takich "kwiatków" jest więcej :(

    Piotrek

    0
  • #14 18 Cze 2006 12:53
    MooNTER
    Poziom 12  

    Troche poprawilem, nie wiem tylko czy jesli jest:
    1)przerwanie:
    .
    .
    .
    LJMP gdziestam
    RETI

    to czy procesor rozpozna ze jest tu koniec przerwania czy musze najpierw skoczyc a pozniej zakonczyc przerwanie?
    2) w jakims opisie znalazlem zeby wpisac PUSH i POP ale wlasciwie nie wiem co mi to da (bylo to w przypadku licznika czasu) i gdzie to uzyc? czy przez to program mi nie dziala?

    Code:

    ORG 000H
    LJMP START                 ;IDZ DO START
    ORG 0003H         ;PRZERWANIE OD INT0
    LJMP PRZERW_INT0
    ORG 000BH            ;PRZERWANIE OD T0
    LJMP PRZERW_T0
    ORG 0013H            ;PRZERWANIE OD INT1
    LJMP PRZERW_INT1
    ORG 001BH             ;PRZERWANIE OD T1
    LJMP PRZERW_T1
    START:
    LICZNIK DS 1
    LICZNIK_JEDEN DS 1
    SETB ET0                  ;ODBLOKUJ T0 1)
    SETB ET1                   ;ODBLOKUJ T1    1)
    setb EX0   
    SETB EX1            ;ODBLOKUJ /INT1   1)
    SETB EA                    ;ODBLOKUJ PRZERWANIA 1)
    CLR P1.4                      ;WYLACZ COSTAM 2)
    SETB IT1      ;PRIORYTETY PRZERWAN
    SETB IT0      ;...
    SETB PT1
    CLR PT0
    CLR PX1
    CLR PX0
    MOV  TMOD,#00010110B         ;USTAW T0 W TRYB ZLICZ IMP.          ;WEJSC,T1-ODMIERZA CZAS
    MOV TH0,#0FEh              ;FEh=256-2=254 CZYLI ZLICZA 2             ;IMPULSY
    MOV TL0,TH0            ;konieczne!
    MOV TH1,#04CH      ;DLA KWARCU 12MHz             
    MOV TL1,#000H      ; 1 PRZEPELNIENIE CO 0,05S
    PAUZA:
    LJMP PAUZA
    PRZERWANIE_INT0:
             ;TERAZ WLACZAMY T1: 5)
    SETB TR1      ;WLACZA T1
             ;A TERAZ WLACZAMY T0:  6)
    SETB TR0            ;WLACZA LICZNIK T0
    LJMP NIE
    RETI
    NIE:                 
    JB P3.2,WLACZ_JEDEN      ;JESLI NIEZAMKNIETO IDZ DALEJ JESLI ZAMKNIETO SKOCZ
    TUTAJ:
    MOV A,#00H      ; 8)
    MOV A,LICZNIK
    CJNE A,#064h,NIE   ;JESLI LICZNIK SIE NIE ZAPELNIL SKOCZ DO NIE
             ;JESLI SIE ZAPELNIL SPRAWDZ LICZNIK_IMPULSOW
    WLACZ_JEDEN:      ;WLACZA JEDEN 10) I 11)
    CLR TR1         ;ZATRZYMAJ T1   
    MOV TH1,#04CH      ;DLA KWARCU 12MHz             
    MOV TL1,#000H      ; 1 PRZEPELNIENIE CO 0,05S
    MOV LICZNIK,#00H
    INC LICZNIK_JEDEN
    MOV A,#00H
    MOV A,LICZNIK_JEDEN
    CJNE A,#01H,DWA
    SETB P1.4      ;URUCHOM 1.4
    SETB TR1      ;START LICZNIKA
    LJMP TUTAJ
    DWA:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#02H,TRZY
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
    TRZY:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#03H,CZTERY
    SETB P1.4
    SETB TR1
    LJMP TUTAJ
    CZTERY:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#04H,PIEC
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
    PIEC:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#05H,SZESC
    SETB P1.4
    SETB TR1
    LJMP TUTAJ
    SZESC:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#06H,SIEDEM
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
    SIEDEM:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#07H,OSIEM
    SETB P1.4
    SETB TR1
    LJMP TUTAJ
    OSIEM:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#08H,DZIEWIEC
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
    DZIEWIEC:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#09H,DZIESIEC
    SETB P1.4
    SETB TR1
    LJMP TUTAJ
    DZIESIEC:
    MOV A,#00H
    MOV A,liczNIK_JEDEN
    CJNE A,#0AH,JEDENASCIE
    CLR P1.4
    SETB TR1
    LJMP TUTAJ
    JEDENASCIE:
    LJMP KONCOWKA
    PRZERWANIE_T1:
    INC LICZNIK      ;14)
    CLR TR1         ;15)
    MOV TH1,#03CH      ;DLA KWARCU 12MHz             
    MOV TL1,#0B0H      ; 1 PRZEPELNIENIE CO 0,05S
    SETB TR1      ;15)
    LJMP TUTAJ      ;16)
    RETI
    PRZERWANIE_T0:   
    LJMP KONCOWKA      ;19)
    RETI
    PRZERW_T1:      ;13)
    LJMP PRZERWANIE_T1
    PRZERW_T0:      ;17)
    LJMP PRZERWANIE_T0
    PRZERW_INT1:      ; 20)
    LJMP WLACZ_JEDEN   ;21)
    RETI
    PRZERW_INT0:
    LJMP PRZERWANIE_INT0
    KONCOWKA:
    CLR TR1         ;ZATRZYMAJ T1
    MOV LICZNIK_JEDEN,#00H   ;ZERUJ LICZ_JEDEN
    MOV LICZNIK,#00H
    CLR P1.4
    LJMP PAUZA
    END

    0
  • #15 18 Cze 2006 14:10
    GienekS
    Poziom 32  

    MooNTER napisał:
    Troche poprawilem, nie wiem tylko czy jesli jest:
    1)przerwanie:
    .
    .
    .
    LJMP gdziestam
    RETI
    Jeżeli takie coś wykonujesz to musisz to "gdziestam" zakończyć rozkazem RETI Lepiej to "gdziestam" wywołać LCALL ale to musisz pamiętać że musi się kończyć ta procedura rozkazem RET i wtedy będzie to OK!

    0
  • #16 18 Cze 2006 16:04
    MooNTER
    Poziom 12  

    Code:

    LICZNIK DS 1
    LICZNIK_JEDEN DS 1

    PRZERWANIE_T1:
    INC LICZNIK      ;14)
    CLR TR1         ;15)


    doszedlem do tego, ze INC LICZNIK nie zwieksza licznika - dlaczego?
    wlaczylem debuggera i przerwanie z t1 sie uruchamia przechodzi przez ta instrukcje ale nie zwieksza wartosci licznika

    i druga sprawa: normalnie po wykonaniu przerwania program wraca do nastepnego polecenia. Czy da sie zrobic tak, aby po wykonaniu przerwania skoczyl w konkretne miejsce? cos jak LJMP czy LCALL tyle ze one nie zakanczaja dzialania przerwania, ja chcialbym zakonczyc przerwanie (np RETI) ale nie przejsc do nastepnego polecenia w programie a do ustalonego miejsca

    Czy jesli dam tak:
    Code:
    Przerwanie:
    
    .
    .
    LCALL gdziestam
    RETI

    gdziestam:
    ..
    RET
    nastepne instrukcje
    end

    to program wykona instrukcje do LCALL, przejdzie do gdziestam wykona instrukcje do RET, wroci do przerwania, zakonczy to przerwanie i a)Wroci do punktu w ktorym zostal przerwany program i uruchomione przerwanie b) uzna, ze ostatnia wykonywana instrukcja to ta przed RET i po zakonczeniu przerwania wykona nastepna instrukcje po RET ??

    0
  • #17 25 Cze 2006 13:17
    algebro
    Poziom 14  

    MooNTER napisał:

    Czy da sie zrobic tak, aby po wykonaniu przerwania skoczyl w konkretne miejsce? cos jak LJMP czy LCALL tyle ze one nie zakanczaja dzialania przerwania, ja chcialbym zakonczyc przerwanie (np RETI) ale nie przejsc do nastepnego polecenia w programie a do ustalonego miejsca

    Jest to mozliwe, ale trzeba uwazać, aby odpowiednio poustawiać(wyzerować) znaczniki, zdjąć odpowiednia ilość danych ze stosu itd. Coś takiego kiedyś zastosowałem w mioim układzie. Najbezpieczniej jest zakończyć procedurę przerwania rozkazem RETI, ale tuż przed jej wykonaniem zmienić na stosie "oszukany" adres do którego powróci procesor. Ponieważ w czasie przyjecia przerwania, mikrokontroler odkłada adres, do którego ma powrócić, trzeba go zmienić, ale nie naruszjąc wskaźnika stosu:

    Code:
    PRZERWANIE
    
    ...
    ...
    ...          ;to są wykonywane w czasie przerwania instrukcje)
    POP DANA     ;"DANA" to może być pamięć wewn lub rejestr specjalny
    POP DANA     ;który posłuży tutaj do zmniejszenia liczby danych na stosie
    PUSH NOWYL ;młodszy bajt adres nowego adresu skoku
    PUSH NOWYH ;starszy bajt nowego adresu skoku
    RETI


    Rozkazem POP po prostu sciągamy ze stosu prawdziwy adres powrotu i tracimy go, a w jego miejsce kładziemy nowy adres, którego wartość niestety możemy otrzymać czasem dopiero po kompilacji programu :!:
    Trzeba później uważać na zmiany w długości programu przy dopisywaniu linijek, które mogą przesunąć ten adres :!:
    Nowa wartość licznika (adres) musi znajdować się w komórkach NOWY L i H.

    0
  • #18 25 Cze 2006 17:52
    MooNTER
    Poziom 12  

    Udalo mi sie w ten sposob (skacze do miejsce po zakonczeniu przerwania):

    Code:

    przerwanie:
    .
    .
    .
    POP ACC
    POP ACC
    MOV A,#MIEJSCE
    PUSH ACC
    MOV A,#00H
    PUSH ACC
    RETI

    0
  • #19 25 Cze 2006 18:59
    zumek
    Poziom 39  

    MooNTER napisał:
    Udalo mi sie ...

    Ale tylko połowicznie :D
    Code:

    POP ACC
    POP ACC
    MOV A,#MIEJSCE
    PUSH ACC
    MOV A,#00H ; nie zawsze to będzie pierwsze 256 bajtów
    PUSH ACC
    RETI

    Tak można załadować dowolną 16-to bitową daną czy adres , do 8-io bitowych rejestrów , komórek itp.
    Code:

    ...
    mov a,#miejsce-((miejsce/256)*256)
    push acc
    mov a,#miejsce/256
    push acc
    ...


    Piotrek

    0
  Szukaj w 5mln produktów