;********************************************************************************* ; Matkamittari ohjelma. ;********************************************************************************* list p=16f84 include __config ( _CP_OFF & _PWRTE_ON & _XT_OSC & _WDT_OFF) errorlevel -302 ;********************************************************************************* ; Määrittelyt LCD_DATA EQU PORTA ; LCD data linjan liitännät LCD_DATA_TRIS EQU TRISA LCD_CTRL EQU PORTB ; LCD control linjan liitännät LCD_CTRL_TRIS EQU TRISB LCD_LINE0 EQU 0x000 ; LCD:n rivin 1 aloitusosoite LCD_LINE1 EQU 0x040 ; LCD:n rivin 2 aloitusosoite LCD_LINE0_A EQU 0x000 ; LCD:n rivin 1 aloitusosoite alkuosa LCD_LINE0_B EQU 0x014 ; LCD:n rivin 1 aloitusosoite loppuosa LCD_LINE1_A EQU 0x040 ; LCD:n rivin 2 aloitusosoite alkuosa LCD_LINE1_B EQU 0x054 ; LCD:n rivin 2 aloitusosoite loppuosa TOIF EQU 2 ; PORTB OHJAUS CTRL ; ----------------- SW4 EQU 7 ; CANCEL SW3 EQU 6 ; DOWN SW2 EQU 5 ; UP SW1 EQU 4 ; MENU LCD_E EQU 3 ; LCD käskyn ohjaus LCD_RW EQU 2 ; LCD luku/kirjoitus ohjaus ; "0"=kirjoitus, "1"=luku LCD_RS EQU 1 ; LCD rekisterin valinnan ohjaus ; "0"=käskyrekisteri, (kirjoitus) ; Busy flag, osoitelaskija (luku) ; "1"=datarekisteri Anturi EQU 0 ; Anturi ; PORTA OHJAUS DATA ; ----------------- RELE EQU 4 ; Rele ohjaus DB7 EQU 3 ; LCD data 7 DB6 EQU 2 ; LCD data 6 DB5 EQU 1 ; LCD data 5 DB4 EQU 0 ; LCD data 4 ;*********************************************************************************** ; Muuttujat REKISTERIT FSR EQU 0x04 ; ; EQU 0x0B ; LCD_TEMP1 EQU 0x0C ; LCD_TEMP2 EQU 0X0D ; ; EQU 0x0E ; COUNT EQU 0x0F ; H_BYTE EQU 0x10 ; Muunnettava HEX luku HH .. .. .. MH_BYTE EQU 0x11 ; Muunnettava HEX luku .. MH .. .. ML_BYTE EQU 0x12 ; Muunnettava HEX luku .. .. ML .. L_BYTE EQU 0x13 ; Muunnettava HEX luku .. .. .. LL LSD EQU 0x14 ; BIN8-DEC MSD EQU 0x15 ; BIN8-DEC EE_adress EQU 0x16 ; Muistin osoite EE_data EQU 0x17 ; Muistin sisältö DELAY EQU 0x18 ; Viiveitten muodostus X_DELAY EQU 0x19 ; Viiveitten muodostus ASETUS EQU 0x1A ; Halkaisijan asetus YMPMITL EQU 0x1B ; Pyörän ympärysmitta L-bit YMPMITH EQU 0x1C ; Pyörän ympärysmitta H-bit ; EQU 0x1D ; ; EQU 0x1E ; ; EQU 0x1F ; R0 EQU 0x20 ; Muunnettu BIN luku XX .. .. .. .. R1 EQU 0x21 ; Muunnettu BIN luku .. XX .. .. .. R2 EQU 0x22 ; Muunnettu BIN luku .. .. XX .. .. R3 EQU 0x23 ; Muunnettu BIN luku .. .. .. XX .. R4 EQU 0x24 ; Muunnettu BIN luku .. .. .. .. XX ; EQU 0x25 ; ; EQU 0x26 ; ; EQU 0x27 ; ; EQU 0x28 ; ; EQU 0x29 ; ; EQU 0x2A ; ; EQU 0x2B ; ; EQU 0x2C ; ; EQU 0x2D ; ; EQU 0x2E ; ; EQU 0x2F ; Matka1a EQU 0x30 ; Matkalaskija1 a Matka1b EQU 0x31 ; Matkalaskija1 b Matka1c EQU 0x32 ; Matkalaskija1 c Matka1d EQU 0x33 ; Matkalaskija1 d Matka2a EQU 0x34 ; Matkalaskija2 a Matka2b EQU 0x35 ; Matkalaskija2 b Matka2c EQU 0x36 ; Matkalaskija2 c Matka2d EQU 0x37 ; Matkalaskija2 d Matka3a EQU 0x38 ; Matkalaskija3 a Matka3b EQU 0x39 ; Matkalaskija3 b Matka3c EQU 0x3A ; Matkalaskija3 c Matka3d EQU 0x3B ; Matkalaskija3 d Matka4a EQU 0x3C ; Matkalaskija4 a Matka4b EQU 0x3D ; Matkalaskija4 b Matka4c EQU 0x3E ; Matkalaskija4 c Matka4d EQU 0x3F ; Matkalaskija4 d Kok_matkaa EQU 0x40 ; Kokonaismatka a Kok_matkab EQU 0x41 ; Kokonaismatka b Kok_matkac EQU 0x42 ; Kokonaismatka c Kok_matkad EQU 0x43 ; Kokonaismatka d ; EQU 0x44 ; OSOITIN EQU 0x45 ; Välimatka näytön päivityksen osoitin AIKALASK EQU 0x46 ; Aikalaskija TMP1 EQU 0x47 ; Tilapäisrekisteri 1 TMP2 EQU 0x48 ; Tilapäisrekisteri 2 TMP3 EQU 0x49 ; Tilapäisrekisteri 3 TMP4 EQU 0x4A ; Tilapäisrekisteri 4 TMP5 EQU 0x4B ; Tilapäisrekisteri 5 TMP6 EQU 0x4C ; Tilapäisrekisteri 6 TMP7 EQU 0x4D ; Tilapäisrekisteri 7 TMP8 EQU 0x4E ; Tilapäisrekisteri 8 TMP EQU 0x4F ; Tilapäisrekisteri ;********************************************************************************* ; Käynnistysosoitin org H'000' goto START ;********************************************************************************* ; Taulukot NUMERO_TABLE ADDWF PCL,F RETLW A'0' RETLW A'1' RETLW A'2' RETLW A'3' RETLW A'4' RETLW A'5' RETLW A'6' RETLW A'7' RETLW A'8' RETLW A'9' ;********************************************************************************* ; Ohjelma alkaa tästä START CLRF STATUS ; bank 0 valinta CLRF INTCON ; nollataan liput, estetään keskeytykset CLRF PCLATH ; käytetään alinta 2KByte aluetta CLRF PORTA ; kaikki lähtöportit alas porta CLRF PORTB ; kaikki lähtöportit alas portb BSF STATUS, RP0 ; valitaan bank 1 MOVLW b'00000000' ; RA4-0 outputs MOVWF TRISA MOVLW b'11110001' ; RB7-4 ja 0 input. RB3-1 output. MOVWF TRISB BSF OPTION_REG, NOT_RBPU ; PORTB pull-ups esto BCF STATUS, RP0 ; valitaan bank 0 CALL LCDINIT ; Alustetaan LCD-näyttö CLRF Kok_matkaa ; tyhjennetään rekisterit CLRF Kok_matkab CLRF Kok_matkac CLRF Kok_matkad CLRF Matka1a CLRF Matka1b CLRF Matka1c CLRF Matka1d CLRF Matka2a CLRF Matka2b CLRF Matka2c CLRF Matka2d CLRF Matka3a CLRF Matka3b CLRF Matka3c CLRF Matka3d CLRF Matka4a CLRF Matka4b CLRF Matka4c CLRF Matka4d CLRF TMP CLRF TMP1 CLRF TMP2 CLRF TMP3 CLRF TMP4 CLRF TMP5 CLRF TMP6 CLRF TMP7 CLRF TMP8 CLRF ASETUS CLRF EE_adress CLRF EE_data CLRF H_BYTE CLRF MH_BYTE CLRF ML_BYTE CLRF L_BYTE CLRF OSOITIN BSF LCD_DATA,RELE ; asetetaan RELE vapaatilaan ; Noudetaan muistista edellisen jakson MOVLW 0x20 ; aikana ollut viimeinen kokonaislukema. MOVWF EE_adress ; Annetaan osoite 0x20 EE_adress CALL MEMREAD ; Luetaan muisti MOVWF Kok_matkaa ; Siirretään Kok_matkaa rekisteriin MOVLW 0x21 MOVWF EE_adress CALL MEMREAD MOVWF Kok_matkab MOVLW 0x22 MOVWF EE_adress CALL MEMREAD MOVWF Kok_matkac MOVLW 0x23 MOVWF EE_adress CALL MEMREAD MOVWF Kok_matkad MOVLW 0x10 ; Noudetaan muistista pyörän halkaisijan mitta MOVWF EE_adress CALL MEMREAD MOVWF ASETUS MOVLW 0x12 ; Noudetaan muistista pyörän ympärysmitta H-bit MOVWF EE_adress CALL MEMREAD MOVWF YMPMITH MOVLW 0x13 ; Noudetaan muistista pyörän ympärysmitta L-bit MOVWF EE_adress CALL MEMREAD MOVWF YMPMITL BSF OSOITIN,0 ;********************************************************************************* ; Ohjelman alku ohjelma1 CALL LCDCLEAR ; tyhjennetään näyttö MOVLW LCD_LINE1_B+0x04; Tekstin aloituskohta Rivi2 loppu CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A'M' ; Merkki 'M' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'a' ; Merkki 'a' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A't' ; Merkki 't' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A't' ; Merkki 't' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'i' ; Merkki 'i' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A' ' ; Merkki ' ' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'J' ; Merkki 'J' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW h'E1' ; Merkki 'ä' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'r' ; Merkki 'r' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'v' ; Merkki 'v' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'i' ; Merkki 'i' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'n' ; Merkki 'n' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'e' ; Merkki 'e' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVLW A'n' ; Merkki 'n' CALL LCDPUTCHAR ; siirretään LCD näytölle MOVFW Kok_matkaa ; Kokonaismatka lukeman numerot xx .. .. .. MOVWF H_BYTE ; siirretään H_BYTE:en MOVFW Kok_matkab ; Kokonaismatka lukeman numerot .. xx .. .. MOVWF MH_BYTE ; siirretään MH_BYTE MOVFW Kok_matkac ; Kokonaismatka lukeman numerot .. .. xx .. MOVWF ML_BYTE ; siirretään ML_BYTE MOVFW Kok_matkad ; Kokonaismatka lukeman numerot .. .. .. xx MOVWF L_BYTE ; siirretään L_BYTE CALL B4_BCD ; suoritetaan muunnos 32bit BIN -> BCD CALL matka_tul ; siirretään LCD näytölle GOTO SW4_OK ; SW4_OK:n kautta painikkeiden valvontaan ;********************************************************************************* ; Painikkeiden ja anturin valvonta. PAINIKE_VALV ; Painikkeiden valvonta. ; Alkukäynnistyksessä asetetaan välimatkanäyttö. BTFSC OSOITIN,0 ; Ohita seuraava jos OSOITIN bit0 = 0 GOTO SW1_tuli ; SW1 tuli siirrytään ohjelmaan SW1_tuli ; Välimatka 1 BTFSS LCD_CTRL,SW1 ; Ohita seuraava jos SW1 = 0 GOTO SW1_tuli ; SW1 tuli siirrytään ohjelmaan SW1_tuli ; Välimatka 1 BTFSS LCD_CTRL,SW2 ; Ohita seuraava jos SW2 = 0 GOTO SW2_tuli ; SW2 tuli siirrytään ohjelmaan SW2_tuli ; Välimatka 2 BTFSS LCD_CTRL,SW3 ; Ohita seuraava jos SW3 = 0 GOTO SW3_tuli ; SW3 tuli siirrytään ohjelmaan SW3_tuli ; Välimatka 3 BTFSS LCD_CTRL,SW4 ; Ohita seuraava jos SW4 = 0 GOTO SW4_tuli ; SW4 tuli siirrytään ohjelmaan SW4_tuli ; Välimatka 4 BTFSS LCD_CTRL,Anturi ; Ohita seuraava jos Anturi = 0 GOTO Anturi_tuli ; Anturi tuli siirrytään ohjelmaan Anturi_tuli ; Laskijoiden ja LCD:n tietojen päivitys GOTO PAINIKE_VALV ; ;********************************************************************************* ; Kirjoitetaan teksti "Välimatka" LCD näytölle VALIM MOVLW LCD_LINE0_B+0x01; Tekstin aloituskohta Rivi1 alku CALL LCDSDDA ; siirretään kursori em. paikkaan CALL POIS7 ; Poistetaan 7 merkkiä MOVLW LCD_LINE0_B+0x01; Tekstin aloituskohta Rivi1 alku CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A'V' ; V CALL LCDPUTCHAR ; merkki näytölle MOVLW h'E1' ; ä CALL LCDPUTCHAR ; merkki näytölle MOVLW A'l' ; l CALL LCDPUTCHAR ; merkki näytölle MOVLW A'i' ; i CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle RETURN ;--------------------------------------------------------------------------------- ; Välimatka rekisterin sisällön näyttö LCD:llä NAUTA_VALI MOVLW LCD_LINE0_B+0x08; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan CALL B4_BCD ; suoritetaan muunnos 32bit BIN -> BCD CALL NAYTA_TULOS ; siirretään LCD näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle MOVLW A'k' ; k CALL LCDPUTCHAR ; merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; merkki näytölle RETURN ;********************************************************************************* ; Välimatka 1 valintapainike SW1 toiminta SW1_tuli CLRF OSOITIN ; Nollataan osoittimet BSF OSOITIN,1 ; Asetetaan osoitin 1 CALL VALIM ; Kirjoitetaan teksti "Välimatka" MOVLW A'1' ; 1 CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle CALL SW1_LCD ; Rekisterit kopioidaan toiseen paikkaan CALL NAUTA_VALI ; Näytetään LCD:llä ;-------------------------------- ; Jos painiketta painetaan n.4s välimatka rekisterit tyhjennetään. ; Jos painetaan samaan aikaan SW4 siirrytään Asetus valikkoon. ; Jos painike vapautetaan ennen asetetun ajan kulumista ei matkarekistereitä ; tyhjennetä, vaan asetetaan näytön valinta ja näytetään matka. ; Valinta jää voimaan kunnes valitaan jokin toinen välimatka. ;-------------------------------- MOVLW 0x19 ; W = 19h = 25 MOVWF AIKALASK ; AIKALASK = W MOVLW 0x3C ; W = 3Ch = 60 SW1_pois CALL X_DELAY500 ; Odotetaan 60 x 500uS = 30ms BTFSS LCD_CTRL,SW4 ; Onko nappi SW4 ; On GOTO SW1_SW4_tuli ; Asetukseen ; Ei DECF AIKALASK,F ; AIKALASK = AIKALASK - 1 BTFSC STATUS,Z ; Oliko AIKALASK 0 GOTO SW1_NOLLAUS ; Oli ; Ei BTFSS LCD_CTRL,SW1 ; odotetaan nappi pois GOTO SW1_pois ; SW1_ulos GOTO PAINIKE_VALV ; SW1_NOLLAUS CLRF Matka1a ; Tyhjennetään rekisterit CLRF Matka1b CLRF Matka1c CLRF Matka1d GOTO SW1_ulos ;--------------------------------------------------------------------------------- ; Kopioidaan Matka1 muunnos rekistereihin SW1_LCD MOVFW Matka1a ; Matka1a -> W MOVWF H_BYTE ; siirretään H_BYTE MOVFW Matka1b ; Matka1b -> W MOVWF MH_BYTE ; siirretään MH_BYTE MOVFW Matka1c ; Matka1c -> W MOVWF ML_BYTE ; siirretään ML_BYTE MOVFW Matka1d ; Matka1d -> W MOVWF L_BYTE ; siirretään L_BYTE RETURN ;********************************************************************************* ; Välimatka 2 valintapainike SW2 toiminta SW2_tuli CLRF OSOITIN ; Nollataan osoittimet BSF OSOITIN,2 ; Asetetaan osoitin 2 CALL VALIM ; Kirjoitetaan teksti "Välimatka" MOVLW A'2' ; 2 CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle CALL SW2_LCD ; Rekisterit kopioidaan toiseen paikkaan CALL NAUTA_VALI ; Näytetään LCD:llä ;-------------------------------- ; Jos painiketta painetaan n.4s välimatka rekisterit tyhjennetään. ; Jos painike vapautetaan ennen asetetun ajan kulumista ei matkarekistereitä ; tyhjennetä, vaan asetetaan näytön valinta ja näytetään matka. ; Valinta jää voimaan kunnes valitaan jokin toinen välimatka. ;-------------------------------- MOVLW 0x19 ; W = 19h = 25 MOVWF AIKALASK ; AIKALASK = W MOVLW 0x3C ; W = 3Ch = 60 SW2_pois CALL X_DELAY500 ; Odotetaan 60 x 500uS = 30ms DECF AIKALASK,F ; AIKALASK = AIKALASK - 1 BTFSC STATUS,Z ; Oliko AIKALASK 0 GOTO SW2_NOLLAUS ; Oli ; Ei BTFSS LCD_CTRL,SW2 ; odotetaan nappi pois GOTO SW2_pois ; SW2_ulos GOTO PAINIKE_VALV ; SW2_NOLLAUS CLRF Matka2a ; Tyhjennetään rekisterit CLRF Matka2b CLRF Matka2c CLRF Matka2d GOTO SW2_ulos ;--------------------------------------------------------------------------------- ; Kopioidaan Matka2 muunnos rekistereihin SW2_LCD MOVFW Matka2a ; Matka2a -> W MOVWF H_BYTE ; siirretään H_BYTE MOVFW Matka2b ; Matka2b -> W MOVWF MH_BYTE ; siirretään MH_BYTE MOVFW Matka2c ; Matka2c -> W MOVWF ML_BYTE ; siirretään ML_BYTE MOVFW Matka2d ; Matka2d -> W MOVWF L_BYTE ; siirretään L_BYTE RETURN ;********************************************************************************* ; Välimatka 3 valintapainike SW3 toiminta SW3_tuli CLRF OSOITIN ; Nollataan osoittimet BSF OSOITIN,3 ; Asetetaan osoitin 3 CALL VALIM ; Kirjoitetaan teksti "Välimatka" MOVLW A'3' ; 3 CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle CALL SW3_LCD ; Rekisterit kopioidaan toiseen paikkaan CALL NAUTA_VALI ; Näytetään LCD:llä ;-------------------------------- ; Jos painiketta painetaan n.4s välimatka rekisterit tyhjennetään. ; Jos painike vapautetaan ennen asetetun ajan kulumista ei matkarekistereitä ; tyhjennetä, vaan asetetaan näytön valinta ja näytetään matka. ; Valinta jää voimaan kunnes valitaan jokin toinen välimatka. ;-------------------------------- MOVLW 0x19 ; W = 19h = 25 MOVWF AIKALASK ; AIKALASK = W MOVLW 0x3C ; W = 3Ch = 60 SW3_pois CALL X_DELAY500 ; Odotetaan 60 x 500uS = 30ms DECF AIKALASK,F ; AIKALASK = AIKALASK - 1 BTFSC STATUS,Z ; Oliko AIKALASK 0 GOTO SW3_NOLLAUS ; Oli ; Ei BTFSS LCD_CTRL,SW3 ; odotetaan nappi pois GOTO SW3_pois ; SW3_ulos GOTO PAINIKE_VALV ; SW3_NOLLAUS CLRF Matka3a ; Tyhjennetään rekisterit CLRF Matka3b CLRF Matka3c CLRF Matka3d GOTO SW3_ulos ;--------------------------------------------------------------------------------- ; Kopioidaan Matka3 muunnos rekistereihin SW3_LCD MOVFW Matka3a ; Matka3a -> W MOVWF H_BYTE ; siirretään H_BYTE MOVFW Matka3b ; Matka3b -> W MOVWF MH_BYTE ; siirretään MH_BYTE MOVFW Matka3c ; Matka3c -> W MOVWF ML_BYTE ; siirretään ML_BYTE MOVFW Matka3d ; Matka3d -> W MOVWF L_BYTE ; siirretään L_BYTE RETURN ;********************************************************************************* ; Välimatka 4 valintapainike SW4 toiminta SW4_tuli CLRF OSOITIN ; Nollataan osoitin BSF OSOITIN,4 ; Asetetaan osoitin 4 CALL VALIM ; Kirjoitetaan teksti "Välimatka" MOVLW A'4' ; 4 CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle CALL SW4_LCD ; Rekisterit kopioidaan toiseen paikkaan CALL NAUTA_VALI ; Näytetään LCD:llä ;-------------------------------- ; Jos painiketta painetaan n.4s välimatka rekisterit tyhjennetään. ; Jos painetaan samaan aikaan SW1 siirrytään Asetus valikkoon. ; Jos painike vapautetaan ennen asetetun ajan kulumista ei matkarekistereitä ; tyhjennetä, vaan asetetaan näytön valinta ja näytetään matka. ; Valinta jää voimaan kunnes valitaan jokin toinen välimatka. ;-------------------------------- MOVLW 0x19 ; W = 19h = 25 MOVWF AIKALASK ; AIKALASK = W MOVLW 0x3C ; W = 3Ch = 60 SW4_pois CALL X_DELAY500 ; Odotetaan 60 x 500uS = 30ms BTFSS LCD_CTRL,SW1 ; Onko nappi SW1 ; On GOTO SW1_SW4_tuli ; Asetukseen ; Ei DECF AIKALASK,F ; AIKALASK = AIKALASK - 1 BTFSC STATUS,Z ; Oliko AIKALASK 0 GOTO SW4_NOLLAUS ; Oli ; Ei BTFSS LCD_CTRL,SW4 ; odotetaan nappi pois GOTO SW4_pois ; SW4_ulos GOTO PAINIKE_VALV ; Takaisin painikkeitten valvontaan SW4_NOLLAUS CLRF Matka4a ; Nollataan Matka3 rekisterit CLRF Matka4b CLRF Matka4c CLRF Matka4d GOTO SW4_ulos ;--------------------------------------------------------------------------------- ; Kopioidaan Matka4 muunnos rekistereihin SW4_LCD MOVFW Matka4a ; Matka4a -> W MOVWF H_BYTE ; siirretään H_BYTE MOVFW Matka4b ; Matka4b -> W MOVWF MH_BYTE ; siirretään MH_BYTE MOVFW Matka4c ; Matka4c -> W MOVWF ML_BYTE ; siirretään ML_BYTE MOVFW Matka4d ; Matka4d -> W MOVWF L_BYTE ; siirretään L_BYTE RETURN ;********************************************************************************* ; Anturin toiminta ; Siirretään ympärysmitta rekistereihin TMP3 ja TMP4 laskentaa varten. YMPMITY CLRF TMP1 ; TMP1 = 0 CLRF TMP2 ; TMP2 = 0 MOVFW YMPMITH ; YMPMITH -> W MOVWF TMP3 ; W -> TMP3 MOVFW YMPMITL ; YMPMITL -> W MOVWF TMP4 ; W -> TMP4 RETURN ;--------------------------------------------------------------------------------- Anturi_tuli ; Näytetään anturin havahtumismerkki MOVLW LCD_LINE0+0x13 ; Tekstin aloituskohta Rivi0 CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW 0xFF ; 0xFF CALL LCDPUTCHAR ; merkki näytölle BCF LCD_DATA,RELE ; Kytketään RELE Anturi_pois CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,Anturi ; odotetaan anturin poistumista GOTO Anturi_pois ; Poistetaan anturin havahtumismerkki MOVLW LCD_LINE0+0x13 ; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle ;--------------------------------------------------------------------------------- ; Pyörän ympärysmitan lisääminen Matka1 rekistereihin CALL YMPMITY ; Lisätään ympärysmitta laskentarekistereihin MOVFW Matka1a ; Matka1a -> W MOVWF TMP5 ; W -> TMP5 MOVFW Matka1b ; Matka1b -> W MOVWF TMP6 ; W -> TMP6 MOVFW Matka1c ; Matka1c -> W MOVWF TMP7 ; W -> TMP7 MOVFW Matka1d ; Matka1d -> W MOVWF TMP8 ; W -> TMP8 CALL D_ADD32 ; Lasketaan yhteen MOVFW TMP5 ; TMP5 -> W MOVWF Matka1a ; Matka1a rekisteriin MOVFW TMP6 ; TMP6 -> W MOVWF Matka1b ; Matka1b rekisteriin MOVFW TMP7 ; TMP7 -> W MOVWF Matka1c ; Matka1c rekisteriin MOVFW TMP8 ; TMP8 -> W MOVWF Matka1d ; Matka1d rekisteriin ;--------------------------------------------------------------------------------- ; Pyörän ympärysmitan lisääminen Matka2 rekistereihin CALL YMPMITY ; Lisätään ympärysmitta laskentarekistereihin MOVFW Matka2a ; Matka2a -> W MOVWF TMP5 ; W -> TMP5 MOVFW Matka2b ; Matka2b -> W MOVWF TMP6 ; W -> TMP6 MOVFW Matka2c ; Matka2c -> W MOVWF TMP7 ; W -> TMP7 MOVFW Matka2d ; Matka2d -> W MOVWF TMP8 ; W -> TMP8 CALL D_ADD32 ; Lasketaan yhteen MOVFW TMP5 ; TMP5 -> W MOVWF Matka2a ; Matka2a rekisteriin MOVFW TMP6 ; TMP6 -> W MOVWF Matka2b ; Matka2b rekisteriin MOVFW TMP7 ; TMP7 -> W MOVWF Matka2c ; Matka2c rekisteriin MOVFW TMP8 ; TMP8 -> W MOVWF Matka2d ; Matka2d rekisteriin ;--------------------------------------------------------------------------------- ; Pyörän ympärysmitan lisääminen Matka3 rekistereihin CALL YMPMITY ; Lisätään ympärysmitta laskentarekistereihin MOVFW Matka3a ; Matka3a -> W MOVWF TMP5 ; W -> TMP5 MOVFW Matka3b ; Matka3b -> W MOVWF TMP6 ; W -> TMP6 MOVFW Matka3c ; Matka3c -> W MOVWF TMP7 ; W -> TMP7 MOVFW Matka3d ; Matka3d -> W MOVWF TMP8 ; W -> TMP8 CALL D_ADD32 ; Lasketaan yhteen MOVFW TMP5 ; TMP5 -> W MOVWF Matka3a ; Matka3a rekisteriin MOVFW TMP6 ; TMP6 -> W MOVWF Matka3b ; Matka3b rekisteriin MOVFW TMP7 ; TMP7 -> W MOVWF Matka3c ; Matka3c rekisteriin MOVFW TMP8 ; TMP8 -> W MOVWF Matka3d ; Matka3d rekisteriin ;--------------------------------------------------------------------------------- ; Pyörän ympärysmitan lisääminen Matka4 rekistereihin CALL YMPMITY ; Lisätään ympärysmitta laskentarekistereihin MOVFW Matka4a ; Matka4a -> W MOVWF TMP5 ; W -> TMP5 MOVFW Matka4b ; Matka4b -> W MOVWF TMP6 ; W -> TMP6 MOVFW Matka4c ; Matka4c -> W MOVWF TMP7 ; W -> TMP7 MOVFW Matka4d ; Matka4d -> W MOVWF TMP8 ; W -> TMP8 CALL D_ADD32 ; Lasketaan yhteen MOVFW TMP5 ; TMP5 -> W MOVWF Matka4a ; Matka4a rekisteriin MOVFW TMP6 ; TMP6 -> W MOVWF Matka4b ; Matka4b rekisteriin MOVFW TMP7 ; TMP7 -> W MOVWF Matka4c ; Matka4c rekisteriin MOVFW TMP8 ; TMP8 -> W MOVWF Matka4d ; Matka4d rekisteriin ;--------------------------------------------------------------------------------- ; Pyörän ympärysmitan lisääminen Kok_matka rekistereihin CALL YMPMITY ; Lisätään ympärysmitta laskentarekistereihin MOVFW Kok_matkaa ; Kok_matkaa -> W MOVWF TMP5 ; W -> TMP5 MOVFW Kok_matkab ; Kok_matkab -> W MOVWF TMP6 ; W -> TMP6 MOVFW Kok_matkac ; Kok_matkac -> W MOVWF TMP7 ; W -> TMP7 MOVFW Kok_matkad ; Kok_matkad -> W MOVWF TMP8 ; W -> TMP8 CALL D_ADD32 ; Lasketaan yhteen ;--------------------------------------------------------------------------------- ; Päivitetään kokonaismatka rekisteri sekä valmistellaan näytön päivitystä ; siirtämällä laskennan tulos H_BYTE, MH_BYTE, ML_BYTE ja L_BYTE rekistereihin MOVFW TMP5 ; TMP5 -> W MOVWF H_BYTE ; siirretään H_BYTE MOVWF Kok_matkaa ; ja Kok_matkaa rekisteriin MOVFW TMP6 ; TMP6 -> W MOVWF MH_BYTE ; siirretään MH_BYTE MOVWF Kok_matkab ; ja Kok_matkab rekisteriin MOVFW TMP7 ; TMP7 -> W MOVWF ML_BYTE ; siirretään ML_BYTE MOVWF Kok_matkac ; ja Kok_matkac rekisteriin MOVFW TMP8 ; TMP8 -> W MOVWF L_BYTE ; siirretään L_BYTE MOVWF Kok_matkad ; ja Kok_matkad rekisteriin ;--------------------------------------------------------------------------------- ; Kirjoitetaan laskennan tulos muistiin EEPROMiin ; osoitteisiin 20h = H_BYTE, 21h = MH_BYTE, 22h = ML_BYTE ja 23h = L_BYTE MOVLW 0x20 ; W = 20h MOVWF EE_adress ; EE_address = W MOVFW H_BYTE ; H_BYTE -> W MOVWF EE_data ; W -> EE_data CALL WRITEMEM ; kirjoitetaan muistipaikkaan MOVLW 0x21 ; W = 21h MOVWF EE_adress ; EE_address = W MOVFW MH_BYTE ; MH_BYTE -> W MOVWF EE_data ; W -> EE_data CALL WRITEMEM ; kirjoitetaan muistipaikkaan MOVLW 0x22 ; W = 22h MOVWF EE_adress ; EE_address = W MOVFW ML_BYTE ; ML_BYTE -> W MOVWF EE_data ; W -> EE_data CALL WRITEMEM ; kirjoitetaan muistipaikkaan MOVLW 0x23 ; W = 23h MOVWF EE_adress ; EE_address = W MOVFW L_BYTE ; L_BYTE -> W MOVWF EE_data ; W -> EE_data CALL WRITEMEM ; kirjoitetaan muistipaikkaan BSF LCD_DATA,RELE ; irroitetaan RELE ;--------------------------------------------------------------------------------- ; Kokonaismatkan päivitys LCD näytölle MOVLW LCD_LINE0_A ; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan CALL B4_BCD ; suoritetaan muunnos 32bit BIN -> BCD CALL matka_tul ; siirretään LCD näytölle ;--------------------------------------------------------------------------------- ; Välimatka näyttöjen valinta BTFSC OSOITIN,1 ; Jos osoitin 1 on 1 CALL SW1_LCD ; päivitetään ja näytetään Välimatka 1 BTFSC OSOITIN,2 ; Jos osoitin 2 on 1 CALL SW2_LCD ; päivitetään ja näytetään Välimatka 2 BTFSC OSOITIN,3 ; Jos osoitin 3 on 1 CALL SW3_LCD ; päivitetään ja näytetään Välimatka 3 BTFSC OSOITIN,4 ; Jos osoitin 4 on 1 CALL SW4_LCD ; päivitetään ja näytetään Välimatka 4 CALL NAUTA_VALI ; Näytetään välimatkanäyttö GOTO PAINIKE_VALV ; ;********************************************************************************* ; Asetusvalikko. Painettaessa samaan aikaan SW1 ja SW4. SW1_SW4_tuli MOVLW LCD_LINE1_A ; Tekstin aloituskohta Rivi0 CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A'H' ; H CALL LCDPUTCHAR ; merkki näytölle MOVLW A'a' ; a CALL LCDPUTCHAR ; merkki näytölle MOVLW A'l' ; l CALL LCDPUTCHAR ; merkki näytölle MOVLW A'k' ; k CALL LCDPUTCHAR ; merkki näytölle MOVLW A'a' ; a CALL LCDPUTCHAR ; merkki näytölle MOVLW A'i' ; i CALL LCDPUTCHAR ; merkki näytölle MOVLW A's' ; s CALL LCDPUTCHAR ; merkki näytölle MOVLW A'i' ; i CALL LCDPUTCHAR ; merkki näytölle MOVLW A'j' ; j CALL LCDPUTCHAR ; merkki näytölle MOVLW A'a' ; a CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle ; Noudetaan pyörän ympärysmitan matka muistista MOVLW 0x10 ; osoitteesta 0010 MOVWF EE_adress ; osoite muistipaikan osoitteeksi CALL MEMREAD ; Luetaan muisti MOVFW EE_data ; EE_data -> W MOVWF L_BYTE ; W -> L_BYTE CALL B4_BCD ; Muunnetaan desimaaliseksi MOVLW LCD_LINE1_A+0x0C; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan CALL NAYTA_HALK ; Näytetään LCD:llä MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; merkki näytölle SW4a_pois CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,SW4 ; odotetaan nappi pois GOTO SW4a_pois ; SW1a_pois CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,SW1 ; odotetaan nappi pois GOTO SW1a_pois ; HALKAISIJA ; halkaisija min 10cm max 100cm MOVLW 0x10 ; Muistipaikan osoite -> W MOVWF EE_adress ; W -> Muistipaikan osoitteeksi CALL MEMREAD ; Luetaan muistipaikka MOVFW EE_data ; EE_data -> W MOVWF ASETUS ; W -> ASETUS ;********************************************************************************* ; Asetus valikko. Pyörän halkaisijan lisäys ja vähennys sekä poistuminen valikosta H_ASET ; ASETUSVALIKKO BTFSS LCD_CTRL,SW2 ; Ohita seuraava jos SW2 = 0 GOTO SW2_NEG ; SW2 tuli siirrytään ohjelmaan SW2_NEG ; vähennetään halkaisijaa BTFSS LCD_CTRL,SW3 ; Ohita seuraava jos SW3 = 0 GOTO SW3_POS ; SW3 tuli siirrytään ohjelmaan SW3_POS ; lisätään halkaisijaa BTFSS LCD_CTRL,SW4 ; Ohita seuraava jos SW4 = 0 GOTO SW4_OK ; SW4 tuli siirrytään paikkaan SW4_OK ; talletetaan asetukset ja poistutaan valikosta GOTO H_ASET ; siirrytään paikkaan H_ASET ;********************************************************************************* ; ASETUS muutos, eli pyörän halkaisijan muuttaminen SW3_POS ; Lisätään laskijaa askel kerrallaan ; maksimi 64h = 100d CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,SW3 ; odotetaan nappi pois GOTO SW3_POS ; INCF ASETUS,F ; ASETUS = ASETUS + 1 MOVLW 0x9B ; W = 9Bh ADDWF ASETUS,W ; W = W + ASETUS BTFSC STATUS,C ; Oliko yli 64h (tuliko CARRY bit) ; Kyllä DECF ASETUS,F ; ASETUS = ASETUS - 1 ; Ei GOTO H_ASET_N SW2_NEG ; Vähennetään laskijaa askel kerrallaan ; minimi 09h = 09d CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,SW2 ; odotetaan nappi pois GOTO SW2_NEG ; DECF ASETUS,F ; ASETUS = ASETUS - 1 MOVLW 0x09 ; W = 09h SUBWF ASETUS,W ; W = W - ASETUS BTFSC STATUS,Z ; Oliko alle 09h (tuliko ZERO bit) INCF ASETUS,F ; ASETUS = ASETUS + 1 H_ASET_N ; Näytetään merkki LCD:llä MOVFW ASETUS ; ASETUS -> W MOVWF L_BYTE ; W -> L_BYTE CALL B4_BCD ; Muunnetaan desimaaliseksi MOVLW LCD_LINE1_A+0x0C; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan CALL NAYTA_HALK ; Näytetään LCD:llä MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; merkki näytölle GOTO H_ASET ; Palataan asetusvalikkoon ;--------------------------------------------------------------------------------- SW4_OK ; Poistutaan asetuksesta CALL DELAY500 ; Odotetaan 500uS BTFSS LCD_CTRL,SW4 ; odotetaan nappi pois GOTO SW4_OK ; Tyhjennetään rivi MOVLW LCD_LINE1_A ; Tekstin aloituskohta Rivi1 alku CALL LCDSDDA ; siirretään kursori em. paikkaan CALL POIS10 ; Poistetaan 20 merkkiä näytöltä CALL POIS10 ; Kirjoitetaan Pyörän halkaisija muistiin MOVFW ASETUS ; ASETUS -> W MOVWF EE_data ; W -> EE_data MOVLW 0x10 ; W = 0010 MOVWF EE_adress ; W -> EE_adress CALL WRITEMEM ; Kirjoitetaan muistiin ;--------------------------------------------------------------------------------- ; Lasketaan pyörän ympärysmitta ; ASETUS * 314 / 100 ; Asetus kerrottavaksi CLRF TMP3 ; TMP = 0 MOVFW ASETUS ; ASETUS -> W MOVWF TMP4 ; W -> TMP4 ; 314 kertojaksi MOVLW 0x01 ; W = 0001 MOVWF TMP5 ; W -> TMP5 MOVLW 0x3A ; W = 003A MOVWF TMP6 ; W -> TMP6 CLRF TMP7 ; TMP7 = 0 CLRF TMP8 ; TMP8 = 0 CALL KERTO_XXXX ; KERROTAAN CLRF TMP5 ; TMP5 = 0 ; Tulos säilyy rekistereissä TMP7 ja TMP8 ; 100 jakajaksi MOVLW 0x64 ; W = 0064h = 100d MOVWF TMP6 ; W -> TMP6 CALL JAKO_XXXX ; JAETAAN ; Kirjoitetaan tulos muistiin MOVFW TMP7 ; TMP7 -> W MOVWF YMPMITH ; Ylempi sana W rekisteriin MOVWF ML_BYTE MOVWF EE_data ; W -> EE_data MOVLW 0x12 ; W = 0012 MOVWF EE_adress ; W -> EE_adress, muistipaikan osoite CALL WRITEMEM ; Kirjoitetaan muistiin MOVFW TMP8 ; TMP8 -> W MOVWF YMPMITL ; Alempi sana W rekisteriin MOVWF L_BYTE MOVWF EE_data ; W -> EE_data MOVLW 0x13 ; W = 0013 MOVWF EE_adress ; W -> EE_adress, muistipaikan osoite CALL WRITEMEM ; Kirjoitetaan muistiin MOVLW LCD_LINE1_A ; Tekstin aloituskohta Rivi1 alku CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A'Y' ; Y CALL LCDPUTCHAR ; merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; merkki näytölle MOVLW A'p' ; p CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle CALL B4_BCD ; Muunnetaan desimaaliseksi CALL NAYTA_HALK ; Näytetään LCD;llä MOVLW A' ' ; CALL LCDPUTCHAR ; merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; merkki näytölle GOTO PAINIKE_VALV ; Poistutaan asetuksesta !!!!!! ;********************************************************************************* ; Matkan siirto LCD näytölle ; Kirjoitetaan Matka ja lisätään laskijan sisältö, pilkku ja loppuun km. matka_tul MOVLW LCD_LINE0_A ; Tekstin aloituskohta Rivi1 CALL LCDSDDA ; siirretään kursori em. paikkaan MOVLW A'M' ; M CALL LCDPUTCHAR ; merkki siirretään näytölle MOVLW A'a' ; a CALL LCDPUTCHAR ; merkki siirretään näytölle MOVLW A't' ; t CALL LCDPUTCHAR ; merkki siirretään näytölle MOVLW A'k' ; k CALL LCDPUTCHAR ; merkki siirretään näytölle MOVLW A'a' ; a CALL LCDPUTCHAR ; merkki siirretään näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; merkki siirretään näytölle CALL NAYTA_TULOS ; Näytetään matkalukema MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A'k' ; k CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A'm' ; m CALL LCDPUTCHAR ; siirretään merkki näytölle RETURN ;********************************************************************************* ; Tulosten siirto LCD näytölle ; Tulokset rekistereissä R0,R1,R2,R3,R4. Ascii merkki haetaan taulukosta ja ; siirretään aliohjelmassa LCD näytölle NAYTA_TULOS SWAPF R0, W ; Siirretään R0 rekisterin yläosa ; W rekisteriin alaosaksi CALL SIIRTO MOVFW R0 ; siirretään R0 -> W CALL SIIRTO SWAPF R1, W ; Siirretään R1 rekisterin yläosa ; W rekisteriin alaosaksi CALL SIIRTO MOVFW R1 ; siirretään R1 -> W CALL SIIRTO SWAPF R2, W ; Siirretään R2 rekisterin yläosa ; W rekisteriin alaosaksi CALL SIIRTO MOVLW A',' ; , CALL LCDPUTCHAR ; siirretään merkki näytölle MOVFW R2 ; siirretään R2 -> W CALL SIIRTO SWAPF R3, W ; Siirretään R3 rekisterin yläosa ; W rekisteriin alaosaksi CALL SIIRTO MOVFW R3 ; siirretään R3 -> W CALL SIIRTO RETURN ;--------------------------------------------------------------------------------- NAYTA_HALK MOVFW R3 ; siirretään R3 -> W CALL SIIRTO MOVLW A',' ; , CALL LCDPUTCHAR ; siirretään merkki näytölle SWAPF R4, W ; Siirretään R4 rekisterin yläosa ; W rekisteriin alaosaksi CALL SIIRTO MOVFW R4 ; siirretään R4 -> W CALL SIIRTO RETURN SIIRTO ANDLW b'00001111' ; W:n sisällöstä poistetaan yläosa CALL NUMERO_TABLE ; haetaan numero taulukosta NOP CALL LCDPUTCHAR ; ja siirretään LCD näytölle RETURN ;********************************************************************************* ; Merkkien poisto LCD näytöltä. Eli kirjoitetaan tyhjä merkki näytölle. POIS10 CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; POIS7 CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; POIS5 CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle MOVLW A' ' ; CALL LCDPUTCHAR ; siirretään merkki näytölle RETURN ;********************************************************************************* ; Binari BCD muunnos. ; Tämä ohjelmarutiini muuttaa 32 bittisen binariluvun 10 numeron ; BCD luvuksi. ; 32 bit binari luku on rekistereissä H_BYTE, MH_BYTE, ML_BYTE ja ; L_BYTE joista H_BYTE on eniten merkitsevä ja L_BYTE vähiten ; merkitsevä luku. ; ; 10 numeron BCD luku on muunnoksen jälkeen luettavissa rekistereissä ; R0, R1, R2, R3 and R4 jossa R0 on eniten meritsevä luku. ; Yhdessä rekisterissä on aina 2 numeroa joista vasen on eniten ; merkitsevä. B4_BCD BCF STATUS,0 ; nollataan CARRY bitti MOVLW 0x20 ; W- rekisterin sisällöksi 32d MOVWF COUNT ; ja siirretään COUNT laskijaan CLRF R0 ; Tyhjennetään rekisteri R0 CLRF R1 ; Tyhjennetään rekisteri R1 CLRF R2 ; Tyhjennetään rekisteri R2 CLRF R3 ; Tyhjennetään rekisteri R3 CLRF R4 ; Tyhjennetään rekisteri R4 LOOP32 RLF L_BYTE, F ; Siirretään L_BYTE vasemmalle 1 bit RLF ML_BYTE, F ; Siirretään ML_BYTE vasemmalle 1 bit RLF MH_BYTE, F ; Siirretään MH_BYTE vasemmalle 1 bit RLF H_BYTE, F ; Siirretään H_BYTE vasemmalle 1 bit RLF R4, F ; Siirretään R4 vasemmalle 1 bit RLF R3, F ; Siirretään R3 vasemmalle 1 bit RLF R2, F ; Siirretään R2 vasemmalle 1 bit RLF R1, F ; Siirretään R1 vasemmalle 1 bit RLF R0, F ; Siirretään R0 vasemmalle 1 bit DECFSZ COUNT, F ; Vähennetään COUNT laskijasta 1 ; jos tulos on 0 ohitetaan seuraava GOTO ADJDEC ; Jatketaan paikkaan ADJDEC RETLW 0 ADJDEC MOVLW R4 ; Siirretään R4 rekisterin osoite MOVWF FSR ; sisäiseen osoittimeen FSR CALL ADJBCD ; Aliohjelma ADJBCD MOVLW R3 ; Siirretään R3 rekisterin osoite MOVWF FSR ; sisäiseen osoittimeen FSR CALL ADJBCD ; Aliohjelma ADJBCD MOVLW R2 ; Siirretään R2 rekisterin osoite MOVWF FSR ; sisäiseen osoittimeen FSR CALL ADJBCD ; Aliohjelma ADJBCD MOVLW R1 ; Siirretään R1 rekisterin osoite MOVWF FSR ; sisäiseen osoittimeen FSR CALL ADJBCD ; Aliohjelma ADJBCD MOVLW R0 ; Siirretään R0 rekisterin osoite MOVWF FSR ; sisäiseen osoittimeen FSR CALL ADJBCD ; Aliohjelma ADJBCD GOTO LOOP32 ADJBCD MOVLW 3 ; W = 3 ADDWF 0,W ; MOVWF TMP ; BTFSC TMP,3 ; Testataan jos suurempi kuin 7 MOVWF 0 ; MOVLW 30 ; ADDWF 0,W ; MOVWF TMP ; BTFSC TMP,7 ; Testataan jos suurempi kuin 7 MOVWF 0 ; Talletetaan MSD RETLW 0 ; ;********************************************************************************* ; Viiveitten muodostus ; ; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time ; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time) ; ; i.e. (@ 4MHz crystal) ; Delay_time = ((32 * 3) + 4) * 1uSec ; = 100uSec ; DELAY_value = (500uSec - 4) / 3 ; = 165.33 ; = 165 DELAY500 MOVLW D'165' ; +1 1 jakso MOVWF DELAY ; +2 1 jakso DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 jakso GOTO DELAY500_LOOP ; step 2 2 jaksoa DELAY500_END RETURN ; +3 2 jaksoa ;================================ X_DELAY500 MOVWF X_DELAY ; +1 1 jakso X_DELAY500_LOOP CALL DELAY500 ; step 1 Odotetaan 500uSec DECFSZ X_DELAY, F ; step 2 1 jakso GOTO X_DELAY500_LOOP ; step 3 2 jaksoa X_DELAY500_END RETURN ; +2 2 jaksoa ;********************************************************************************* ; Muistin käsittelyn aliohjelmat ; Muistista luku. ; Muistipaikan osoite rekisterissä EE_adress. ; Sisältö palautuu EE_data rekisteriin. MEMREAD MOVF EE_adress,W ; Osoite W rekisteriin BCF STATUS, RP0 ; Pankki 0 MOVWF EEADR ; W-rekisterin sisältö muistipaikan osoitteeksi BSF STATUS, RP0 ; Pankki 1 BSF EECON1, RD ; Asetetaan lukubitti BCF STATUS, RP0 ; Pankki 0 MOVF EEDATA, W ; Luetaan EE luku W-rekisteriin MOVWF EE_data ; ja siirretään EE_data rekisteriin RETURN ;================================================================================= ; Muistiin kirjoitus ; Muistiin siirrettävä tavu EE_data rekisterissä. ; Muistipaikan osoite rekisterissä EE_adress. ; Alussa odotetaan että edellinen kirjoitus on saatu valmiiksi. WRITEMEM BSF STATUS, RP0 ; Pankki 1 BTFSC EECON1, WR ; Odotellaan kunnes edellinen kirjoitus GOTO WRITEMEM ; on suoritettu loppuun. BCF STATUS, RP0 ; Pankki 0 MOVF EE_data, W ; EE_data rekisterin sisältö MOVWF EEDATA ; muistin sisällöksi MOVF EE_adress, W ; EE_adress rekisterin sisältö siirretään MOVWF EEADR ; muistin osoittimeksi BSF STATUS, RP0 ; Pankki 1 BCF INTCON, GIE ; Estetään keskeytykset BSF EECON1, WREN ; Sallitaan kirjoitus EEPROMiin ;------------------------- MOVLW 0x55 ; Muistiin kirjoituksen MOVWF EECON2 ; vaatima toiminne MOVLW 0xAA ; MOVWF EECON2 ; Asetetaan WR bitti BSF EECON1, WR ; kirjoituksen alussa ;------------------------- BCF EECON1, WREN ; Estetään EEPROM kirjoitus BSF INTCON, GIE ; Sallitaan keskeytykset BCF STATUS, RP0 ; Pankki 0 RETURN ;********************************************************************************* ; LCD:n aliohjelmat ; LCDINIT ; Alustetaan LCD-näyttömoduli ; Voidaan vaikuttaa näytön ominaisuuksiin ja näyttömodulin toimintaan ; ( näytön tyyppi, kursori käytössä tai pois, yms.) LCDINIT BCF LCD_CTRL,LCD_RS ; kaikki control portin bitit alas BCF LCD_CTRL,LCD_RW ; käynnistysviiveen ajaksi BCF LCD_CTRL,LCD_E MOVLW 0x01E CALL X_DELAY500 ; 30 * 0.5mS = 15mS ; 15 ms käynnistysviive. MOVLW b'00000010' MOVWF LCD_DATA CALL LCD_ENABLE MOVLW b'00101000' ; 8-bit-interface, 2-lines CALL LCDPUTCMD MOVLW b'00000000' ; Sammutetaan LCD, kursori pois, ei vilkutusta CALL LCDDMODE CALL LCDCLEAR ; Tyhjennetään näyttö MOVLW b'00000100' ; LCD päälle, kursori pois CALL LCDDMODE MOVLW b'00000010' ; automaattinen siirto LCD:lle lisättäessä tekstiä CALL LCDEMODE RETURN ;================================================================================= ; LCDPUTCHAR ; Lähetetään merkki LCD näytölle ; Merkki oltava W rekisterissä LCDPUTCHAR BTFSC LCD_DATA,RELE ; jos releen asento on "1" BSF LCD_TEMP2,RELE ; talletetaan muistiin MOVWF LCD_TEMP1 ; W -> LCD_TEMP1 rekisteriin CALL LCDBUSY ; odotetaan kunnes moduli on valmiina BCF LCD_CTRL, LCD_RW; RW linja "0" BSF LCD_CTRL, LCD_RS; RS linja "1" BSF LCD_CTRL, LCD_E ; E linja "1" SWAPF LCD_TEMP1, W ; Siirretään LCD_TEMP1 rekisterin yläosa ; W rekisteriin ANDLW b'00001111' ; W:n sisällöstä poistetaan yläosa BTFSC LCD_TEMP2,RELE ; jos releen asento oli "1" ADDLW b'00010000' ; lisätään W rekisteriin MOVWF LCD_DATA ; Siirretään merkki lähtöporttiin ja ; lähetetään LCD:lle CALL LCD_ENABLE ; pulssilla E linjalle. MOVF LCD_TEMP1, W ; merkki siirretään LCD_TEMP1 ; rekisteristä W rekisteriin ANDLW b'00001111' ; W:n sisällöstä poistetaan yläosa BTFSC LCD_TEMP2,RELE ; jos releen asento oli "1" ADDLW b'00010000' ; lisätään W rekisteriin MOVWF LCD_DATA ; Siirretään merkki lähtöporttiin ja ; lähetetään LCD:lle CALL LCD_ENABLE ; pulssilla E linjalle. BCF LCD_TEMP2,RELE ; poistetaan releen asentotieto BCF LCD_CTRL, LCD_E ; E linja "0" RETURN ;================================================================================= ; LCDPUTCMD ; Lähetetään käsky LCD modulille ; Merkki oltava W rekisterissä LCDPUTCMD BTFSC LCD_DATA,RELE ; jos releen asento on "1" BSF LCD_TEMP2,RELE ; talletetaan muistiin MOVWF LCD_TEMP1 ; Käsky siirretään w rekisteristä ; LCD_TEMP1 rekisteriin CALL LCDBUSY ; odotetaan kunnes moduli on valmiina BCF LCD_CTRL, LCD_RW; RW linja "0" BCF LCD_CTRL, LCD_RS; RS linja "0" BSF LCD_CTRL, LCD_E ; E linja "1" SWAPF LCD_TEMP1, W ; Siirretään LCD_TEMP1 rekisterin yläosa ; W rekisteriin ANDLW b'00001111' ; W:n sisällöstä poistetaan yläosa BTFSC LCD_TEMP2,RELE ; jos releen asento oli "1" ADDLW b'00010000' ; lisätään W rekisteriin MOVWF LCD_DATA ; Lähetetään LCD:lle BCF LCD_CTRL, LCD_E ; E linja "0" MOVF LCD_TEMP1, W ; merkki siirretään LCD_TEMP1 ; rekisteristä W rekisteriin ANDLW b'00001111' ; W:n sisällöstä poistetaan yläosa BTFSC LCD_TEMP2,RELE ; jos releen asento oli "1" ADDLW b'00010000' ; lisätään W rekisteriin MOVWF LCD_DATA ; Siirretään merkki lähtöporttiin ja ; lähetetään LCD:lle CALL LCD_ENABLE ; pulssilla E linjalle. BCF LCD_TEMP2,RELE ; poistetaan releen asentotieto RETURN ;================================================================================= ; LCDDMODE ; Asetetaan LCD modulin asetuksia ; Seuraavat toiminnat muutettavissa W rekisterin b0, b1 ja b2 biteillä ; b0 : 0 = vilkkuva kursori pois käytöstä 1 = vilkkuva kursori käytössä ; b1 : 0 = kursori pois käytöstä 1 = kursori käytössä ; b2 : 0 = tekstiä ei näytetä 1 = näytetään teksti ; (näytön data talletettu DDRAM) ; b3-7 : ei merkitystä LCDDMODE ANDLW 0x007 ; Leikkaa ylemmät bitit IORLW 0x008 ; Funktio asetus CALL LCDPUTCMD ; siirretään LCD moduliin RETURN ;================================================================================= ; LCDBUSY ; Odottaa kunnes LCD modulin BUSY flag on 0 LCDBUSY BSF STATUS,RP0 ; valitaan bank 1 MOVLW b'00001111' ; asetetaan RA3-0 input MOVWF LCD_DATA_TRIS ; asetetaan PORTA sisääntuloksi BCF STATUS, RP0 ; valitaan bank 0 BCF LCD_CTRL, LCD_RS; asetetaan control RS "0" BSF LCD_CTRL, LCD_RW; asetetaan control RW "1" BSF LCD_CTRL, LCD_E ; LCD E-linja "1" MOVF LCD_DATA, W ; luetaan busy flag + DDram osoite BCF LCD_CTRL, LCD_E ; LCD E-linja "0" NOP CALL LCD_ENABLE ; Pulssi E-linjaan ANDLW b'00001000' ; Tarkistetaan Busy flag, "1" = Busy BTFSS STATUS, Z ; (jos Z=1 lopettaa silmukan) GOTO LCDBUSY ; hyppy LCDBUSY LCDNOTBUSY BCF LCD_CTRL, LCD_RW; asetetaan control RW "0" BSF STATUS, RP0 ; valitaan bank 1 MOVLW b'00000000' MOVWF LCD_DATA_TRIS ; asetetaan PORTB ulostuloksi BCF STATUS, RP0 ; valitaan bank 0 RETURN ;================================================================================= ; LCD_ENABLE ; Pulssi LCD E linjalle LCD_ENABLE BSF LCD_CTRL, LCD_E ; LCD E-linja "1" NOP BCF LCD_CTRL, LCD_E ; LCD E-linja "0" RETURN ;================================================================================= ; LCDCLEAR ; Tyhjentää näytön ja siirtää kursorin ensimmäisen rivin alkuun. LCDCLEAR MOVLW 0x001 ; W rekisteriin 01 CALL LCDPUTCMD ; siirretään LCD moduliin RETURN ;================================================================================= ; LCDEMODE ; Asetetaan modulin toiminta asetuksia ; Seuraavat toiminnat muutettavissa W rekisterin b0 ja b1 biteillä ; b0 : 0 = ei näytön siirtoa 1 = näytön siirto ; b1 : 0 = automaattinen vähennys 1 = automaattinen lisäys ; b2-7 : ei merkitystä LCDEMODE ANDLW 0x003 ; Leikkaa ylemmät bitit IORLW 0x004 ; Funktio asetus CALL LCDPUTCMD ; siirretään LCD moduliin RETURN ;================================================================================= ; LCDSDDA ; Asetetaan näyttö RAM osoite. DDRAM data on luettavissa/kirjoitettavissa ; tämän asetuksen jälkeen ; asetetaan DDRAM osoite W rekisteriin ; b0-6 : käytettävä DDRAM osoite ; b7 : ei merkitystä LCDSDDA IORLW 0x80 ; Funktio asetus CALL LCDPUTCMD ; siirretään LCD moduliin RETURN ;********************************************************************************* ; Laskenta aliohjelmat ; ; YHTEENLASKU : B(32 bits) + A(32 bits) -> B(32 bits) ; (a) Ladataan 1 luku rekistereihin TMP1 & TMP2 & TMP3 & TMP4 ( 32 bits ) ; (b) Ladataan 2 luku rekistereihin TMP5 & TMP6 & TMP7 & TMP8 ( 32 bits ) ; (c) Kutsutaan aliohjelma CALL D_ADD32 ; (d) Tulos rekistereissä TMP5 & TMP6 & TMP7 & TMP8 ( 32 bits ) D_ADD32 BCF STATUS,0 ; STATUS bit0 = 0 MOVF TMP4,W ; TMP4 -> W ADDWF TMP8,F ; TMP8 = TMP8 + W BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) GOTO PLUS1 ; On Lisätään seuravaan numeroon 1 PLUS1P BCF STATUS,0 ; STATUS bit0 = 0 MOVF TMP3,W ; TMP3 -> W ADDWF TMP7,F ; TMP7 = TMP7 + W BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) GOTO PLUS2 ; On Lisätään seuravaan numeroon 1 PLUS2P BCF STATUS,0 ; STATUS bit0 = 0 MOVF TMP2,W ; TMP2 -> W ADDWF TMP6,F ; TMP6 = TMP6 + W BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) ; On Lisätään seuravaan numeroon 1 INCF TMP5,F ; TMP5 = TMP5 + 1 ; Ei MOVF TMP1,W ; TMP1 -> W ADDWF TMP5, F ; TMP5 = TMP5 + W GOTO PLUSLOP ;-------------------------------- PLUS1 BCF STATUS,0 ; STATUS bit0 = 0 MOVLW 0x01 ADDWF TMP7,F ; TMP7 = TMP7 + 1 BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) GOTO PLUS1A ; On Lisätään seuravaan numeroon 1 GOTO PLUS1P ; Ei Paluu PLUS1A BCF STATUS,0 ; STATUS bit0 = 0 MOVLW 0x01 ADDWF TMP6,F ; TMP6 = TMP6 + 1 BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) GOTO PLUS1B ; On Lisätään seuravaan numeroon 1 GOTO PLUS1P ; Ei Paluu PLUS1B MOVLW 0x01 ADDWF TMP5,F ; TMP5 = TMP5 + 1 GOTO PLUS1P ; Paluu PLUSLOP RETURN ; Paluu kutsuneseen ohjelmaan ;-------------------------------- PLUS2 BCF STATUS,0 ; STATUS bit0 = 0 MOVLW 0x01 ADDWF TMP6,F ; TMP6 = TMP6 + 1 BTFSC STATUS,C ; Onko STATUS bit0 = 1 (carry bit) GOTO PLUS2A ; On Lisätään seuravaan numeroon 1 GOTO PLUS2P ; Ei Paluu PLUS2A MOVLW 0x01 ADDWF TMP5,F ; TMP5 = TMP5 + 1 GOTO PLUS2P ; Paluu ;********************************************************************************* ; KERTOLASKU ; Kahden 8 bittisen hexa luvun kertominen ( 16 X 16 -> 32 ) ; 16bit kertoja A ( TMP3,TMP4 ) ja 16bit kerrottava B ( TMP5, TMP6 ) ; ( B * A -> B,C ) 32 bittinen tulos rekistereissä B & C. ; Jossa B rekisteri ( TMP5,TMP6 ) on eniten merkitsevä ja ; C rekisteri ( TMP7,TMP8 ) on vähiten merkitsevä luku. ; ; Tulos rekistereissä B=(16 MSB)=(TMP5,TMP6) ja C=(16 LSB)=(TMP7,TMP8) KERTO_XXXX ; Kierroslaskija = 16 MOVLW .16 ; W=0Fh MOVWF TMP ; W -> TMP ; Siirretään B rekisteristä ; D rekisteriin MOVF TMP5,W ; TMP5 -> W MOVWF TMP1 ; W -> TMP1 MOVF TMP6,W ; TMP6 -> W MOVWF TMP2 ; W -> TMP2 CLRF TMP5 ; TMP5 = 0 CLRF TMP6 ; TMP6 = 0 ; Suoritetaan KERTO16 aliohjelma 16 kertaa CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 CALL KERTO16 RETURN ; palataan kutsuneeseen ohjelmaan ;********************************************************************************* KERTO16 RRF TMP1, F ; Siirretään TMP1:n sisältöä oikealle RRF TMP2, F ; Siirretään TMP2:n sisältöä oikealle BTFSS STATUS,C ; Onko STATUS rekisterin bit0, 1. GOTO NO_ADD ; Ei, hyppy paikkaan NO_ADD ; On, lisätään ( B + A -> B ) MOVF TMP4,W ; TMP4 -> W ADDWF TMP6, F ; TMP6 = TMP6 + W BTFSC STATUS,C ; Onko STATUS rekisterin bit0, 0. INCF TMP5, F ; On, TMP5 = TMP5 + 1 ; Ei MOVF TMP3,W ; TMP3 -> W ADDWF TMP5, F ; TMP5 = TMP5 + W NO_ADD RRF TMP5, F ; Siirretään TMP5:n sisältöä oikealle RRF TMP6, F ; Siirretään TMP6:n sisältöä oikealle RRF TMP7, F ; Siirretään TMP7:n sisältöä oikealle RRF TMP8, F ; Siirretään TMP8:n sisältöä oikealle RETURN ; Palataan kutsuneeseen ohjelmaan ;********************************************************************************* ; JAKOLASKU ( 16bit / 16bit -> 16bit ) ; ; ( TMP7,TMP8 / TMP5,TMP6 -> TMP7,TMP8 ja jakojäännös TMP3,TMP4 ) ; 16bit output tulos rekisterissä TMP7,TMP8 ; ja 16bitjakojäännös rekisterissä TMP3,TMP4. JAKO_XXXX ; D_DIVF MOVLW .16 ; Muunnoslaskija 10h MOVWF TMP MOVF TMP7,W ; Siirretään TMP7 -> TMP1 MOVWF TMP1 MOVF TMP8,W ; Siirretään TMP8 -> TMP2 MOVWF TMP2 CLRF TMP7 ; Tyhjennetään TMP7 CLRF TMP8 ; Tyhjennetään TMP8 CLRF TMP3 ; Tyhjennetään TMP3 CLRF TMP4 ; Tyhjennetään TMP4 ; suoritetaan BITJAK aliohjelma 16 kertaa CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK CALL BITJAK RETURN ; Paluu pääohjelmaan ;--------------------------------------------------------------------------------- ; Jakolaskun aliohjelma BITJAK BCF STATUS,C ; STATUS rekisterin bit0 = 0 RLF TMP2, F ; Siirretään 1 bit vasemmalle TMP2 RLF TMP1, F ; Siirretään 1 bit vasemmalle TMP1 RLF TMP4, F ; Siirretään 1 bit vasemmalle TMP4 RLF TMP3, F ; Siirretään 1 bit vasemmalle TMP3 MOVF TMP5,W ; TMP5 -> W SUBWF TMP3,W ; W = TMP3 - W BTFSS STATUS,Z ; Onko STATUS rekisterin bit2 = 1 ; On GOTO NOCHK ; Hyppy NOCHK ; Ei MOVF TMP6,W ; TMP6 -> W SUBWF TMP4,W ; W = TMP4 - W ; Jos MSB on yhtäsuuri kuin LSB ; carry asetetaan jos TMP6 > TMP4 NOCHK BTFSS STATUS,C ; Onko STATUS rekisterin bit0 = 1 ; Ei GOTO NOGO ; Hyppy NOGO ; On MOVF TMP6,W ; W = TMP6 SUBWF TMP4, F ; TMP4 = TMP4 - W BTFSS STATUS,C ; Onko STATUS rekisterin bit0 = 1 ; Ei DECF TMP3, F ; TMP3 = TMP3 - 1 ; On MOVF TMP5,W ; W = TMP5 SUBWF TMP3, F ; TMP3 = TMP3 - W BSF STATUS,C ; STATUS rekisterin bit0 = 0 NOGO RLF TMP8, F ; Siirretään 1 bit vasemmalle TMP8 RLF TMP7, F ; Siirretään 1 bit vasemmalle TMP7 RETURN ;********************************************************************************* org 2110 ; EEPROM muistin alkuasetukset de h'20',h'00',h'27',h'40' ; Halkaisija 32 ja ympärys 10048 org 2120 de h'00',h'00',h'00',h'00' ; Aloitusmatka 00 00 00 00 ; Pilkku ohjelmassa (00000,000 km) ;********************************************************************************* END ; ohjelmakoodin loppu