Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Atmel 89S8253, proszę o sprawdzenie kodu ASM

darkonel 22 Nov 2009 23:44 2778 11
  • #1
    darkonel
    Level 19  
    Witam. Napisałem kod na procesor jak w temacie, zaprogramowałem go (z małymi problemami, ale po zwiększeniu w programie /Dybkowski/ wartości częstotliwości kwarcu udało się), podłączam LCD i nic. W ogóle nie dochodzi do inicjacji. Podejrzewam, że może coś skopałem przy odczycie z wewnętrznej EEPROM. Proszę o sprawdzenie i/lub ewentualne sugestie. Dziękuję z góry.
    Code:

    name generator          ; nazwa projektu
       org 000h                ; organizacja pamieci
       jmp Progr               ; skok do wykonywania programu
       org 000bh               ; wektor obslugi przerwania od timera T0
       jmp intT0               ; skok do obslugi przerwania
       org 001bh               ; wektor obslugi przerwania od timera T1
       jmp intT1               ; skok do obslugi przerwania
    Progr: ;------------------------
       RegOut  equ P2           ; port wyjsciowy adresowania pamieci 8-bitowej 
       LcdData equ P3          ; port wyswietlacza LCD
       PrzAut  equ P1.5         ; wyprowadzenie przycisku AUTO
       PrzWri  equ P1.6   ; wyprowadzenie przycisku Send
       PrzSet  equ P1.4        ; wyprowadzenie przycisku SET
       PrzUp   equ P1.7        ; wyprowadzenie przycisku UP
       PrzDn   equ P1.3        ; wyprowadzenie przycisku DN
       Send      equ P0.1   ; bit wysylajacy zadanie operacji do uP2
       Rcv   equ P0.2   ; bit zwrotny z uP2 potwierdzajacy operacje
       Buzzer  equ P0.0   ; wyprowadzenie brzeczyka
       LcdRS   equ P1.1        ; bit dane/instrukcje wyswietlacza LCD
       LcdRW   equ P1.0        ; bit Read/Write wyswietlacza LCD
       LcdCE   equ P1.2   ; bit sterujacy wyswietlacza LCD
       MemWE   equ P0.5   ; bit WriteEnable pamieci zewnetrznej (impuls zapisujacy)
       Bank0   equ P0.3   ; dodatkowe wyjscie adresowania pamieci (bank A8)
       Bank1   equ P0.4   ; dodatkowe wyjscie adresowania pamieci (bank A9)
       Bank2   equ P0.6   ; dodatkowe wyjscie adresowania pamieci (bank A10)
    ;-------------------------------
       DelB    equ 016h        ; rejestr programowego tlumika drgan
       LimL    equ 018h        ; rejestr dolnego limitu adresu
       LimH    equ 019h        ; rejestr gornego limitu adresu
       RegCycl equ 01ah        ; rejestr dynamicznej zmiany ilosci cykli T0
       Setki   equ 01bh        ; rejestr setek po konwersji bajtu
       Dzies   equ 01ch        ; rejestr dziesiatek po konwersji bajtu
       Jedn    equ 01dh        ; rejestr jednostek po konwersji bajtu
       Del1    equ 01eh        ; rejestr 1 petli opoznienia 10ms dla potrzeb LDC
       Del2    equ 01fh        ; rejestr 2 petli opoznienia 10ms dla potrzeb LDC
       Auto    equ 020h.6      ; flaga trybu automatycznego
       Loop    equ 022h.0      ; flaga zapetlenia Loop (bit 0 w rejestrze)
       fTime   equ 021h.0      ; flaga ustawiana przy ustawianiu czasow T0 w SET
       fCycle  equ 021h.1      ; flaga ostatniego okrazenia timera T0
       fl1     equ 020h.0      ; flaga nacisniecia przycisku AUTO
       fl2     equ 020h.1      ; flaga nacisniecia przycisku WRITE
       fl3     equ 020h.2      ; flaga nacisniecia przycisku SET
       fl4     equ 020h.3      ; flaga nacisniecia przycisku UP
       fl5     equ 020h.4      ; flaga nacisniecia przycisku DN
       WrEn   equ 023h.5   ; flaga 0-blokada zapisu na bankach 1-7, 1-zezwolenie               
       flUP    equ 020h.5      ; ustawiana gdy wcisniemy UP, zerowana gdy DN podczas pracy gen.
       TimeH   equ R0          ; rejestr TH0 wybranego czasu ostatniego okrazenia timera
       TimeL   equ R1          ; rejestr TL0 wybranego czasu ostatniego okrazenia timera
       Cycle   equ R2          ; liczba cykli timera T0
       RegSet  equ R3          ; rejestr opcji SET (od 0 do 4)
       RegTime equ R4          ; rejestr wyboru czasu StepTime (od 0 d0 7)
       Bank    equ R5          ; rejestr numeru Banku (od 0 do 7)
       BuzzLp  equ R6          ; dodatkowa petla opozniajaca buzzera
       WrDelay equ R7          ; dodatkowa petla opozniajaca cykl zapisu
    ; Odczyt ustawien z EEPROM:-----
       mov 0096h,#00001000b   ; EEMEN = 1 , EEMWE = 0 - dostep do EEPROM, odczyt
       mov DPTR,#0000h      ; Adres komorki w pamieci EEPROM z zapisanym bajtem 2
       movx A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov RegTime,A      ; Aktualizacja rejestru RegTime
       mov DPTR,#0001h      ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov 022h,A      ; Aktualizacja rejestru z bitem LOOP
       mov DPTR,#0002h      ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov LimL,A      ; Aktualizacja rejestru LimL
       mov DPTR,#0003h      ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov LimH,A      ; Aktualizacja rejestru LimH
       mov 0096h,#00000000b   ; EEMEN = 0 , EEMWE = 0 - koniec pracy z EEPROM-em
    ; Inne ustawienia poczatkowe ---
       mov     tmod,#11h       ; ustawienie timerow (2 timery 16-bitowe)
       mov     ie,#1000$1010b  ; ustawienie rejestru przerwan (EA X T2 SPI | T1 ExT1 T0 ExT0)
       mov     ip,#0000$0010b  ; ustawienie priorytetu przerwan (X X T2 SPI | T1 ExT1 T0 ExT0)
              mov     00a7h,#0e3h     ; ustawienie watchdoga (info w nocie katalogowej kontrolera)
       mov     RegOut,LimL     ; ustaw wyjscie generatora na dolna granice
       setb    fTime           ; flaga poczatkowego wczytania czasu do timera
       clr     fCycle          ; zeruj flage ostatniego okrazenia timera
       clr     Auto            ; opcja AUTO wylaczona
       clr   Send      ; zadanie wlaczenia trybu odczytu
       mov     RegSet,#0   ; zerowanie rejestru ustawien
       mov     Bank,#0      ; ustawianie banku na bank T
       Setb   Buzzer      ; wylaczenie buzzera
       call    LcdInit         ; inicjacja wyswietlacza LCD
  • #2
    wzk
    Level 19  
    Z tego co przedstawiłeś nic nie można powiedzieć o przyczynie braku działania LCD. Podaj cały program względnie HEX, częstotliwość zegara i wtedy można coś dumać.
    A propos - dlaczego nie używasz nazwy rejestru a podajesz jego adres (96h, 0A7h)? Przecież zaciemnia, to zapis programu.
  • #3
    darkonel
    Level 19  
    Przepraszam, że się niezbyt precyzyjnie określiłem w pierwszym poście. Chodzi mi o to czy procedura odczytu z EEPROM jest poprawna. program obsługi LCD jest ok, bo na innym procku (bez odczytywania EEPROM) wyświetlacz śmigał jak należy. Proszę o skoncentrowanie się na kodzie dotyczącym odczytu z wewnętrznej EEPROM. Pozostały fragment kodu przedstawiłem aby zachować kontekst.
  • #4
    wzk
    Level 19  
    Procedura odczytu z EEPROM jest poprawną, chociaż nie jest napisaną optymalnie.
  • #5
    kemot55
    Level 31  
    A czy jesteś pewien, że EEPROM zawiera poprawne dane do odczytania? Jak i kiedy ładujesz tam dane?
  • #6
    darkonel
    Level 19  
    kemot55 wrote:
    A czy jesteś pewien, że EEPROM zawiera poprawne dane do odczytania? Jak i kiedy ładujesz tam dane?

    Dane nie są ważne w początkowym procesie rozruchu. Mogą one przyjmować wartość od 00 do FF. Program ma działać tak, że po włączeniu urządzenia program odczytuje dane z EEPROM, dalej w czasie używania urządzenia dane są modyfikowane i przyciskiem zapisywane w EEPROM µkontrolera po to by po ponownym uruchomieniu procesor je odtworzył z EEPROM.
    No ale skoro procedura odczytu jest poprawna, to rozumiem, ze procesor nie "zawiśnie" w tym momencie.
    To teraz już nie wiem co może być przyczyną, że na AT89S52 program działał (LCD pracował) a nieco inny program (z tą samą obsługą LCD) - ten, którego fragment przedstawiłem powoduje, ze LCD nie reaguje, a co za tym idzie sądzę, ze procek nie pracuje poprawnie. Dodam, ze zaprogramował się z pozytywną weryfikacją kodu.
  • #7
    JarekC
    Level 32  
    Witam,

    Pierwsze co zauważyłem to brak inicjalizacji wskaźnika stosu.
    Co prawda po resecie SP ma wartość 07h więc wywołania CALL nie zniszczą
    zawartości R0-R7 ale już zmienne od adresu 08h w górę tak.

    Pozdrawiam
    JarekC
  • #8
    kemot55
    Level 31  
    Rozumiem, że przerwania są zablokowane (przy wykonywaniu procedury inicjalizacji LCD)?
    Zastanawia mnie jeszcze tylko uruchomienie WACHDOG'a. Przejrzałem swoje programy i z bliżej nie znanych mi (na dzień dzisiejszy) powodów zaraz po uruchomieniu wykonywałem procedurę resetu WDG'a (do rejestru A6 wpisuję kolejno bajty 1E i następnie E1). Wynikało to prawdopodobnie z rysunku 8.1 (manual 8253)
    A ogólnie to proponuję nie załączać systemu ochrony w trakcie pisania programu.

    Jeżeli dysponujesz buzerem to możesz go załączyć w kolejnych liniach programu (zawsze tylko w jednym miejscu programu w danym teście np. bezpośrednio przed inicjalizacją LCD). Będziesz w ten sposób wiedział gdzie dokładnie "utyka" procesor (jeżeli buzer nie zadziała to oczywiście procesor nie będzie już wykonywał danej linii).
    Ważne: nie włączaj już wachdoga przy takim sposobie poszukiwań błędu!
  • #9
    wzk
    Level 19  
    Zamiast ćwiczyć na sprzęcie, czy nie warto najpierw poćwiczyć na symulatorze? Odpadłoby w przedbiegach wiele pytań i naszego telepatycznego dumania, co w programie fiksuje.
  • #10
    darkonel
    Level 19  
    wzk wrote:
    Zamiast ćwiczyć na sprzęcie, czy nie warto najpierw poćwiczyć na symulatorze? Odpadłoby w przedbiegach wiele pytań i naszego telepatycznego dumania, co w programie fiksuje.

    Problem w tym, że cały program z wyłączeniem obsługi EEPROM zapuściłem (oczywiście po mozolnych symulacjach programowych i udoskonalaniu kodu) na procku AT89C2051. Program działał dokładnie tak jak chciałem. A że jest bardzo rozbudowany (w pierwszym poście jest jedynie jego mały fragment) to sprawdzenie rzeczywistego działania zajęło mi trochę czasu, ale wszystko działało jak należy!
    Po dodaniu obsługi Watchdoga i wewnętrznej EEPROM zapuściłem go na procek AT89S8253 (oczywiście uwzględniając inne porty). Tutaj niestety nie pójdzie. Oto mój cały problem. No ale ok, będę sprawdzał krok po kroku co jest nie tak z nadzieją, że któraś z wypowiedzi Kolegów będzie mi pomocna w tej kwestii.
    Quote:
    Co prawda po resecie SP ma wartość 07h więc wywołania CALL nie zniszczą
    zawartości R0-R7 ale już zmienne od adresu 08h w górę tak.

    Tutaj zastosowałem wolną przestrzeń nad stosem. Oczywiście nie zdarza sie aby stos przekroczył 3 poziomy, ale dałem spory zapas mimo wszystko mając oczywiście na uwadze, że po resecie SP jest równy 07h.
  • #11
    wzk
    Level 19  
    Skoro twierdzisz, że wszystkie procedury symulacji przetrenowałeś, to wróć do początku. Wgraj sprawdzony program i sprawdź jeszcze raz jego działanie. Może sprzęt w międzyczasie padł. Potem stopniowo dołączaj inne podprogramy. Gdy coś się zatrzyma - zmień miejsce włączenia w programie głównym.
    Pierwszy raz spotykam się z takim przypadkiem, że pierwszymi instrukcjami wykonywanymi przez procesor są manewry na EEPROMie a nie porządne zainicjowanie procesora, LCD i innych bloków. Trochę więcej ogólnego spojrzenia na programowanie a będzie mniej kłopotów i program będzie bardziej czytelny.
  • #12
    darkonel
    Level 19  
    Sprawa się wyjaśniła, ale powstał kolejny problem. Jeśli chodzi o brak reakcji LCD podejrzewałem procedury operacji na EEPROM-ie. Myliłem się. Problem braku czegokolwiek na LCD pojawił się po przeniesieniu działającego kodu na drugi procesor. Port obsługujący LCD uległ zmianie, a bit nr 7 szyny danych LCD odpowiedzialny za zajętość LCD, w procku pozostał na starym miejscu, przez co wszystko wzięło w łeb. Po korekcie wszystko ładnie pracuje, musiałem też wyłączyć Watchdoga wpisując kod
    Code:
    mov     00a7h,#0e2h

    zamiast kodu
    Code:
    mov     00a7h,#0e3h

    ponieważ powodowało to cykliczne resetowanie procka co 2 sekundy.
    To tyle - układ działa dobrze za małym wyjątkiem. Tutaj chcę opisać problem z którym się spotkałem podczas zabawy w zapis i odczyt wewnętrznej pamięci EEPROM.
    Oto procedura zapisu znajdująca się w programie i uaktywniana po dokonaniu ustawień urządzenia:
    Code:

    ; Zapis ustawien do EEPROM:-----;
    skok1:  mov       0096h,#00011000b; EEMEN (dostep do EEPROM) = 1, EEMWE (tryb zapisu do EEPROM) = 1
              mov     DPTR,#0000h     ; Adres komorki w pamieci EEPROM
              mov     A,RegTime         ; Bajt zapisywany (RegTime)
              movx    @DPTR,A          ; Zapisanie bajtu
    spr1:     mov     A,0096h            ; wpisanie do A rejestru EECON
              anl       A,#00000010b   ; zamaskowanie wszystkich bitow EECON oprocz bitu RDY
              cjne     A,#2,spr1          ; porownaj, i jesli odkryty bit nie jest ustawiony - zaczekaj
              mov     DPTR,#0001h     ; Adres komorki w pamieci EEPROM
              mov     A,022h              ; Bajt zapisywany (LOOP)
              movx    @DPTR,A           ; Zapisanie bajtu
    spr2:     mov     A,0096h             ; wpisanie do A rejestru EECON
              anl       A,#00000010b    ; zamaskowanie wszystkich bitow oprocz bitu 2
              cjne     A,#2,spr2           ; porownaj, i jesli odkryty bit nie jest ustawiony - zaczekaj
              mov     DPTR,#0002h     ; Adres komorki w pamieci EEPROM
              mov     A,LimL               ; Bajt zapisywany (LimL)
              movx    @DPTR,A          ; Zapisanie bajtu
    spr3:     mov     A,0096h             ; wpisanie do A rejestru EECON
              anl       A,#00000010b    ; zamaskowanie wszystkich bitow oprocz bitu 2
              cjne     A,#2,spr3          ; porownaj, i jesli odkryty bit nie jest ustawiony - zaczekaj
              mov     DPTR,#0003h      ; Adres komorki w pamieci EEPROM
              mov     A,LimH               ; Bajt zapisywany (LimH)
              movx    @DPTR,A           ; Zapisanie bajtu
    spr4:     mov     A,0096h             ; wpisanie do A rejestru EECON
              anl       A,#00000010b    ; zamaskowanie wszystkich bitow oprocz bitu 2
              cjne    A,#2,spr4           ; porownaj, i jesli odkryty bit nie jest ustawiony - zaczekaj
              mov     0096h,#00000000b  ; EEMEN = 0 , EEMWE = 0 - koniec zapisu i pracy z EEPROM-em


    A to procedura odczytująca te ustawienia po uruchomieniu urządzenia (coś na zasadzie zapamiętywania nastaw użytkownika):
    Code:

    ; Odczyt ustawien z EEPROM:-----
       mov    0096h,#00001000b; EEMEN = 1 , EEMWE = 0 - dostep do EEPROM, odczyt
       mov    DPTR,#0000h   ; Adres komorki w pamieci EEPROM z zapisanym bajtem 2
       movx    A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov    RegTime,A   ; Aktualizacja rejestru RegTime
       mov    DPTR,#0001h   ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx    A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov    022h,A      ; Aktualizacja rejestru z bitem LOOP
       mov    DPTR,#0002h   ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx    A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov    LimL,A      ; Aktualizacja rejestru LimL
       mov    DPTR,#0003h   ; Adres komorki w pamieci EEPROM z zapisanym bajtem
       movx    A,@DPTR      ; Pobranie bajtu z EEPROM do A
       mov    LimH,A      ; Aktualizacja rejestru LimH
       mov    0096h,#00000000b; EEMEN = 0 , EEMWE = 0 - koniec pracy z EEPROM-em


    Problem pojawia się taki, że poprawnie zapisują się w EEPROM-ie tylko komórka 0000 oraz 0002. Pozostałe dwie są nietknięte!
    Oto wynik odczytania pamięci EEPROM po przejściu przez powyższe procedury odczytu i zapisu:

    Atmel 89S8253, proszę o sprawdzenie kodu ASM

    No i oczywiście potwierdza się to po resecie. Ustawienia, za które odpowiada komórka 0 i 2 EEPROM są zapamiętane i poprawnie wczytane przez program (powyższa procedura odczytu) natomiast dane z komórek 1 i 3 są to zawsze FF

    Czy ktoś się kiedyś spotkał z takim niecodziennym zjawiskiem?
    Co może być tego przyczyną?