; ram_show.asm ; ; Take RAM contents from another PIC and display it list P = 18F2520 include "P18F2520.inc" errorlevel -305, -302, -306 ;MPLAB error suppression ;================================================= ConfigBase equ 0x300000 ; base address of config registers CONFIG OSC=HSPLL CONFIG BOREN=OFF, PWRT=ON CONFIG WDT=OFF CONFIG CCP2MX=PORTC CONFIG PBADEN = OFF CONFIG STVREN=ON, LVP=OFF, DEBUG=OFF CONFIG CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF CONFIG CPB=OFF, CPD=OFF CONFIG WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF CONFIG WRTC=OFF, WRTB=OFF,WRTD=OFF CONFIG EBTR0=OFF, EBTR1=OFF, EBTR2=OFF, EBTR3=OFF CONFIG EBTRB=OFF wr_space macro ;write space to LCD movlw 0x20 call write_d endm clrscrn macro ;clear LCD movlw 0x01 call write_c endm mov macro litval,file ;= movlw then movwf movlw litval movwf file endm movfw macro litval movf litval,w endm lcd_pos macro litval ;set display position movlw litval-1 ;eg lcd_pos ln2+.06 call address ; disp "A" endm disp macro litval ;display character movlw litval call write_d endm dispw macro ;display WREG call write_d endm sec1 macro ;1 second delay call one_sec endm usec macro ;1us delay movff temp,temp movff temp,temp movff temp,temp movff temp,temp movff temp,temp endm #define up porta,0 ;up 8 RAM locations #define down porta,1 ;down 8 RAM locations #define bbclk portc,0 #define bbdata portc,1 #define marker portc,2 ;test output #define accept portc,3 ;accept data if low ;LCD pins 0V V+ VO RS R/W En DB0-DB7 #define rs portc,4 ;LCD #define rw portc,5 ;LCD #define en portc,6 ;LCD ;PortB 0-7 - LCD data #define busy portb,7 ;LCD Busy flag #define dc status,1 cblock 0x0000 dg1 dg2 dg3 dg4 dg5 d100 d010 d011 kzero lo hi cnt1 cnt2 temp temp1 char_lo char_hi endc ln1 = 0x00 ;LCD line addresses ln2 = 0x40 ;================================================ org 0x00000 ;start address goto init org 0x00020 init clrf lata clrf latb clrf latc bcf intcon,gie call clr_ram ;zero all RAM mov b'00000011',trisa ; 1 pushbutton - down 4 chars ; 1 pushbutton - up 4 chars mov b'00000000',trisb ;LCD data mov b'00001011',trisc ; 1 pushbutton - accept ; 0 marker (test) ; 1 bbdata in ; 1 bbclk in mov 0x0f,adcon1 ;PortA as I/O mov 0x07,cmcon ;comparators off sms_t call ms100 ;LCD power up delay call ms100 call lcd_init call ms100 clrscrn disp "*" ;LCD good ;================================================ swaitl btfsc accept ;accept data if goes low bra swaitl swaith btfsc accept bra swaith ready clrscrn ;ready for bbclk disp "R" mov 0xd8,temp ;number of bytes to store ;which is 0x20 to 0xf8 of eg 16F88 lfsr fsr0,0x120 ;storage address in 2520 ; Store in RAM 0x0120 onwards. That's if sending PIC (source) has ; RAM starting at 0x20. Display then reflects source's addresses ; Otherwise use byte count and storage address to suit reset_c mov 0x07,cnt1 ;bit counter clrf temp1 chwait btfss bbclk ;wait for bbclk to go high bra chwait nop nop nop nop clwait btfsc bbclk ;data valid when clk goes low bra clwait nop nop nop nop bsf temp1,0 ;data buffer btfss bbdata bcf temp1,0 dcfsnz cnt1 ;bit counter bra store rlncf temp1 ;buffer bra chwait ;get next bit store rlncf temp1 ;final shift movff temp1,postinc0 ;copy buffer to RAM decfsz temp ;byte counter bra reset_c ;1234567890123456 ;xx xx xx xx xx lfsr fsr0,0x120 ;reset fsr to start of array ;display address + four RAM byes on line1 new_disp clrscrn movfw fsr0l ;address call conv2h movfw postinc0 ;4 bytes call conv2h movfw postinc0 call conv2h movfw postinc0 call conv2h movfw postinc0 call conv2h ;display address + four RAM byes on line2 call line2 movfw fsr0l ;address call conv2h movfw postinc0 ;4 bytes call conv2h movfw postinc0 call conv2h movfw postinc0 call conv2h movfw postinc0 call conv2h det_sw btfss up ;look for any button bra add_up btfss down bra add_dn btfss accept bra ready ;reset for new data input bra det_sw add_dn movlw 0xf0 ;show previous 8 addwf fsr0l dn_rel btfss down bra dn_rel call ms100 call ms100 bra new_disp add_up btfss up ;show next 8 bra add_up call ms100 call ms100 bra new_disp ;================================================ ; convert byte in W to 2-digit hex ;================================================ conv2h movwf char_hi swapf char_hi,w andlw 0x0f addlw .6 btfsc dc addlw 'A'-('9'+.1) addlw '0'-.6 xorwf char_hi,w xorwf char_hi xorwf char_hi,w andlw 0x0f addlw .6 btfsc dc addlw 'A'-('9'+.1) addlw '0'-.6 movwf char_lo nop movfw char_hi dispw movfw char_lo dispw wr_space return ;================================================ ; Copy RAM to EEPROM ; Note time for many writes @ 3ms each ;================================================ copyr2e bcf eecon1,eepgd bcf eecon1,cfgs lfsr fsr0,0x100 mov 0x00,eeadr mov 0x00,cnt1 c_r2e movff postinc0,eedata call save incf eeadr decfsz cnt1 bra c_r2e return save bsf eecon1,wren ;enable write mov 0x55,eecon2 mov 0xaa,eecon2 bsf eecon1,wr ;initiate write cycle nop wrend btfsc eecon1,wr ;wait for WR bit to clear bra wrend bcf eecon1,wren return ;================================================ ; Convert 8-bit data to ASCII for LCD - not used ;================================================ ; binary_to_bcd - 8-bits ; ; Input bin - 8-bit binary number ; ; Output ; ; d100 - hundreds digit of the BCD conversion ; d011 - tens and ones digits of the BCD conversion bin2bcd clrf d100 swapf temp,w addwf temp,w andlw b'00001111' btfsc dc addlw 0x16 btfsc dc addlw 0x06 addlw 0x06 btfss dc addlw -0x06 btfsc temp,4 addlw 0x16 - 1 + 0x6 btfss dc addlw -0x06 btfsc temp,5 addlw 0x30 btfsc temp,6 addlw 0x60 btfsc temp,7 addlw 0x20 addlw 0x60 rlcf d100 btfss d100,0 addlw -0x60 movwf d011 btfsc temp,7 incf d100 swapf d011,w andlw 0x0f movwf d010 movlw 0x0f andwf d011,w movwf d011 return ;================================================ ; Display 3-digit ASCII - not used ;================================================ show3 movf d100,w ;display 100s addlw 0x30 call write_d show2 movf d010,w ;display 10s addlw 0x30 call write_d movf d011,w ;display 1s addlw 0x30 call write_d movlw 0x20 ;trailing space call write_d return ;================================================ ; Convert 16-bit data to ASCII for LCD - not used ;================================================ ;data in hi:lo ascii16 nop radix dec clrf kzero clrf temp lfsr fsr0,dg1 bra $+4 sub10k incf temp movlw 10000 & 255 subwf lo IFNDEF known_zero movlw 10000 >> 8 skpc movlw (10000>>8)+1 subwf hi ELSE rlcf kzero,w sublw (10000>>8)+1 subwf hi ENDIF bc sub10k call out_temp mov 10,temp add1K decf temp movlw 1000 & 255 addwf lo IFNDEF kzero movlw 1000 >> 8 skpnc movlw (1000>>8)+1 addwf hi ELSE rlcf kzero,w addlw 1000 >> 8 addwf hi ENDIF bnc add1k call out_temp clrf temp movlw 100 bra $+4 sub100 incf temp subwf lo skpnc bra sub100 decf hi btfss hi,7 bra sub100 call out_temp mov 10,temp add10 decf temp addwf lo bnc add10 call out_temp call out_lo radix hex return ;convert to ASCII and store out_temp movfw temp addlw 0x30 ;add 0x30 to convert to ASCII movwf postinc0 return out_lo movfw lo addlw 0x30 movwf indf0 return ;================================================ ; Display 5-digit ASCII - not used ;================================================ show5 movfw dg1 call write_d movfw dg2 call write_d movfw dg3 call write_d movfw dg4 call write_d movfw dg5 call write_d movlw 0x20 call write_d return ;=============================================== ; LCD commands ;================================================ line1 movlw 0x00 ;line 1, column 0 call address return line2 movlw 0x40 ;line 2, column 0 call address return address addlw 0x80 ;set high bit of address command call write_c return write_c bcf rs ;write command bra d_out write_d bsf rs ;write data usec d_out movwf latb ;write to port usec bcf rw usec bsf en usec bcf en usec bsf rw ;set up for Busy Flag read usec bcf rs usec clrf portb usec mov b'10000000',trisb bsf en usec getbusy btfsc busy ;loop until Busy Flag clear bra getbusy bcf en usec bcf rw mov b'00000000',trisb return ;================================================ ; Initialise LCD screen ;================================================ lcd_init bcf rw usec bcf rs usec movlw 0x30 movwf portb usec bsf en usec bcf en call msdelay call msdelay call msdelay call msdelay call msdelay bsf en usec bcf en call msdelay movlw 0x38 call write_c movlw 0x0c call write_c movlw 0x01 call write_c movlw 0x06 call write_c return ;================================================ ; Clear all RAM ;================================================ clr_ram lfsr fsr0,0x000 lfsr fsr1,0x100 lfsr fsr2,0x200 clear1 clrf postinc0 clrf postinc1 clrf postinc2 btfss fsr0h,0 bra clear1 lfsr fsr0,0x300 lfsr fsr1,0x400 lfsr fsr2,0x500 clear2 clrf postinc0 clrf postinc1 clrf postinc2 btfss fsr0h,2 bra clear2 return ;================================================ ; Delays @ 10MHz ;================================================ one_sec movlw .246 ;1 second delay movwf temp1 call ms100 incfsz temp1 bra $-6 return ms100 movlw .156 ;100.5ms delay movwf temp ms1 call msdelay incfsz temp bra ms1 return ;1ms delay - call 100us delay 10 times msdelay movlw 0xf6 movwf cnt1 next100 call usdelay ;enter here with number of 100us in cnt1 incfsz cnt1 goto next100 return ;100us delay usdelay movlw 0xa7 movwf cnt2 inc movff temp,temp movff temp,temp movff temp,temp movff temp,temp incfsz cnt2 bra inc return end