list p=PIC16F84A #include ; ; (c) 2003 Sugihara Toshio. ; All rights reserved. ; ; PIC16F84A ; Clock=32768Hz 8192 orders/s ; WDT=off, StartTimer=on ; Protect=off, Oscllator=LP outbuf equ H'0c' timea equ H'0d' ;wait loop value for general pt equ H'0e' ;Current Base address st equ H'0f' ;current status cp equ H'10' ;cursor position hexbuf equ H'11' ;Hex output buffer hexbuf2 equ H'12' btn equ H'13' ;Button buffer btnb equ H'14' ;Button backup btnt equ H'15' ;Button timer readh equ H'16' ;Read data h readl equ H'17' ;Read data l readp equ H'18' ;Read address(H'00'-H'3f') rloop equ H'19' ;Loop value in Read vadr equ H'1a' ;address to verify or read or write writeh equ H'1b' ;Write data h writel equ H'1c' ;Write data l writep equ H'1d' ;Write address(H'00'-H'3f') wloop equ H'1e' ;Loop value in Write ; Memory buffers are from H'20' to H'27' ;--Program start ; org H'00' Boot goto Start org H'04' Warikomi goto Start Start movlw B'00111000' ;Select Bank 1 movwf STATUS Startloop clrf INTCON ;Stop Interrupt btfsc INTCON,7 goto Startloop movlw B'10000100' ;B port is not pulled up movwf OPTION_REG movlw B'00010000' ;A4 is only input movwf TRISA movlw B'00000000' ;B port is all output movwf TRISB bcf STATUS,5 ;Select Bank 0 movlw B'11111110' ;DI is only 0 movwf PORTA clrf PORTB ;B port is all 0 ;Init variable clrf pt ;Pointer is H'00' clrf st ;normal status movlw H'81' movwf cp ;Cursor is first line 2nd char clrf btn ;clear button buffer clrf btnb ;clear button backup clrf btnt ;clear button timer goto Pb ;treat as B button pressed. ; ;Main loop ; Mainloop ;Re-setup I/O PORTS for safety bsf STATUS,5 ;Select bank 1 movlw B'00010000' ;A4 is only input. movwf TRISA clrf TRISB ;B is all output. bcf STATUS,5 ;Select Bank 0 movlw B'11111110' ;DI is only 0 movwf PORTA clrf PORTB ;B port is all 0 ;Show display call Initlcd ;Display setup call Showall ;Wait for button to be pressed. Buttonwait ;76543210 = NBALDRUN ;backup previous data movf btn,W movwf btnb clrf btn ;U:001 bsf PORTA,1 bcf PORTA,2 bcf PORTA,3 btfss PORTA,4 bsf btn,1 ;D:011 bsf PORTA,2 btfss PORTA,4 bsf btn,3 ;R:010 bcf PORTA,1 btfss PORTA,4 bsf btn,2 ;B:110 bsf PORTA,3 btfss PORTA,4 bsf btn,6 ;L:100 bcf PORTA,2 btfss PORTA,4 bsf btn,4 ;A:101 bsf PORTA,1 btfss PORTA,4 bsf btn,5 ;wait for up to 250ms ;if data is equal to the previous. movf btn,W btfss STATUS,2 ;Any button pressed? goto Buttonp1 ;Yes. ;No. Try again. ;No button pressed clrf btnt goto Buttonwait Buttonp1 ;Button is pressed subwf btnb,W ;W = btnb - btn btfsc STATUS,2 ;btnb == btn ? goto Buttonp2 ;Yes. ;No. status changed. clrf btnt goto Buttonend Buttonp2 ;Same button pressed. incf btnt,F movf btnt,W sublw D'54' btfsc STATUS,0 ;loop >= 55 times ? goto Buttonwait ;No. decf btnt,F ;Yes. Buttonend ;Up key :1 Cup btfss btn,1 goto Cright Pup ;Up pressed btfss cp,7 ;2nd line? goto Uplower ;Yes. ;No. Change address btfsc st,0 ;Something changed? goto Mainloop ;Yes. go back to mainloop. ;No. movlw D'4' btfss cp,0 ;cp is 129? movlw D'16' ;No. it is 128. ;Yes. it is 129. addwf pt,F movf pt,W sublw H'3c' btfss STATUS,0 ;pt > H'3c' ? clrf pt ;Yes. ;No. goto Pb ;Then go to read operation ;Up key in 2nd line Uplower ;Set memory address rrf cp,W andlw H'0f' addlw H'20' movwf FSR ;Set increment value movlw D'1' btfss cp,0 ;0:+=16 1:+=1 movlw D'16' addwf INDF,F btfsc st,0 ;"*" is displayed ? goto Updownfast ;Yes. fast draw mode. ;No. movlw D'1' ;Change status to "*" movwf st goto Mainloop Updownfast call Showallmem goto Buttonwait Cright btfss btn,2 goto Cdown Pright incf cp,F movf cp,W sublw D'130' btfss STATUS,2 ;cp==130? goto Prightp1 ;No. clrf cp ;Yes. cp becomes 0. goto Plrafter Prightp1 movf cp,W sublw D'16' btfss STATUS,2 ;cp==16? goto Plrafter ;No. movlw D'128' ;Yes. cp becomes 128. movwf cp Plrafter ;Show cursor only call Showcp movlw D'60' ;Wait for 30ms call waitw goto Buttonwait Cdown btfss btn,3 goto Cleft Pdown btfss cp,7 ;2nd line? goto Downlower ;Yes. ;No. btfsc st,0 ;Is something changed? goto Mainloop ;Yes, go back to mainloop. ;No. change the address. movlw D'4' btfss cp,0 ;cp is 129? movlw D'16' ;No. it is 128. ;Yes. it is 129. subwf pt,F btfsc STATUS,0 ;pt undef 0? goto Pb ;No. go to read operation. ;Yes. movlw H'3c' ;pt = H'3c' movwf pt goto Pb ;Then go to read operation ;Down key in 2nd line Downlower ;Set memory address rrf cp,W andlw H'0f' addlw H'20' movwf FSR ;Set decrement value movlw D'1' btfss cp,0 ;0:-=16 1:-=1 movlw D'16' subwf INDF,F btfsc st,0 ;"*" is displayed ? goto Updownfast ;Yes. fast draw mode. ; No. movlw D'1' ; Change status to "*". movwf st goto Mainloop Cleft btfss btn,4 goto Ca Pleft decf cp,F movlw D'127' subwf cp,W btfss STATUS,2 ;pt is 127? goto Pleftp1 ;No. movlw D'15' ;Yes. next value is 15. movwf cp goto Plrafter Pleftp1 incf cp,W btfss STATUS,2 ;pt is 255? goto Plrafter ;No. movlw D'129' ;Yes. next value is 129 movwf cp goto Plrafter Ca btfss btn,5 goto Cb Pa ;Write to E3ROM from RAM movlw H'20' ;Start RAM address movwf FSR movf pt,W ;Start E3ROM address movwf vadr ;Enable writing call E3Wen Pap1 movf INDF,W movwf writeh incf FSR,F movf INDF,W movwf writel incf FSR,F movf vadr,W call E3Write incf vadr,F movf FSR,W sublw H'28' btfss STATUS,2 ;8bytes (4words) wrote? goto Pap1 ;No. send next word. ;Yes. ;Disable writing call E3Wds ;Verify data movlw D'4' movwf st ;set "WROK" call E3Verify andlw H'ff' btfsc STATUS,2 ;Verify OK? goto Mainloop ;Yes. ;No. movlw D'16' movwf st ;set "WERR" goto Mainloop Cb btfss btn,6 goto Mainloopend Pb ;Read from E3ROM to RAM movlw H'20' ;Start RAM address movwf FSR movf pt,W ;Start E3ROM address movwf vadr Pbp1 ;Read from E3ROM movf vadr,W call E3Read ;Set values into RAM movf readh,W movwf INDF incf FSR,F movf readl,W movwf INDF incf FSR,F incf vadr,F ;End check movf FSR,W sublw H'28' btfss STATUS,2 ;8 bytes (4 words) done? goto Pbp1 ;No. read next word. ;Yes. ;Verify Read data movlw D'2' ;Set "READ" status movwf st call E3Verify andlw H'ff' btfsc STATUS,2 ;Verify OK(0)? goto Mainloop ;Yes. return with status 2 movlw D'8' ;No. return with status 8 movwf st goto Mainloop Mainloopend goto Mainloop ;Verify E3ROM ;pt and memory from H'20' to H'27' are checked ;if they are equal to E3ROM. ;If OK, W register is 0 ;Of NG, W register is not 0 E3Verify movlw H'20' movwf FSR ;Initial RAM address movf pt,W movwf vadr ;Initial E3ROM address E3Vp1 ;Read from E3rom movf vadr,W call E3Read ;Check higher byte movf readh,W subwf INDF,W btfss STATUS,2 retlw H'ff' ;Values are not equal. incf FSR,F ;Check lower byte movf readl,W subwf INDF,W btfss STATUS,2 retlw H'ff' ;Values are not equal. incf FSR,F incf vadr,F ;End check movf FSR,W sublw H'28' btfss STATUS,2 ;8 bytes (4 words) done? goto E3Vp1 ;No. Try next ;Yes. All memory is OK. retlw H'00' ;Write enabling to E3ROM E3Wen ;I/O port init clrf PORTB movlw B'00001110' movwf PORTA ;Send WEN instruction bsf PORTB,7 ;CS UP ;Send 1 bsf PORTA,0 bsf PORTB,6 bcf PORTB,6 ;Send 0 bcf PORTA,0 bsf PORTB,6 ;0 bcf PORTB,6 ;Send 0 bsf PORTB,6 ;0 bcf PORTB,6 ;Send 1 bsf PORTA,0 bsf PORTB,6 ;1 bcf PORTB,6 ;Send 1 bsf PORTB,6 ;1 bcf PORTB,6 ;Send 4 cycle with 1 bsf PORTB,6 bcf PORTB,6 bsf PORTB,6 bcf PORTB,6 bsf PORTB,6 bcf PORTB,6 bsf PORTB,6 bcf PORTB,6 ;Operation done bcf PORTA,0 bcf PORTB,7 ;CS DOWN return ;Write disabling to E3ROM E3Wds ;I/O port init clrf PORTB movlw B'00001110' movwf PORTA ;Send WEN instruction bsf PORTB,7 ;CS UP ;Send 1 bsf PORTA,0 bsf PORTB,6 bcf PORTB,6 ;Send 0 bcf PORTA,0 bsf PORTB,6 ;0 bcf PORTB,6 ;Send 0 bsf PORTB,6 ;0 bcf PORTB,6 ;Send 0 bsf PORTB,6 ;0 bcf PORTB,6 ;Send 0 bsf PORTB,6 ;0 bcf PORTB,6 ;send 4 cycle with 0 bsf PORTB,6 ;0 bcf PORTB,6 bsf PORTB,6 ;0 bcf PORTB,6 bsf PORTB,6 ;0 bcf PORTB,6 bsf PORTB,6 ;0 bcf PORTB,6 ;Operation done bcf PORTB,7 ;CS DOWN return ;Writeing to E3ROM ;address to write is in W register ;writeh and writel are values to be written ;writeh and writel are broken by this routine. E3Write ;Save address to write movwf writep ;I/O port init clrf PORTB ;B6=SK B7=CS movlw B'00001110' movwf PORTA ;A4=DO A0=DI ;Write operation start bsf PORTB,7 ;CS UP ;Send 1 bsf PORTA,0 ;1 bsf PORTB,6 bcf PORTB,6 ;Send 0 bcf PORTA,0 ;0 bsf PORTB,6 bcf PORTB,6 ;Send 1 bsf PORTA,0 ;1 bsf PORTB,6 bcf PORTB,6 ;Send write address movlw D'6' movwf wloop E3Wp1 bcf PORTA,0 btfsc writep,5 ;DI=writep,5 bsf PORTA,0 rlf writep,F ;left shift for next bit bsf PORTB,6 bcf PORTB,6 decf wloop,F btfss STATUS,2 ;6 times done? goto E3Wp1 ;No. send next bit ;Yes. ;Send 1st 8 bits data movlw D'8' movwf wloop E3Wp2 bcf PORTA,0 btfsc writeh,7 ;DI=writeh,7 bsf PORTA,0 rlf writeh,F ;left shift bsf PORTB,6 bcf PORTB,6 decf wloop,F btfss STATUS,2 ;8 times done? goto E3Wp2 ;No. send next bit ;Yes. ;Send 2nd 8 bits data movlw D'8' movwf wloop E3Wp3 bcf PORTA,0 btfsc writel,7 ;DI=writel,7 bsf PORTA,0 rlf writel,F ;left shift bsf PORTB,6 bcf PORTB,6 decf wloop,F btfss STATUS,2 ;8 times done? goto E3Wp3 ;No, send next bit. ;Yes. ;Wait for write time bcf PORTA,0 ;DI DOWN bcf PORTB,7 ;CS DOWN bsf PORTB,7 ;CS UP movlw D'80' ;Set waiting limit movwf wloop E3Wp4 btfsc PORTA,4 ;Writing is Busy ? goto E3Wp5 ;No. It's done. ;Yes. decf wloop,F btfss STATUS,2 ;80 times (58.6ms) done? goto E3Wp4 ;No. try again. ;Yes. E3Wp5 bcf PORTB,7 ;CS DOWN return ;Done writeing ;Reading E3ROM ;address to read is in W register ;readh and readl are values to be read E3Read ;Save address to read movwf readp ;I/O port init clrf PORTB ;B6=SK B7=CS movlw B'00001110' movwf PORTA ;A4=DO A0=DI ;Read operation start bsf PORTB,7 ;CS UP bsf PORTA,0 bsf PORTB,6 ; 1 bcf PORTB,6 bsf PORTB,6 ; 1 bcf PORTB,6 bcf PORTA,0 bsf PORTB,6 ; 0 bcf PORTB,6 ;Send address to read movlw D'6' movwf rloop E3Rp1 bcf PORTA,0 btfsc readp,5 ;DI = readp,5 bsf PORTA,0 rlf readp,F ;left shift bsf PORTB,6 ;address send bcf PORTB,6 decf rloop,F btfss STATUS,2 ;6 times done? goto E3Rp1 ;No. bcf PORTA,0 ;Yes. ;Read 1st 8 bits movlw D'8' movwf rloop E3Rp2 bsf PORTB,6 ;Send SK purse bcf PORTB,6 rlf readh,F ;left shift bcf readh,0 btfsc PORTA,4 ;readh,0 = DO bsf readh,0 decf rloop,F btfss STATUS,2 ;8 times done? goto E3Rp2 ;No. ;Yes. ;Read 2nd 8bits movlw D'8' movwf rloop E3Rp3 bsf PORTB,6 ;Send SK purse bcf PORTB,6 rlf readl,F ;left shift bcf readl,0 btfsc PORTA,4 ;readl,0 = DO bsf readl,0 decf rloop,F btfss STATUS,2 ;8 times done? goto E3Rp3 ;No. ;Yes. bcf PORTB,7 ;Turn off CS return ;Show display all Showall ;Hide the cursor call Hidecsr ;cursor move to line1 movlw D'128' call Putrs0 movf pt,W call Puthex ;show message movf st,W btfss STATUS,2 ;st==0? goto Showallp0 ;No. ;Yes. movlw A' ' ;clear status display call Putrs1 movlw A' ' call Putrs1 movlw A' ' call Putrs1 movlw A' ' call Putrs1 goto Showallmem Showallp0 btfss st,0 goto Showallp1 movlw A'*' ;bit0 shows "*" call Putrs1 movlw A' ' call Putrs1 movlw A' ' call Putrs1 movlw A' ' call Putrs1 goto Showallmem Showallp1 btfss st,1 goto Showallp2 movlw A'R' ;bit1 shows "REOK" call Putrs1 movlw A'E' call Putrs1 movlw A'O' call Putrs1 movlw A'K' call Putrs1 goto Showallmem Showallp2 btfss st,2 goto Showallp3 movlw A'W' ;bit2 shows "WROK" call Putrs1 movlw A'R' call Putrs1 movlw A'O' call Putrs1 movlw A'K' call Putrs1 goto Showallmem Showallp3 btfss st,3 goto Showallp4 movlw A'R' ;bit3 shows "RERR" call Putrs1 movlw A'E' call Putrs1 movlw A'R' call Putrs1 movlw A'R' call Putrs1 goto Showallmem Showallp4 btfss st,4 goto Showallmem movlw A'W' ;bit4 shows "WERR" call Putrs1 movlw A'E' call Putrs1 movlw A'R' call Putrs1 movlw A'R' call Putrs1 Showallmem ;Hide cursor call Hidecsr ;Show 4 words movlw D'192' ;Cursor is 2nd line call Putrs0 movlw H'20' movwf FSR Shownextbyte movf INDF,W call Puthex incf FSR,F movf FSR,W sublw H'28' btfss STATUS,2 goto Shownextbyte Showcp ;Move and show cursor ;* >= 128 is line1 ;* < 128 is line2 btfss cp,7 ;cursor is 1st line? goto Show2ndline ;No. ;Yes. movf cp,W call Showcsr return Show2ndline movf cp,W iorlw B'11000000' call Showcsr return ;put number as HEX format ;Input is W register Puthex movwf hexbuf swapf hexbuf,W andlw H'0f' addlw A'0' ;Higher 4 bits as ASCII char movwf hexbuf2 sublw A'9' btfsc STATUS,0 goto Puthexp1 ;value <= '9' ;value > '9' movlw D'39' addwf hexbuf2,F Puthexp1 movf hexbuf2,W call Putrs1 movf hexbuf,W andlw H'0f' addlw A'0' movwf hexbuf2 sublw A'9' btfsc STATUS,0 ;value > A'9'? goto Puthexp2 ;No. movlw D'39' ;Yes. So it must be from a to f. addwf hexbuf2,F Puthexp2 movf hexbuf2,W call Putrs1 return ;LCD start up Initlcd movlw D'205' call waitw ;wait for 100ms movlw B'00000011' call puthalf movlw D'10' call waitw ;wait for 4.5ms movlw B'00110011' call Putrs0 movlw B'00000010' call puthalf movlw B'00101000' call Putrs0 ;8bit 2lines 5x7dot movlw B'00001000' call Putrs0 movlw B'00000001' call Putrs0 movlw D'3' call waitw ;wait for 2ms movlw B'00000110' ;incerment=yes, shift=no call Putrs0 movlw B'00001100' ;cursor=off display=on call Putrs0 clrf PORTB ;power save return ;Send a byte to LCD with RS=0 ;Value to write is in W register ;Used for cursor move Putrs0 movwf outbuf movlw B'00000000' ;E=0,RS=0 goto put4bit ;Send a byte to LCD with RS=1 ;Used to send a character Putrs1 movwf outbuf movlw B'00010000' ;E=0,RS=1 ;Send higher 4 bits put4bit movwf PORTB ;set initual value swapf outbuf,W andlw H'0f' iorwf PORTB,F;set higher 4 bits bsf PORTB,5 ;E=1 bcf PORTB,5 ;E=0 movlw B'00010000' andwf PORTB,F ;clear except RS signal ;Send lower 4 bits putlowbits movf outbuf,W andlw H'0f' iorwf PORTB,F ;set lower 4 bits bsf PORTB,5 ;E=1 bcf PORTB,5 ;E=0 return ;Send only lower 4 bits with RS=0 puthalf movwf outbuf movlw B'00000000' ;E=0,RS=0 movwf PORTB goto putlowbits ;wait for a while ;value is in W address ;w=3: 2ms 30: 15ms 205: 100ms waitw movwf timea waitwloop decf timea,F btfss STATUS,2 goto waitwloop return ;Show the cursor. ;Cursor moves to value of W register. ; D'128' = Start of first line ; D'192' = Start of second line Showcsr call Putrs0 movlw B'00001111' ;Cursor show command call Putrs0 clrf PORTB ;Power save return Hidecsr movlw B'00001100' ;Cursor and blink off call Putrs0 return end