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

[AT89C2051][ASM] - potrzebna modyfikacja programu

21 Sty 2010 12:25 2255 15
  • Poziom 25  
    Pliki zamieszczone w załączniku to kod źródłowy napisany w C do komputerka samochodowego zamieszczonego kiedys w PE.

    Jako, że dopiero zaczynam z mikro-kontrolerami i staram się nauczyć Bascoma a nie C jest mi trudno załapać o co chodzi w tych plikach C. W Bascomie jest tylko jeden plik źródłowy a tutaj kilka - jak podglądnąć cały kod źródłowy tego komputerka?
    Komputerek posiada zegar, pomiar napięcia, prądu, dwa punkty pomiaru temperatury - gdzie to wszystko jest?

    I jeszcze jedno pytanie - czy jest jakiś prosty sposób przekonwertowania tego kodu z C do Bascoma?

    Pliki które tu załączam próbowałem otwierać w AVR Studio ze strony Atmel'a.

    Z góry dziękuje za każdą pomoc
  • Poziom 15  
    Niestety program nie jest napisany w C tylko w asm. Główny program zawarty jest w pliku LowLevel.asm. Program w C uruchamia tylko funkcje napisane w asm. Tak więc rozszyfrowanie tego będzie jeszcze trudniejsze.
  • Poziom 43  
    Ja bym powiedział że łatwiejsze bo BASCOM łyka assemblera więc niczego nie trzeba będzie rozszyfrowywać a jedynie dostosować składnię.
  • Poziom 25  
    czy ktoś z Was otworzył i przejrzał ten plik napisany w ASM? czy to możliwe, że tak krótki kod ma w sobie i zegar i pomiar temp., napięcia i prądu?

    Jak by to było z przełożeniem tego na Bascom? trzeba pisać od nowa czy da się to w prosty sposób "przełożyć"?

    Potrzebuje w tym programie zmienić 2 lub 3 funkcje - nie znam w ogóle asemblera...


    Ok po przejrzeniu tego pliku ASM tak na chłopski rozum jest tam zawarte wszystko...tylko teraz jak i co z tym zrobić dalej żeby przełożyć to na Bascom?
  • Poziom 43  
    Kod w asemblerze można normalnie kompilować w BASCOMie. Trzeba tylko będzie „EQU” pozamieniać na Alias, Labelom podopisywać wykrzykniki na początku i jeszcze wektory przerwań inaczej zadeklarować.
    Ale może się okazać że kod nie zmieścić się do procesora bo BASCOM dorzuca swoje kilkadziesiąt bajtów do kodu.
    No i zostaje jeszcze ta część w C.
    W ogóle po co to przerabiać skoro masz gotowca a zmienić chcesz i tak tylko to co jest w assemblerze? Zmień to co trzeba a skompiluj to normalnie czyli w kompilatorze C.
    Skoro nie znasz assemblera to co Ci za różnica czy to C czy BASCOM skoro zmieniał i tak będziesz tylko kod w assemblerze.
  • Poziom 25  
    atom1477 - czy mozesz porozmawiac ze mna na PW? niepotrzebnie zasmiecać tutaj forum jak można załatwić sprawę na PW - może nie warto rozpisywać się tutaj?

    Czytasz w ogóle wiadomości na PW ?:) bo wolałbym przeczytać odp, że nie udzielasz pomocy poza ogólnym forum niż mieć wątpliwości czy coś do Ciebie dochodzi :)


    Co do zmian to nie wiem do końca czy ta część jest zapisana w ASM - chciałem wywalić w ogóle zegar z tego cacka, druga sprawa - zmienić automatyczne wygaszanie wyświetlaczy po upływie jakiegoś czasu od naciśnięcia któregoś ze switchy na coś zupełnie innego - po wywaleniu zegara zostanie mi jeden wolny pin w procku który chciałbym wykorzystać jako kontrole tego czy stacyjka jest załączona czy nie i na tej podstawie LED'y będą świecić albo nie, kolejna i ostatnia już rzecz to to, żeby po starcie pracy urządzenia (napięcie po stacyjce na pinie czy w ogóle załączenie zasilania komputerka) powodowało automatyczne przejście do trybu wyświetlania napięcia - to tyle...
    chciaż mozna by było jeszcze zrobić jedno - w podstawowym projekcie sa 4 switche - jeden przełącza tryb wyswietlania czasu, drugi przelacza na wyswietlanie U lub I a kolejne 2 sluza do ustawiania czasu na zegarze lub sprawdzenie temp w 1 lub 2 punkcie - po tym jak usune zegar pozbede sie jednego switcha, zostaja 3 - i mam pomysl na wyrzucenie jeszcze jednego - po przeprogramowaniu mialo by to tak wygladac ze jeden z nich bedzie tak samo zmienial wyswietlanie U lub I a drugi po naciśnieciu uaktywni wyswietlanie temperatury - ale bedzie to wyswietlanie naprzemienne temperatur z dwoch punktow - zalozmy 2 sekundy z jednego czujnika i 2 sekundy z drugiego i tak w kółko az to nacisniecia przycisku podgladu napiecia - z tym ze jak sie juz przelaczy na pokazywanie napiecia to tak powinno zostac i powinno byc wyswietlane napiecie do czasu az zazycze sobie sprawdzic cos innego :) ale sie rozpisalem :)

    a moze jeszcze inaczej - tak mi przychodza pomysly do glowy i je odrazu pisze - pozostajac przy tym co pisalem wyzej robimy tak zeby byly 2 switche i - pierwszy sluzy do zmiany wyswietlania U lub I a drugi T1 lub T2 - tak by bylo super...naciskam przycisk U/I pokazuje napiecie - naciskam drugi raz pokazuje prąd - jesli nacisnę przycisk T1/T2 pokazuje mi temp w 1 punkcie a po kolejnym nacisnieciu tego przycisku pokazuje temp w 2 punkcie - i gra gitara - 2 switche , brak automatycznego wygaszania LED - LED'y wygaszane sa dopiero po zaniku napiecia po stacyjce i brak zegarka - to bym chcial osiagnac :) ale nie poradze sobie z tym sam.......

    Dla zainteresowanych wstawie schemat - to komputerek z prockiem jak w temacie, 4 switche - dwa podwójne 8-seg wyswietlacze LED do wysietlania informacji...projekt dosc stary bo z 97 roku :) ale tego mi akurat brakuje w samochodzie
  • Poziom 43  
    Z tego robi się już duży projekt. Zmian trochę jest. I może się okazać że nie zmieści się to do mikrokontrolera po wprowadzeniu tych zmian.
    Do tego pasowało by to testować na bieżąco a na nie mam nawet takiego procesora, programatora do niego, a co dopiero całego zegara.
    Więc ja się tego nie podejmę.

    PS. WP czytam (choć tym razem nic do mnie nie doszło) ale nie pomagam przez PW.
  • Poziom 25  
    ja ten projekt testuje w Proteusie...tzn mam jego namacalna wersje, ale narysowałem wszystko w proteusie i póki co tam będę ładował hex'a i patrzył co się dzieje :)

    Ale ok - skoro uważasz, że to tak dużo to może udało by się wywalić tylko zegarek i wyłączyć całkowicie funkcje wygaszania wyswietlaczy po uplywie jakiegos czasu?

    To co pisze teraz i wcześniej to raczej okrajanie programu a nie dopisywanie nowych funkcji - no może oprócz tej dotyczącej kontroli napięcia po stacyjce - ale ok darujmy sobie to ....

    Niech nie będzie zegarka - albo niech będzie, ale po starcie niech przechodzi do wyświetlania napięcia a nie do opcji ustawiania i wyświetlania zegarka to raz, dwa - zlikwidować opcję wygaszania wyświetlaczy po czasie - przecież to jest okrajanie...prawda?a nie dopisywania...i tyle ... jak już to będę miał to wystarczy a co do reszty to może kiedyś :)

    Dodano po 8 [minuty]:

    a może podpowiesz mi chociaż gdzie jest w kodzie ukryta funkcja automatycznego wygaszania wyświetlaczy jeśli żaden z przycisków nie będzie naciskany przez pewien czas - to jest najbardziej wkurzające - jak po chwili wszystko gaśnie ...
  • Poziom 19  
    Kiedyś toto ćwiczyłem. Zobacz czy załącznik odpowiada Twemu programowi. Niestety RAR jest dla mnie niezjadliwy i Twego załącznika nie widzę.
    Chyba jest tam wszystko przeniesione do assemblera i skomentowane.
  • Poziom 25  
    To jest chyba to samo, ale pewności nie mam - trochę inaczej wygląda ten kod - czyżbyś wprowadzał jakieś zmiany?
    W moim pliku też są opisy, ale raczej marne...

    W załączniku specjalnie dla Ciebie wersja ZIP

    Jeśli to jest to samo - a raczej tak z tego co widzę to teraz już jest sam ASM bez wstawek z C ... czy teraz by było łatwiej wyrzucić funkcję wygaszania wyświetlaczy?
  • Poziom 19  
    Plik wynikowy assemblacji mego "car.asm" powinien być taki sam jak oryginał w PE.
    Teraz masz wszystko w jednym pliku źródłowym i możesz robić z programem co dusza zapragnie. Wyłączenie wygaszania, to być może tylko postawienie średnika na początku linii odpowiedzialnej za wygaszenie. Musisz sam się z tym uporać, bo ja już niewiele pamiętam z tego co robiłem.
    Korzystałem z intelowskiego assemblera "asm51.exe". W katalogu z plikiem xródłowym musi znaleźć się jeszcze plik "mod51".

    Powodzenia!

    PS
    Przyjrzyj się bitowi "bPowerSave" zdefiniowanemu w segmencie BSEG.
    Chyba jest on odpowiedzialny za przechodzenie procesora w stan zamrożenia. Za etykietą "Main" jest on testowany i podejmowane jest odpowiednie działanie.
  • Poziom 17  
    tu mozna zablokować wygaszanie
    Code:

    ;********************************************************************
    OvT0: ;             h  m
    ;minimalny  czas =  0:00
    ;maksymalny czas = 23:59
          ;4000 Hz
          djnz Val1Cnt,LeaveOvT0
          ;16 Hz
          mov Val1Cnt,#DivVal1
          djnz Val2Cnt,LeaveOvT0
          ;2 Hz
          cpl bBlinker
          setb bAllowMeasure
          mov Val2Cnt,#DivVal2
          djnz Val3Cnt,LeaveOvT0
          ;1/60 Hz
          ;tutaj zwieksz wskazanie czasu o 1 minute
          mov Val3Cnt,#DivVal3
          push Acc
          push PSW
          acall IncClockValue
          djnz PowSavCntDn,NotPowerSave ;zmniejsza licznik czasu do wygaszania
                ;jeżeli doliczy do zera to nie ominie poniższej
                ;instrukcji i ustawi bit "bPowerSave"
    ;---- UWAGA  modyfikacja-----
          ;setb bPowerSave    ;ustawienie tego bitu powoduje przejście
             ;w tryb oszczędzania energii(wygaszenie wyswietlaczy)
             ;średnik na początku spowoduje pominięcie tego polecenia
             ;tym samym nie będzie włączany tryb "Power Save"
        NotPowerSave:
          pop PSW
          pop Acc
      LeaveOvT0:
          reti
    ;********************************************************************





    tu można zmienić tryb wyświetlania po włączeniu zasilania
    obecnie jest wyświetlanie czasu
    Code:

        mov DisplayStatus,#DS_CLOCK

    zamiast DS_CLOCK
    można do "DisplayStatus" wpisać jedną z poniższych stałych:

    DS_TEMP1 ;temperatura 1
    DS_TEMP2 ;temperatura 2
    DS_VOLTA ;pomiar napiecia
    DS_CURRE ;pomiar natęzenia

    Code:

    Init:
            clr bMoreThan2s
            mov TMOD,#12h   ;T1: 16 - bit, T0: 8 - bit
            mov TH1,#256-19 ;ok 200Hz@12MHz
            mov TH0,#256-250 ;
            mov TL0,#256-250 ;
            mov IE,#8Ah     ;T0+T1+EA
            mov TCON,#50h    ;start T1 i T0
            mov ValBuff,#0h
            mov ValBuff+1,#0h
            mov DOTS,#0
            mov Hour,#0
            mov Min,#0
            mov Val1Cnt,#DivVal1
            mov Val2Cnt,#DivVal2
            mov Val3Cnt,#DivVal3
            mov KbCnt,#0     ;rownowazne zatrzymaniu licznika
            setb bAllowMeasure
            clr bBlinker
            clr bSwapTmp
            clr bPowerSave
    ;        mov ADCStatus,#00001011b

            mov DisplayStatus,#DS_CLOCK ;<<< tu włącza wyświetlanie zegara

            mov PowSavCntDn,#TenMinVal
    ;        setb K1
    ;        setb K2
    ;        setb K3
    ;        setb K4
            setb ADCCS
            clr ADCCLK
            setb bSetClock
            ret
    ;********************************************************************
  • Poziom 25  
    Panowie - no zaskakujecie mnie i to tak pozytywnie, że nie wiem co powiedzieć...
    Bo samo dziękuję to chyba za mało w tym przypadku...
    Serdecznie dziękuję za pomoc...nie będę tego jeszcze wgrywał do procka tylko przeprowadzę symulacje w Proteusie - o wynikach poinformuje...

    A co do reszty opcji to pewnie będą potrzebne większe przeróbki ... może komuś się będzie zupełnie nudziło to coś zmieni i może i inni skorzystają ...

    Wielkie dzięki - jak tylko przeprowadzę testy to oczywiście napiszę i punkty polecą na Wasze konta...
  • Poziom 25  
    pepson napisał:
    tu mozna zablokować wygaszanie
    Code:

    ;---- UWAGA  modyfikacja-----
          ;setb bPowerSave    ;ustawienie tego bitu powoduje przejście
             ;w tryb oszczędzania energii(wygaszenie wyswietlaczy)
             ;średnik na początku spowoduje pominięcie tego polecenia
             ;tym samym nie będzie włączany tryb "Power Save"





    tu można zmienić tryb wyświetlania po włączeniu zasilania
    obecnie jest wyświetlanie czasu
    Code:

        mov DisplayStatus,#DS_CLOCK

    zamiast DS_CLOCK
    można do "DisplayStatus" wpisać jedną z poniższych stałych:

    DS_TEMP1 ;temperatura 1
    DS_TEMP2 ;temperatura 2
    DS_VOLTA ;pomiar napiecia
    DS_CURRE ;pomiar natęzenia

    Code:

    Init:
            clr bMoreThan2s
            mov TMOD,#12h   ;T1: 16 - bit, T0: 8 - bit
            mov TH1,#256-19 ;ok 200Hz(małpa)12MHz
            mov TH0,#256-250 ;
            mov TL0,#256-250 ;
            mov IE,#8Ah     ;T0+T1+EA
            mov TCON,#50h    ;start T1 i T0
            mov ValBuff,#0h
            mov ValBuff+1,#0h
            mov DOTS,#0
            mov Hour,#0
            mov Min,#0
            mov Val1Cnt,#DivVal1
            mov Val2Cnt,#DivVal2
            mov Val3Cnt,#DivVal3
            mov KbCnt,#0     ;rownowazne zatrzymaniu licznika
            setb bAllowMeasure
            clr bBlinker
            clr bSwapTmp
            clr bPowerSave
    ;        mov ADCStatus,#00001011b

            mov DisplayStatus,#DS_CLOCK ;<<< tu włącza wyświetlanie zegara

            mov PowSavCntDn,#TenMinVal
    ;        setb K1
    ;        setb K2
    ;        setb K3
    ;        setb K4
            setb ADCCS
            clr ADCCLK
            setb bSetClock
            ret
    ;********************************************************************


    I wprowadziłem zmiany tak jak na powyższym obrazku.
    Jeśli chodzi o dezaktywacje wygaszania wyświetlaczy to po modyfikacjach wszystko jest super.

    Natomiast jeśli chodzi o kolejna modyfikację kodu dotycząca wyświetlania napięcia po starcie to jest jedno ale. Chodzi o to, że po włączeniu owszem wyświetlane jest napięcie, ale nie funkcjonuje żaden z przycisków i nie mogę przełączać trybu wyświetlania napięcie/prąd itd... owszem mogę to odblokować tylko w momencie kiedy przełączę w tryb wyświetlania czasu i przytrzymam przycisk ZEGAR dłużej niż 2 sekundy w celu zatwierdzenia aktualnej godziny.

    Czy ktoś pomoże mi jeszcze z tym tematem?

    Może wytłumaczę szybko co się dzieje po włączeniu zasilania w pierwotnej wersji:
    po włączeniu zasilania na wyświetlaczach pojawia się 0.00 i migają wszystkie kropki wyświetlaczy - jest to znak, że należy ustawić godzinę - dopóki nie ustawimy godziny i nie przytrzymamy klawisza ZEGAR na czas dłuższy jak 2 sekundy żadne inne opcje komputerka nie działają - nawet jeśli nie chce ustawiać zegara to muszę przytrzymać klawisz ZEGAR na minimum 2 sekundy celem zatwierdzenia godziny - dopiero wtedy pozostałe funkcje komputerka funkcjonują prawidłowo.

    Z tego wynika, że trzeba zmienić tak kod źródłowy, aby pominąć opcje ustawiania zegara i odrazu wyświetlać wartość napięcia z tym - czy ktoś pomoże? zwracam się tu głownie do kolegi pepson

    Poniżej wklejam cały kod źródłowy w asm i na tym kodzie proszę operować

    Za wszelką pomoc dziękuję

    Dla informacji w poniższym kodzie wprowadzona jest tylko zmiana dotycząca automatycznego wygaszania po 10 minutach nic poza tym

    Code:
    $MOD51
    
    DSEG AT 8
       Temp:      DS   4   ;RAM bajtowa
       Oper:      DS   4
       StackCount:   DS   1
    DSEG AT 20h            ;4 bajty RAM bitowej
       DOTS:      DS   1
       KbStat:      DS   1
       BF2:      DS   1   ;nie uzywane jako bajt
       DisplayStatus:   DS   1
       DispBuff:   DS   4   ;dcn RAM bajtowej
       ValBuff:   DS   2
       ADCStatus:   DS   1
       Tmp:      DS   1   ;nie uzywane
       BitCnt:      DS   1
       KbTmp:      DS   1   ;nie uzywane
       KbCnt:      DS   1   ;licznik opoznienia klawiszy
       Cnt2s:      DS   1
       ToKbCnt:   DS   1
       KbStatBak:   DS   1
       Hour:      DS   1
       Min:      DS   1
       Val1Cnt:   DS   1
       Val2Cnt:   DS   1
       Val3Cnt:   DS   1
       PowSavCntDn:   DS   1
       ACVoltage:   DS   1
       ACCurrent:   DS   1
       ACTemperature1:   DS   1
       ACTemperature2:   DS   1
    BSEG
       DOT0:      DBIT   1
       DOT1:      DBIT   1
       DOT2:      DBIT   1
       DOT3:      DBIT   1
    BSEG AT 11
       KB_T1_UP:   DBIT   1
       KB_U_I:      DBIT   1
    BSEG AT 13
       KB_ZEGAR:   DBIT   1
    BSEG AT 15
       KB_T2_DOWN:   DBIT   1
    BSEG AT 16
       bAllowMeasure:   DBIT   1
       bSwapTmp:   DBIT   1
       bMoreThan2s:   DBIT   1
       bSetClock:   DBIT   1
       bBlinker:   DBIT   1
       bPowerSave:   DBIT   1
    BSEG AT 24
       DSB_CLOCK:   DBIT   1
       DSB_TEMP1:   DBIT   1
       DSB_TEMP2:   DBIT   1
       DSB_VOLTA:   DBIT   1
       DSB_CURRE:   DBIT   1

    ;   WL1 EQU P3.3      ;przyciski
    ;   WL2 EQU P3.4
    ;   WL3 EQU P3.5
    ;   WL4 EQU P3.7
       SIPODAT   EQU   P1.6      ;sygnaly 74HC164
       SIPOCLK   EQU   P1.7
       K1   EQU   P1.4      ;LEDy
       K2   EQU   P1.5
       K3   EQU   P1.3
       K4   EQU   P1.2
       ADCCLK   EQU   P3.1      ;sygnaly ADC0834
       DI   EQU   P3.0
       DO   EQU   P3.0
       ADCCS   EQU   P3.2
       DS_CLOCK   EQU   1   ;wartosci do DisplayStatus
       DS_TEMP1   EQU   2
       DS_TEMP2   EQU   4
       DS_VOLTA   EQU   8
       DS_CURRE   EQU   16
    ;   IS_TEMP1 EQU 00000011b      ;nie uzywane
    ;   IS_TEMP2 EQU 00000111b      ;nie uzywane
    ;   IS_VOLTA EQU 00001011b      ;nie uzywane
    ;   IS_CURRE EQU 00001111b      ;nie uzywane
       ACS_VOLTA   EQU   11   ;00001011b
       ACS_CURRE   EQU   15   ;00001111b
       ACS_TEMP1   EQU   3   ;00000011b
       ACS_TEMP2   EQU   7   ;00000111b
    ;ponizsze wartosci jako krotnosci 9.6ms, najmniejsza wartosc 2
       TimeValMax   EQU   54
    ;   TimeValMin   EQU   5
       TimeVal2s   EQU   156
       TenMinVal   EQU   10
       DivVal1      EQU   250
       DivVal2      EQU   8
       DivVal3      EQU   120

    CSEG AT 0000H
       LJMP   Start
    RstIn:
        ACALL   Init         ;przerwanie IE0
    MLoop:
       ACALL   MainLoop
       SJMP   MLoop
       ORG   0Bh         ;przerwanie timera T0
       AJMP   OvT0
    Start:
       MOV   R0,#3Fh         ;reset RAM
       CLR   A
    ResetRAM:
       MOV   @R0,A
       DJNZ   R0,ResetRAM
       MOV   SP,#3Bh         ;wskaznik stosu
       LJMP   RstIn
       ORG    1Bh         ;przerwanie timera T1
       AJMP   OvT1
    TempCalc:
       MOV   R3,07h      ;przechowaj w R3 zawartosc R7
       CLR   A
       MOV   R4,A
       MOV   R5,A
       MOV   R6,A
       ACALL   Push32      ;long ADC na stos
       MOV   R7,#079h   ;laduj 633 do R4 - R7
       MOV   R6,#02
       MOV   R5,#0
       MOV   R4,#0
       ACALL   Mul32      ;mnozenie long 633*ADC
       ACALL   Push32      ;iloczyn na stos
       MOV   R7,03h      ;long ADC z R3
       CLR   A
       MOV   R4,A
       MOV   R5,A
       MOV   R6,A
       ACALL   Push32      ;long ADC na stos
       MOV   R7,#00Ch   ;laduj 1036 do R4 - R7
       MOV   R6,#04
       MOV   R5,#0
       MOV   R4,#0
       ACALL   Sub32      ;odjecie od 1036 long ADC
       ACALL   Div32      ;iloczyn/roznica
       ACALL   Pop32
       MOV   Temp+3,R7
       MOV   Temp+2,R6
       MOV   Temp+1,R5
       MOV   Temp,R4
       RET
    ;*******************************************************************
    INIT:
       CLR   bMoreThan2s
       MOV   TMOD,#12h      ;T0 - 8 bit;T1 - 16 bit
       MOV   TH1,#256-19      ;ok 200Hz @12MHz
       MOV   TH0,#256-250
       MOV   TL0,#256-250
       MOV   IE,#8Ah         ;T0+T1+EA
       MOV   TCON,#50h      ;start T1 i T0
       MOV   ValBuff,#0
       MOV   ValBuff+1,#0
       MOV   DOTS,#0
       MOV   Hour,#0
       MOV   Min,#0
       MOV   Val1Cnt,#DivVal1   ;#250
       MOV   Val2Cnt,#DivVal2   ;#8
       MOV   Val3Cnt,#DivVal3   ;#120
       MOV   KbCnt,#0
       SETB   bAllowMeasure
       CLR   bBlinker
       CLR   bSwapTmp
       CLR   bPowerSave
       MOV   DisplayStatus,#01
       MOV   PowSavCntDn,#0Ah
       SETB   ADCCS         ;P3.2
       CLR   ADCCLK         ;P3.1
       SETB   bSetClock      ;13
       RET
    ;*******************************************************************
    MainLoop:
       ACALL   CheckKb
       JNB   bPowerSave,NPS
       ACALL   LoadDisp
    TestKb:
       MOV   A,P3
       ANL   A,#0B8h
       CJNE   A,#0B8h,ExitPS
       SJMP   TestKb
       ACALL   WaitFreeKey
    ExitPS:
       CLR   bPowerSave
    NPS:
       JBC   bAllowMeasure,SMeasure
       ACALL   LoadDisp
       SJMP   MainLoop
    SMeasure:
       ACALL   MeasureAll
       ACALL   LoadDisp
       SJMP   MainLoop
    ;*******************************************************************
    CheckKb:
       ACALL   CheckFreeKey
       MOV   KbStatBak,KbStat   ;zapamietaj stan klawiszy
       JNC   ExitCheckKb   ;jezeli zaden nie wcisniety to wyjdz
       MOV   PowSavCntDn,#TenMinVal   ;init power save count down
       CLR   bMoreThan2s
       ACALL   KbExecute   ;wykonaj - stan klawiszy w SBKB
       MOV   ToKbCnt,#TimeValMax   ;#36h
       MOV   Cnt2s,#TimeVal2s   ;#9Ch
    RepKb:
       MOV   KbCnt,ToKbCnt      ;odmierzaj czas
    WTV1:
       ACALL   CheckFreeKey
       JNC   ExecuteBeforeExit   ;jezeli puszczone to wyjdz
       MOV   A,KbCnt
       JNZ   WTV1   ;czekaj az licznik zliczy do TimeVal1
             ;zliczyl - wykonaj
       SETB   bMoreThan2s
       MOV   A,Cnt2s         ;sprawdz czy uplynelo 2s
       JZ   MoreThan2s
       CPL   bMoreThan2s      ;nie uplynelo
    MoreThan2s:
       ACALL   KbExecute   ;wykonaj - stan klawiszy w SBKB
       MOV   A,ToKbCnt
       MOV   B,#03
       MUL   AB
       MOV   B,#04
       DIV   AB
       MOV   ToKbCnt,A      ;ToKbCnt=2*ToKbCnt/3
       INC   ToKbCnt
       SJMP   RepKb
    ExitCheckKb:
       RET
    ExecuteBeforeExit:
       RET
    ;*******************************************************************
    KbDelay:
       MOV   R6,#14h         ;okolo 20 ms
    KbDL:
       DJNZ   R5,$
       DJNZ   R6,KbDL
       RET
    ;*******************************************************************
    ReadKb:               ;KbStat stan klawiatury
       MOV   A,P3
       ANL   A,#0B8h
       MOV   KbStat,A      ;ponizej petla antyodbiciowa
       ACALL   KbDelay
       MOV   A,P3
       ANL   A,#0B8h
       XRL   A,KbStat
       JNZ   ReadKb
       RET
    ;*******************************************************************
    WaitFreeKey:
       LCALL   ReadKb
       MOV   A,KbStat
       CJNE   A,#0B8h,WaitFreeKey
       RET
    ;*******************************************************************
    CheckFreeKey:
       LCALL   ReadKb
       MOV   A,KbStat
       CJNE   A,#0B8h,KbPressed
       CLR   C
       RET
    KbPressed:
       SETB   C
       RET
    ;*******************************************************************
    KbExecute:
       JNB   KB_T1_UP,E_T1_UP
       JNB   KB_U_I,E_U_I
       JNB   KB_ZEGAR,E_ZEGAR
       JNB   KB_T2_DOWN,E_T2_DOWN
       RET
    E_T1_UP:
       JNB   bSetClock,DisplayT1
       ACALL   IncClockValue
       ACALL   LoadDisp
       RET
    DisplayT1:
       MOV   DisplayStatus,#DS_TEMP1      ;#02
       ACALL   LoadDisp
       RET
    E_U_I:
       JB   bSetClock,NotAllowed
       JB   DSB_VOLTA,SCURRE
       MOV   DisplayStatus,#DS_VOLTA      ;#08
       ACALL   LoadDisp
    NotAllowed:
       ACALL   WaitFreeKey
       RET
    SCURRE:
       MOV   DisplayStatus,#DS_CURRE
       ACALL   LoadDisp
       ACALL   WaitFreeKey
       RET
    E_ZEGAR:
       JB   bMoreThan2s,ZE2S
       MOV   DisplayStatus,#DS_CLOCK      ;#01
       ACALL   LoadDisp
       RET
    ZE2S:
       CPL   bSetClock
       ACALL   LoadDisp
       ACALL   WaitFreeKey
       RET
    E_T2_DOWN:
       JNB   bSetClock,DisplayT2
       ACALL   DecClockValue
       ACALL   LoadDisp
       RET
    DisplayT2:
       MOV   DisplayStatus,#DS_TEMP2      ;#04
       ACALL   LoadDisp
       RET
    ;*******************************************************************
    SendToDisp:      ;w A dana do wyslania na 74164 (E_16C)
       MOV   BitCnt,#08
    SLOOP:
       CLR   SIPOCLK
       RLC   A
       MOV   SIPODAT,C
       SETB   SIPOCLK
       DJNZ   BitCnt,SLOOP
       RET
    ;*******************************************************************
    Pulse:
       SETB   ADCCLK
       NOP
       NOP
       CLR   ADCCLK
       RET
    ;*******************************************************************
    XRADC:
       MOV   A,ADCStatus
    ;                                      sb1 os sd start
    ;A - wartosc do wyslania  - 0  0  0  0  0  0  0  0  b
       CLR   ADCCLK
       MOV   B,#04
       CLR   EA      ;zablokuj przerwania
       CLR   ADCCS
    Loop1:
       RRC   A
       MOV   DI,C      ;send mux
       ACALL   Pulse
       DJNZ   B,Loop1
       SETB   DI      ;przygotuj sie na odbior
       ACALL   Pulse
       MOV   B,#08
    Loop2:
       MOV   C,DO      ;rcv dat
       ACALL   Pulse
       RLC   A
       DJNZ   B,Loop2
       ACALL   Pulse
       SETB   EA      ;odblokuj przerwania
       SETB   ADCCS
       RET         ;w A - wartosc odebrana
    ;*******************************************************************
    IncClockValue:
       MOV   A,#256-60
       INC   Min
       ADD   A,Min
       JNC   ICVMO
       MOV   Min,#0
       MOV   A,#256-24
       INC   Hour
       ADD   A,Hour
       JNC   ICVMO
       MOV   Hour,#0
    ICVMO:
       RET
    ;*******************************************************************
    DecClockValue:
       MOV   A,#01
       DEC   Min
       ADD   A,Min
       JNZ   DCVMO
       MOV   Min,#3Bh
       MOV   A,#01
       DEC   Hour
       ADD   A,Hour
       JNZ   DCVMO
       MOV   Hour,#17h
    DCVMO:
       RET
    ;*******************************************************************
    LoadDisp:
       JB   DSB_CLOCK,LD_CLOCK
       JB   DSB_TEMP1,LD_TEMP1
       JB   DSB_TEMP2,LD_TEMP2
       JB   DSB_VOLTA,LD_VOLTA
       JB   DSB_CURRE,LD_CURRE
    LD_CLOCK:
       LCALL   LoadTime
       LCALL   ValBuffToDispBuff
       RET
    LD_TEMP1:
       LCALL   CalcT1
       LCALL   ValBuffToDispBuff
       RET
    LD_TEMP2:
       LCALL   CalcT2
       LCALL   ValBuffToDispBuff
       RET
    LD_VOLTA:
       LCALL   CalcV
       LCALL   ValBuffToDispBuff
       RET
    LD_CURRE:
       LCALL   CalcI
       LCALL   ValBuffToDispBuff
       RET
    ;*******************************************************************
    LoadTime:
       MOV   A,Min
       LCALL   ByteToBCD
       MOV   ValBuff,A
       MOV   A,Hour
       LCALL   ByteToBCD
       MOV   ValBuff+1,A
       ANL   A,#0F0h
       JNZ   LZO
       MOV   A,ValBuff+1
       ANL   A,#0Fh
       ADD   A,#0B0h
       MOV   ValBuff+1,A
    LZO:
       MOV   DOTS,#0
       JNB   bBlinker,NSAD
       SETB   DOT2
       RET
    NSAD:
       JNB   bSetClock,NSWD
       JB   bBlinker,NSWD
       MOV   DOTS,#0FFh
    NSWD:
       RET
    ;*******************************************************************
    MeasureAll:
       MOV   ADCStatus,#ACS_TEMP1
       ACALL   XRADC
       MOV   ACTemperature1,A
       MOV   ADCStatus,#ACS_TEMP2
       ACALL   XRADC
       MOV   ACTemperature2,A
       MOV   ADCStatus,#ACS_VOLTA
       ACALL   XRADC
       MOV   ACVoltage,A
       MOV   ADCStatus,#ACS_CURRE
       ACALL   XRADC
       MOV   ACCurrent,A
       RET
    ;*******************************************************************
    CalcT1:
       MOV   ValBuff+1,#0EBh
       MOV   R7,ACTemperature1
       ACALL   TempCalc
       MOV   A,R7         ;wynik w R7
       CLR   C
       SUBB   A,#06Bh         ;odejmij 107
       JNC   T1Dodatnie
       CPL   A
       INC   A
       MOV   ValBuff+1,#0EAh      ;znak minus
    T1Dodatnie:
       LCALL   ByteToBCD
       MOV   ValBuff,A
       MOV   DOTS,#0
       RET
    ;*******************************************************************
    CalcT2:
       MOV   ValBuff+1,#0FBh
       MOV   ADCStatus,#07
       ACALL   XRADC
       MOV   R7,ACTemperature2
       ACALL   TempCalc
       MOV   A,R7         ;wynik w R7
       CLR   C
       SUBB   A,#06Bh         ;odejmij 107
       JNC   T2Dodatnie
       CPL   A         ;T2 ujemne
       INC   A
       MOV   ValBuff+1,#0FAh      ;znak minus
    T2Dodatnie:
       LCALL   ByteToBCD
       MOV   ValBuff,A
       MOV   DOTS,#0
       RET
    ;*******************************************************************
    CalcV:
       MOV   A,ACVoltage
       MOV   B,#064h
       DIV   AB
       MOV   ValBuff+1,A
       MOV   A,B
       LCALL   ByteToBCD
       MOV   ValBuff,A
       MOV   DOTS,#0
       SETB   DOT1
       MOV   A,ValBuff+1
       ANL   A,#0Fh
       ADD   A,#0C0h         ;wyswietl - u
       MOV   ValBuff+1,A
       RET
    ;*******************************************************************
    CalcI:
       MOV   A,ACCurrent
       MOV   B,#064h
       DIV   AB
       MOV   ValBuff+1,A
       MOV   A,B
       LCALL   ByteToBCD
       MOV   ValBuff,A
       MOV   DOTS,#0
       MOV   A,ValBuff+1
       ANL   A,#0Fh
       ADD   A,#0D0h         ;wyswietl - i
       MOV   ValBuff+1,A
       RET
    ;*******************************************************************
    ByteToBCD:
       MOV   B,#0Ah         ;A/10
       DIV   AB
       SWAP   A
       ADD   A,B
       RET
    ;*******************************************************************
    ValBuffToDispBuff:
       MOV   A,ValBuff
       MOV   DPTR,#Conv13
       ANL   A,#0Fh
       MOVC   A,@A+DPTR
       JNB   DOT0,ND0
       CLR   ACC.4
    ND0:
       MOV   DispBuff,A
       MOV   A,ValBuff+1
       ANL   A,#0Fh
       MOVC   A,@A+DPTR
       JNB   DOT2,ND2
       CLR   ACC.4
    ND2:
       MOV   DispBuff+2,A
       MOV   A,ValBuff
       MOV   DPTR,#Conv24
       SWAP   A
       ANL   A,#0Fh
       MOVC   A,@A+DPTR
       JNB   DOT1,ND1
       CLR   ACC.0
    ND1:
       MOV   DispBuff+1,A
       MOV   A,ValBuff+1
       SWAP   A
       ANL   A,#0Fh
       MOVC   A,@A+DPTR
       JNB   DOT3,ND3
       CLR   ACC.0
    ND3:
       MOV   DispBuff+3,A
       RET
    ;*******************************************************************
    Conv13:      ;0   1    2   3   4   5   6   7   8   9   -   blind
       DB   14h,0D7h,98h,91h,53h,31h,30h,17h,10h,11h,0FBh,0FFh
    Conv24:      ;0   1    2   3   4   5   6   7   8   9   -   blind
       DB   21h,7Dh, 13h,19h,4Dh,89h,81h,2Dh,01h,09h,0DFh,0FFh
          ;u    i   o(upper)  o(down)
       DB   0F1h,0F7h,  0Fh,    0D1h
    ;*******************************************************************
    OvT1:
       PUSH   ACC
       PUSH   PSW
       MOV   TH1,#256-19
       MOV   A,#0FFh
       ACALL   SendToDisp
       JB   bPowerSave,LeaveBlank
       JNB   K1,BK1
       JNB   K2,BK2
       JNB   K3,BK3
       JNB   K4,BK4
    BK1:
       SETB   K1
       CLR   K2
       MOV   A,DispBuff+2
       SJMP   Common
    BK2:
       SETB   K2
       CLR   K3
       MOV   A,DispBuff+1
       SJMP   Common
    BK3:
       SETB   K3
       CLR   K4
       MOV   A,DispBuff
       SJMP   Common
    BK4:
       CLR   K1
       SETB   K4
       MOV   A,DispBuff+3
    Common:
       ACALL   SendToDisp
    LeaveBlank:
       CPL   bSwapTmp
       JNB   bSwapTmp,NotDecCnt2s
       MOV   A,KbCnt
       JZ   NotDecKbCnt
       DEC   KbCnt
    NotDecKbCnt:
       MOV   A,Cnt2s
       JZ   NotDecCnt2s      ;czy licznik rowny 0
       DEC   Cnt2s
    NotDecCnt2s:
       POP   PSW
       POP   ACC
       RETI
    ;*******************************************************************
    OvT0:
    ;minimalny  czas =  0:00   ;maksymalny czas = 23:59
       DJNZ   Val1Cnt,LeaveOvT0   ;4000 Hz
       MOV   Val1Cnt,#DivVal1   ;16 Hz
       DJNZ   Val2Cnt,LeaveOvT0
       CPL   bBlinker      ;2 Hz
       SETB   bAllowMeasure
       MOV   Val2Cnt,#DivVal2
       DJNZ   Val3Cnt,LeaveOvT0   ;1/60Hz
       MOV   Val3Cnt,#DivVal3   ;+1min
       PUSH   ACC
       PUSH   PSW
       ACALL   IncClockValue
       DJNZ   PowSavCntDn,NotPowerSave
       ;SETB   bPowerSave
    NotPowerSave:
       POP   PSW
       POP   ACC
    LeaveOvT0:
       RETI
    ;*******************************************************************
    Sub32:
       CLR   C
       MOV   A,R7
       SUBB   A,Oper+3
       MOV   R7,A
       MOV   A,R6
       SUBB   A,Oper+2
       MOV   R6,A
       MOV   A,R5
       SUBB   A,Oper+1
       MOV   R5,A
       MOV   A,R4
       SUBB   A,Oper
       MOV   R4,A
       LJMP   ShortPop32
    ;*******************************************************************
    Mul32:
       MOV   A,R7
       MOV   R0,A
       MOV   B,Oper+3
       MUL   AB
       MOV   R7,A
       MOV   A,Oper+3
       XCH   A,B
       XCH   A,R6
       MOV   R1,A
       MUL   AB
       ADD   A,R6
       MOV   R6,A
       CLR   A
       ADDC   A,B
       XCH   A,R5
       MOV   R2,A
       MOV   B,R0
       MOV   A,Oper+2
       MUL   AB
       ADD   A,R6
       MOV   R6,A
       MOV   A,R5
       ADDC   A,B
       MOV   R5,A
       CLR   A
       RLC   A
       XCH   A,R4
       MOV   B,Oper+3
       MUL   AB
       ADD   A,R4
       MOV   R4,A
       MOV   A,Oper+2
       MOV   B,R2
       MUL   AB
       ADD   A,R4
       MOV   R4,A
       MOV   A,Oper+1
       MOV   B,R1
       MUL   AB
       ADD   A,R4
       MOV   R4,A
       MOV   A,Oper
       MOV   B,R0
       MUL   AB
       ADD   A,R4
       MOV   R4,A
       MOV   B,R1
       MOV   A,Oper+2
       MUL   AB
       ADD   A,R5
       MOV   R5,A
       MOV   A,R4
       ADDC   A,B
       MOV   R4,A
       MOV   A,Oper+1
       MOV   B,R0
       MUL   AB
       ADD   A,R5
       MOV   R5,A
       MOV   A,R4
       ADDC   A,B
       MOV   R4,A
       MOV   B,R2
       MOV   A,Oper+3
       MUL   AB
       ADD   A,R5
       MOV   R5,A
       MOV   A,R4
       ADDC   A,B
       MOV   R4,A
       LJMP   ShortPop32
    ;*******************************************************************
    Div32:
       CLR   A
       XCH   A,R4
       MOV   R0,A
       CLR   A
       XCH   A,R5
       MOV   R1,A
       CLR   A
       XCH   A,R6
       MOV   R2,A
       CLR   A
       XCH   A,R7
       MOV   R3,A
       MOV   B,#20h         ;licznik petli
    Div32Loop:
       CLR   C
       MOV   A,Oper+3
       RLC   A
       MOV   Oper+3,A
       MOV   A,Oper+2
       RLC   A
       MOV   Oper+2,A
       MOV   A,Oper+1
       RLC   A
       MOV   Oper+1,A
       MOV   A,Oper
       RLC   A
       MOV   Oper,A
       MOV   A,R7
       RLC   A
       MOV   R7,A
       MOV   A,R6
       RLC   A
       MOV   R6,A
       MOV   A,R5
       RLC   A
       MOV   R5,A
       MOV   A,R4
       RLC   A
       MOV   R4,A
       MOV   A,R7
       SUBB   A,R3
       MOV   A,R6
       SUBB   A,R2
       MOV   A,R5
       SUBB   A,R1
       MOV   A,R4
       SUBB   A,R0
       JC   Carry32
       MOV   R4,A
       MOV   A,R7
       SUBB   A,R3
       MOV   R7,A
       MOV   A,R6
       SUBB   A,R2
       MOV   R6,A
       MOV   A,R5
       SUBB   A,R1
       MOV   R5,A
       INC   Oper+3
    Carry32:
       DJNZ   B,Div32Loop
       RET
    ;*******************************************************************
    Push32:
       MOV   A,StackCount
       INC   StackCount
       JZ   NoPush32
       POP   B
       POP   ACC
       PUSH   Oper
       PUSH   Oper+1
       PUSH   Oper+2
       PUSH   Oper+3
       PUSH   ACC
       PUSH   B
    NoPush32:
       MOV   Oper+3,R7
       MOV   Oper+2,R6
       MOV   Oper+1,R5
       MOV   Oper,R4
       RET
    ;*******************************************************************
    Pop32:
       MOV   R7,Oper+3
       MOV   R6,Oper+2
       MOV   R5,Oper+1
       MOV   R4,Oper
    ShortPop32:
       MOV   A,StackCount
       DEC   A
       JZ   NoPop32
       POP   B
       POP   ACC
       POP   Oper+3
       POP   Oper+2
       POP   Oper+1
       POP   Oper
       PUSH   ACC
       PUSH   B
    NoPop32:
       DEC   StackCount
       RET
    ;*******************************************************************
       END
  • Poziom 17  
    Tak na szybko
    z procedurki interpretującej naciśnięte klawisze
    usunąłem polecenia dotyczące obsługi zegara
    wolny klawisz "ZEGAR" mozna wykorzystać do innego zadania
    Code:

    KbExecute:
       JNB   KB_T1_UP,E_T1_UP
       JNB   KB_U_I,E_U_I
       JNB   KB_ZEGAR,E_ZEGAR
       JNB   KB_T2_DOWN,E_T2_DOWN
       RET
    E_T1_UP:
    ;   JNB   bSetClock,DisplayT1
    ;   ACALL   IncClockValue
    ;   ACALL   LoadDisp
    ;   RET
    ;DisplayT1:
       MOV   DisplayStatus,#DS_TEMP1      ;#02
       ACALL   LoadDisp
       RET
       
    E_U_I:
    ;   JB   bSetClock,NotAllowed
       JB   DSB_VOLTA,SCURRE
       MOV   DisplayStatus,#DS_VOLTA      ;#08
       ACALL   LoadDisp
    ;NotAllowed:
       ACALL   WaitFreeKey
       RET
    SCURRE:
       MOV   DisplayStatus,#DS_CURRE
       ACALL   LoadDisp
       ACALL   WaitFreeKey
       RET
       
    E_ZEGAR:
    ;przycisk od zegara nie będzie aktywny
    ;można w tym miejscu przypisać mu inną funkcję
     
    ;   JB   bMoreThan2s,ZE2S
    ;   MOV   DisplayStatus,#DS_CLOCK      ;#01
    ;   ACALL   LoadDisp
    ;   RET
    ;ZE2S:
    ;   CPL   bSetClock
    ;   ACALL   LoadDisp
    ;   ACALL   WaitFreeKey
       RET
    E_T2_DOWN:
    ;   JNB   bSetClock,DisplayT2
    ;   ACALL   DecClockValue
    ;   ACALL   LoadDisp
    ;   RET
    ;DisplayT2:
       MOV   DisplayStatus,#DS_TEMP2      ;#04
       ACALL   LoadDisp
       RET
  • Poziom 25  
    pepson napisał:
    Tak na szybko
    z procedurki interpretującej naciśnięte klawisze
    usunąłem polecenia dotyczące obsługi zegara
    wolny klawisz "ZEGAR" mozna wykorzystać do innego zadania


    Niestety nie mogę ponownie przyznać punktów za pomoc dla Kolegi pepson, ale powiem wszystkim tu obecnym, ze BARDZO DZIEKUJE za pomoc.
    Kolega pepson pomógł mi niesamowicie - oryginalny projekt z PE przerobił dokładnie tak jak chciałem.
    Teraz do obsługi używam tylko dwóch klawiszy a nie czterech, nie włącza się już automatyczne wygaszanie po 10 minutach i co najważniejsze po włączeniu zasilania układ przechodzi odrazu w tryb wyświetlania napięcia pomijając ustawianie zegara...

    Wszystko to co chciałem zmienić w tym projekcie zostało zmienione przez Kolegę pepson. Wielkie ukłony dla Niego i szacunek !