;------------------------------------------------------------------------------- ; FILE: Memory ; AUTH: Ed's Projects ; DATE: 28/06/2016 ; DESC: 4x4 Keypad input, 10 values saved to RAM, displayed on LCD ;------------------------------------------------------------------------------- LIST P=16F628A, R=DEC ; All numbers Decimal format unless otherwise stated. include ; Define configurations, registers, etc. __config _CP_OFF & _CPD_OFF & _LVP_OFF & _BOREN_ON & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _HS_OSC ;------------------------------------------------------------------------------- ;----------------------------- Port Definitions ------------------------------ ;------------------------------------------------------------------------------- ; PortA - Output - RA0 - Pin 17 - RS Register select for LCD ; PortA - Output - RA1 - Pin 18 - E Enable for LCD ; PortB - Output - RB4 - Pin 10 - DB4 Dataline for LCD ; PortB - Output - RB5 - Pin 11 - DB5 Dataline for LCD ; PortB - Output - RB6 - Pin 12 - DB6 Dataline for LCD ; PortB - Output - RB7 - Pin 13 - DB7 Dataline for LCD ; PortB - Output - RB0 - Pin 6 - Column 1 Keypad ; PortB - Output - RB1 - Pin 7 - Column 2 Keypad ; PortB - Output - RB2 - Pin 8 - Column 3 Keypad ; PortB - Output - RB3 - Pin 9 - Column 4 Keypad ; PortA - Input - RA2 - Pin 1 - Row 1 Keypad ; PortA - Input - RA3 - Pin 2 - Row 2 Keypad ; PortA - Input - RA4 - Pin 3 - Row 3 Keypad ; PortA - Input - RA5 - Pin 4 - Row 4 Keypad ;------------------------------------------------------------------------------- ;-------------------------------- Variables ---------------------------------- ;------------------------------------------------------------------------------- cblock h'20' micro200f ms2delayf ms2delayg dly0 Tmp temp temp2 offset keytemp vartemp lcdtemp clrtemp endc ;------------------------------------------------------------------------------- ;----------------------------- Define Symbols -------------------------------- ;------------------------------------------------------------------------------- #define LCD4 PORTB, 4 #define LCD5 PORTB, 5 #define LCD6 PORTB, 6 #define LCD7 PORTB, 7 #define LCDRS PORTA, 0 #define LCDE PORTA, 1 #define R1 PORTA, 2 #define R2 PORTA, 3 #define R3 PORTA, 4 #define R4 PORTA, 5 #define C1 PORTB, 0 #define C2 PORTB, 1 #define C3 PORTB, 2 #define C4 PORTB, 3 ;------------------------------------------------------------------------------- ;------------------------------- Program Code -------------------------------- ;------------------------------------------------------------------------------- ORG 0 ;------------------------------------------------------------------------------- ;-------------------------- Initialisation of Ports -------------------------- ;------------------------------------------------------------------------------- Init bsf STATUS,RP0 ; Set RP0 to 1 bcf STATUS,RP1 ; Set RP1 to 0 ; Bank 1 Selected clrf VRCON ; Set Vref to off clrf TRISB ; Set all PortB as Output movlw b'00111100' ; Load 00111100 to working register movwf TRISA ; bcf STATUS,RP0 ; Set RP0 to 0 ; Bank 0 Selected movlw d'7' ; Load working register with "7" movwf CMCON ; Turn off comparators clrf PORTA clrf PORTB clrf micro200f clrf ms2delayf clrf ms2delayg clrf dly0 clrf Tmp clrf temp clrf temp2 clrf keytemp clrf clrtemp movlw h'A0' movwf vartemp movlw h'A0' ; This section will clear the first 64 movwf FSR ; blocks of RAM in bank 1 clrram clrf INDF incf FSR, f incf clrtemp, f btfss clrtemp, 6 goto clrram ; Clear variables and output ports ;------------------------------------------------------------------------------- ;--------------------------- LCD Initialisation ------------------------------ ;------------------------------------------------------------------------------- movlw d'32' call delay bsf LCD5 bsf LCD4 call Enable call ms2delay call ms2delay call Enable call micro200 call Enable bcf LCD4 call Enable ;Function Set movlw b'00101000' ;4-bit mode, 2 lines, 5x7 matrix call SendLCD ;Display on / off movlw b'00001100' ;Display on, Cursor off, Blink off call SendLCD ;Entry Mode Set movlw b'00000110' ;Increment, Display shifted call SendLCD ;Cursor or display shift movlw b'00010000' ;Display Shift call SendLCD ;Clear Screen movlw b'00000001' ; Clear screen call SendLCD call ms2delay call ms2delay bsf LCDRS ; Set data mode goto Start ;------------------------------------------------------------------------------- ;----------------------------- Send Data to LCD ------------------------------ ;------------------------------------------------------------------------------- SendLCD ; Send data in two 4-bit nibbles movwf Tmp bcf LCD7 bcf LCD6 bcf LCD5 bcf LCD4 btfsc Tmp, 7 bsf LCD7 btfsc Tmp, 6 bsf LCD6 btfsc Tmp, 5 bsf LCD5 btfsc Tmp, 4 bsf LCD4 call Enable bcf LCD7 bcf LCD6 bcf LCD5 bcf LCD4 btfsc Tmp, 3 bsf LCD7 btfsc Tmp, 2 bsf LCD6 btfsc Tmp, 1 bsf LCD5 btfsc Tmp, 0 bsf LCD4 call Enable return ;------------------------------------------------------------------------------- ;--------------------------------- Enable ------------------------------------ ;------------------------------------------------------------------------------- Enable bsf LCDE nop nop nop nop bcf LCDE call micro200 call micro200 call micro200 return ;------------------------------------------------------------------------------- ;--------------------------------- LCD Clear --------------------------------- ;------------------------------------------------------------------------------- LCDClr bcf LCDRS movlw b'00000001' call SendLCD bsf LCDRS call ms2delay call ms2delay return ;------------------------------------------------------------------------------- ;----------------------------- LCD Cursor Shift ------------------------------ ;------------------------------------------------------------------------------- LCDShi bcf LCDRS iorlw b'10000000' call SendLCD bsf LCDRS call ms2delay return ;------------------------------------------------------------------------------- ;--------------------------- LCD Character Space ----------------------------- ;------------------------------------------------------------------------------- LCDSpace movlw d'32' call SendLCD return ;------------------------------------------------------------------------------- ;---------------------------- Loops 2ms Delay -------------------------------- ;------------------------------------------------------------------------------- delay movwf dly0 delayloop call ms2delay decfsz dly0, f goto delayloop return ;------------------------------------------------------------------------------- ;------------------------------- 2ms Delay ----------------------------------- ;------------------------------------------------------------------------------- ms2delay movlw d'8' movwf ms2delayg ms2delayc movlw d'250' movwf ms2delayf ms2delaya nop ;0.2us nop ;0.2us decfsz ms2delayf,f ;0.2us goto ms2delaya ;0.4us ;total 250us ms2delayb decfsz ms2delayg,f ;0.2us goto ms2delayc ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------- 200us Delay --------------------------------- ;------------------------------------------------------------------------------- micro200 movlw d'200' movwf micro200f micro200a nop ;0.2us nop ;0.2us decfsz micro200f,f ;0.2us goto micro200a ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;--------------------------- Character Storage ------------------------------- ;------------------------------------------------------------------------------- Charr call LCDClr clrf offset charra movf offset, w call charrlookup ; fetch a character addlw 0 btfsc STATUS, Z return call SendLCD call micro200 incf offset, f goto charra charrlookup addwf PCL, f DT " Welcome to ", "4x4 Keypad using the", " Ed's Projects ", " PIC16F628A ", d'0' Char1 ; Since this table will cross the page boundary call LCDClr ; and increment the PCH then PCLATH must be clrf offset ; dealt with Char1a call Char1b ; Fetch a character addlw 0 btfsc STATUS, Z goto Char1c call SendLCD call micro200 incf offset, f ; Increment offset to choose next character goto Char1a ; from table Char1b movlw LOW table ; Get low 8 bits of table address addwf offset, w ; Check to see if a carry will occur movlw HIGH table ; Get high 5 bits of address btfsc STATUS, C ; Has page crossed? addlw 1 ; Yes then increment PCLATH - PCH movwf PCLATH ; Load high address into PCLATH - PCH movlw LOW table ; Get low 8 bits of table address again addwf offset, w ; Load original PCL offset value movwf PCL ; Jump into table table DT "Please enter a value ", d'0' Char1c movlw h'A0' ; Load start of RAM location to be sent movwf lcdtemp Chard movf lcdtemp, w movwf FSR movf INDF, w addlw d'48' call SendLCD incf lcdtemp movf lcdtemp, w xorlw h'AA' ; Check if ten digits have been sent, if btfss STATUS, Z ; so return goto Chard return ;------------------------------------------------------------------------------- ;---------------------------------- Keypad ----------------------------------- ;------------------------------------------------------------------------------- Keyscan bsf C1 ; Check to see if any key has been pressed bsf C2 bsf C3 bsf C4 btfsc R1 goto scanprocess btfsc R2 goto scanprocess btfsc R3 goto scanprocess btfsc R4 goto scanprocess return Keynot ; Return to main program when no keys are bsf C1 ; pressed bsf C2 bsf C3 bsf C4 btfsc R1 goto Keynot btfsc R2 goto Keynot btfsc R3 goto Keynot btfsc R4 goto Keynot bsf temp2, 0 return scanprocess ; Start scanning which key is pressed bsf C1 bcf C2 bcf C3 bcf C4 movlw d'1' call Rscan bcf C1 movlw d'2' bsf C2 call Rscan bcf C2 movlw d'3' bsf C3 call Rscan bcf C3 movlw d'32' bsf C4 call Rscan movf keytemp, w xorlw d'11' btfsc STATUS, Z clrf keytemp ; When 48 is added later on it will translate movf keytemp, w ; to the ASCII number 0 xorlw d'10' btfsc STATUS, Z call star movf keytemp, w xorlw d'12' btfsc STATUS, Z call hash goto Keynot star ; When 48 is added later on it will roll over movlw d'250' ; to ASCII number 42 - * movwf keytemp return hash movlw d'243' ; When 48 is added later on it will roll over movwf keytemp ; to ASCII number 35 - # return Rscan btfsc R1 goto R1set btfsc R2 goto R2set btfsc R3 goto R3set btfsc R4 goto R4set return R1set movwf keytemp call checkalpha goto Keynot R2set addlw d'3' movwf keytemp call checkalpha goto Keynot R3set addlw d'6' movwf keytemp call checkalpha goto Keynot R4set addlw d'9' movwf keytemp call checkalpha goto Keynot checkalpha btfss keytemp, 5 return movf keytemp, w xorlw b'00100000' btfsc STATUS, Z goto leta movf keytemp, w xorlw b'00100011' btfsc STATUS, Z goto letb movf keytemp, w xorlw b'00100110' btfsc STATUS, Z goto letc goto letd leta movlw d'17' ; When 48 is added later on these will movwf keytemp ; translate to ASCII letter corresponding return ; with what was pressed on the keypad letb movlw d'18' movwf keytemp return letc movlw d'19' movwf keytemp return letd movlw d'20' movwf keytemp return ;------------------------------------------------------------------------------- ;------------------------- Main part of program ------------------------------ ;------------------------------------------------------------------------------- Start call Charr movlw d'250' call delay movlw d'250' call delay movlw d'250' call delay movlw d'250' call delay call Char1 Here call Keyscan btfsc temp2, 0 ; Only write if a new character has been entered call incvar clrf temp2 clrf keytemp goto Here incvar movf vartemp, w movwf FSR movf keytemp, w movwf INDF call Char1 clrf keytemp incf vartemp movf vartemp, w xorlw h'AA' btfss STATUS, Z return movlw h'A0' movwf vartemp return end