__CONFIG _CONFIG1, _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_OFF & _LVP_OFF & _CP_OFF & _MCLRE_OFF
List P=16F628a
#include "P16F628a.INC"
__config _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_ON & _LVP_OFF & _CP_OFF & _MCLRE_OFF
No I trust you man, its just that I had another thought. I am still trying to put the resistor in a correct way, I wld let you know wht I have achievedThe pull up resistor is wrong...why won't you listen to me?
Disclaimer: I have not tested the contents of this code recently, am uploading to help friend here.
Code:;************************************* ; Author : Mike Baird ; Program : 32 bit calculator ; Date : June 13th, 2010 ;************************************* List P=16F88 #include "P16F88.INC" __CONFIG _CONFIG1, _PWRTE_OFF & _WDT_OFF & _INTRC_IO & _BODEN_OFF & _LVP_OFF & _CP_OFF & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF errorlevel -302,-305 ;*** Cblock *** CBLOCK 0x20 Count1 ; For delay! CountA ; CountB ; CountC TempLCD ; For LCD ; For all math InputA3 InputA2 ; For storing input keys InputA1 InputA0 ; InputB3 InputB2 InputB1 ; InputB0 ; REGA3 ; 32-bit Accumulator a, lsb+3, ms-byte REGA2 ; 32-bit Accumulator a, lsb+2 REGA1 ; 32-bit Accumulator a, lsb+1 REGA0 ; 32-bit Accumulator a, ls-byte REGB3 ; 32-bit Accumulator b, lsb+3, ms-byte REGB2 ; 32-bit Accumulator b, lsb+2 REGB1 ; 32-bit Accumulator b, lsb+1 REGB0 ; 32-bit Accumulator b, ls-byte REGC3 ; Scracth for Remainder and Multiplication REGC2 REGC1 REGC0 DSIGN DIGIT1 ; 10^9, billions DIGIT2 ; 10^8 DIGIT3 ; 10^7 DIGIT4 ; 10^6, millions DIGIT5 ; 10^5 DIGIT6 ; 10^4 DIGIT7 ; 10^3, thousands DIGIT8 ; 10^2 DIGIT9 ; 10^1 DIGIT10 ; 10^0 DCOUNT ; digit count MCOUNT MTEMP Temp Operation ENDC ;*** Defines *** ; PORTB #Define Column1 PORTB,3 #Define Column2 PORTB,2 #Define Column3 PORTB,1 #Define Column4 PORTB,0 #Define Row1 PORTB,7 #Define Row2 PORTB,6 #Define Row3 PORTB,5 #Define Row4 PORTB,4 LCD_Port EQU PORTA RS EQU 0x04 RW EQU 0x06 E EQU 0x07 ;*** START OF RAM *** ORG 0x000 ; Start of program vector GOTO Start ; ORG 0x004 ; Interrupt vector ;*** Configuration *** Start clrf PORTA ; PortA all low clrf PORTB ; PortB all low bsf STATUS,RP0 ; Bank 1 movlw b'01100000' ; Make clock 4Mhz iorwf OSCCON ; movlw b'00100000' ; Bit 5 input movwf TRISA movlw 0xF0 ; PortA all output except MCLR movwf TRISB ; PortB half in half out clrf ANSEL ; Make PORTA all digital I/O bcf STATUS,RP0 ; Bank 0 call Delay100 ; wait for LCD to settle call LCD_Init ; Initialize LCD ;*** Main *** bsf Column1 ; set up columns bsf Column2 bsf Column3 bsf Column4 Main movlw .32 ; 32 registers to clear movwf CountC movlw InputA3 movwf FSR clrf INDF ; Clear all registers sequentially incf FSR decfsz CountC goto $-3 ; *** Input and Load ACa0-4 *** call Delay255 call CheckKeys movwf Temp call LCD_Char movlw .48 ; Turn into 0-9 (Not ASCII) subwf Temp,W movwf REGA0 movwf InputA0 InputACa call Delay255 call CheckKeys movwf Temp ; Hold temporarily xorlw '*' ; was operation pressed? btfsc STATUS,Z goto ChooseOperation ; yes it was movlw .10 ; multiply by 10 movwf REGB0 ; on every other pass it will now x10 call multiply ; e.g. for 1 digit * X movf Temp,W ; Show key call LCD_Char movlw .48 ; Turn into 0-9 (Not ASCII) subwf Temp,W addwf REGA0,W movwf REGA0 movwf InputA0 addcf REGA1 movf REGA1,W movwf InputA1 movf REGA2,W movwf InputA2 movf REGA3,W movwf InputA3 goto InputACa ;*** Input and Load ACb0-4 *** ChooseOperation: call LCD_Line2 call Delay255 call CheckKeys movwf Temp xorlw '*' bz RedrawFirst movf Temp,w movwf Operation movlw .48 subwf Operation,w call OperationTable call LCD_Char goto ChooseOperation OperationTable addwf PCL nop retlw '+' retlw '-' retlw '*' retlw '/' retlw 's' RedrawFirst call LCD_Clr call LCD_Line1 movf InputA0,w movwf REGA0 movf InputA1,w movwf REGA1 movf InputA2,w movwf REGA2 movf InputA3,w movwf REGA3 call bin2dec movlw .10 movwf CountC movlw DIGIT1 movwf FSR clearzeros movf INDF,W ; Clear all leading 0's bnz answerdisplay incf FSR decf CountC movf CountC,W ; If answer is actually 0, display just one Zero xorlw .1 btfsc STATUS,Z goto answerdisplay goto clearzeros answerdisplay: movf INDF,W call LCD_CharD incf FSR ; point at next digit decfsz CountC goto answerdisplay movlw .48 subwf Operation,w call OperationTable call LCD_Char NextInput call Delay255 call CheckKeys movwf Temp call LCD_Char movlw .48 ; Turn into 0-9 (Not ASCII) subwf Temp,W movwf REGA0 movwf InputB0 clrf REGA1 InputACb call Delay255 call CheckKeys movwf Temp ; Hold temporarily xorlw '*' ; was multiply again pressed? btfsc STATUS,Z goto MathTime ; yes it was, we are done getting inputs movlw .10 ; multiply by 10 movwf REGB0 ; on every other pass it will now x10 call multiply movf Temp,W ; Show key call LCD_Char movlw .48 subwf Temp,W addwf REGA0,W movwf REGA0 movwf InputB0 addcf REGA1 movf REGA1,W movwf InputB1 movf REGA2,W movwf InputB2 movf REGA3,W movwf InputB3 goto InputACb ;*** Perform Operation *** MathTime movf InputA0,W movwf REGA0 movf InputA1,W movwf REGA1 movf InputA2,W movwf REGA2 movf InputA3,W movwf REGA3 movf InputB0,W movwf REGB0 movf InputB1,W movwf REGB1 movf InputB2,W movwf REGB2 movf InputB3,W movwf REGB3 movlw .48 subwf Operation clrc rlf Operation,w addwf PCL nop nop call add goto DisplayResult call subtract goto DisplayResult call multiply goto DisplayResult call divide goto DisplayResult call sqrt ;*** Display Result *** DisplayResult call bin2dec call LCD_Line2 ; Display answer on Line 2 movlw '=' call LCD_Char movlw ' ' call LCD_Char movlw .1 xorwf DSIGN skpz goto $+3 movlw '-' call LCD_Char movlw .10 movwf CountC movlw DIGIT1 movwf FSR ClearZeros movf INDF,W ; Clear all leading 0's bnz AnswerDisplay incf FSR decf CountC movf CountC,W ; If answer is actually 0, display just one Zero xorlw .1 btfsc STATUS,Z goto AnswerDisplay goto ClearZeros AnswerDisplay: movf INDF,W call LCD_CharD incf FSR ; point at next digit decfsz CountC goto AnswerDisplay call Delay255 call CheckKeys ; A key press will now restart the calculator call LCD_Clr call LCD_Line1 call Delay255 ; Debouncing goto Main ;********************************** Math Subroutines ************************************** ;{ ;*** 32 BIT SIGNED SUTRACT *** ;REGA - REGB -> REGA ;Return carry set if overflow subtract call negateb ;Negate REGB skpnc return ;Overflow ;*** 32 BIT SIGNED ADD *** ;REGA + REGB -> REGA ;Return carry set if overflow add movf REGA3,w ;Compare signs xorwf REGB3,w movwf MTEMP call addba ;Add REGB to REGA clrc ;Check signs movf REGB3,w ;If signs are same xorwf REGA3,w ;so must result sign btfss MTEMP,7 ;else overflow addlw 0x80 return ;*** 32 BIT SIGNED MULTIPLY *** ;REGA * REGB -> REGA ;Return carry set if overflow multiply clrf MTEMP ;Reset sign flag call absa ;Make REGA positive skpc call absb ;Make REGB positive skpnc return ;Overflow call movac ;Move REGA to REGC call clra ;Clear product movlw D'31' ;Loop counter movwf MCOUNT muloop call slac ;Shift left product and multiplicand rlf REGC3,w ;Test MSB of multiplicand skpnc ;If multiplicand bit is a 1 then call addba ;add multiplier to product skpc ;Check for overflow rlf REGA3,w skpnc return decfsz MCOUNT,f ;Next goto muloop btfsc MTEMP,0 ;Check result sign call negatea ;Negative return ;*** 32 BIT SIGNED DIVIDE *** ;REGA / REGB -> REGA ;Remainder in REGC ;Return carry set if overflow or division by zero divide clrf MTEMP ;Reset sign flag movf REGB0,w ;Trap division by zero iorwf REGB1,w iorwf REGB2,w iorwf REGB3,w sublw 0 skpc call absa ;Make dividend (REGA) positive skpc call absb ;Make divisor (REGB) positive skpnc return ;Overflow clrf REGC0 ;Clear remainder clrf REGC1 clrf REGC2 clrf REGC3 call slac ;Purge sign bit movlw D'31' ;Loop counter movwf MCOUNT dvloop call slac ;Shift dividend (REGA) msb into remainder (REGC) movf REGB3,w ;Test if remainder (REGC) >= divisor (REGB) subwf REGC3,w skpz goto dtstgt movf REGB2,w subwf REGC2,w skpz goto dtstgt movf REGB1,w subwf REGC1,w skpz goto dtstgt movf REGB0,w subwf REGC0,w dtstgt skpc ;Carry set if remainder >= divisor goto dremlt movf REGB0,w ;Subtract divisor (REGB) from remainder (REGC) subwf REGC0,f movf REGB1,w skpc incfsz REGB1,w subwf REGC1,f movf REGB2,w skpc incfsz REGB2,w subwf REGC2,f movf REGB3,w skpc incfsz REGB3,w subwf REGC3,f clrc bsf REGA0,0 ;Set quotient bit dremlt decfsz MCOUNT,f ;Next goto dvloop btfsc MTEMP,0 ;Check result sign call negatea ;Negative return ;*** ROUND RESULT OF DIVISION TO NEAREST INTEGER *** round clrf MTEMP ;Reset sign flag call absa ;Make positive clrc call slc ;Multiply remainder by 2 movf REGB3,w ;Test if remainder (REGC) >= divisor (REGB) subwf REGC3,w skpz goto rtstgt movf REGB2,w subwf REGC2,w skpz goto dtstgt movf REGB1,w subwf REGC1,w skpz goto rtstgt movf REGB0,w subwf REGC0,w rtstgt skpc ;Carry set if remainder >= divisor goto rremlt incfsz REGA0,f ;Add 1 to quotient goto rremlt incfsz REGA1,f goto rremlt incfsz REGA2,f goto rremlt incf REGA3,f skpnz return ;Overflow,return carry set rremlt btfsc MTEMP,0 ;Restore sign call negatea return ;*** 32 BIT SQUARE ROOT *** ;sqrt(REGA) -> REGA ;Return carry set if negative sqrt rlf REGA3,w ;Trap negative values skpnc return call movac ;Move REGA to REGC call clrba ;Clear remainder (REGB) and root (REGA) movlw D'16' ;Loop counter movwf MCOUNT sqloop rlf REGC0,f ;Shift two msb's rlf REGC1,f ;into remainder rlf REGC2,f rlf REGC3,f rlf REGB0,f rlf REGB1,f rlf REGB2,f rlf REGC0,f rlf REGC1,f rlf REGC2,f rlf REGC3,f rlf REGB0,f rlf REGB1,f rlf REGB2,f setc ;Add 1 to root rlf REGA0,f ;Align root rlf REGA1,f rlf REGA2,f movf REGA2,w ;Test if remdr (REGB) >= root (REGA) subwf REGB2,w skpz goto ststgt movf REGA1,w subwf REGB1,w skpz goto ststgt movf REGA0,w subwf REGB0,w ststgt skpc ;Carry set if remdr >= root goto sremlt movf REGA0,w ;Subtract root (REGA) from remdr (REGB) subwf REGB0,f movf REGA1,w skpc incfsz REGA1,w subwf REGB1,f movf REGA2,w skpc incfsz REGA2,w subwf REGB2,f bsf REGA0,1 ;Set current root bit sremlt bcf REGA0,0 ;Clear test bit decfsz MCOUNT,f ;Next goto sqloop clrc rrf REGA2,f ;Adjust root alignment rrf REGA1,f rrf REGA0,f return ;*** 32 BIT SIGNED BINARY TO DECIMAL *** ;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN ;DSIGN = 0 if REGA is positive, 1 if negative ;Return carry set if overflow ;Uses FSR register bin2dec clrf MTEMP ;Reset sign flag call absa ;Make REGA positive skpnc return ;Overflow call clrdig ;Clear all digits movlw D'32' ;Loop counter movwf MCOUNT b2dloop rlf REGA0,f ;Shift msb into carry rlf REGA1,f rlf REGA2,f rlf REGA3,f movlw DIGIT10 movwf FSR ;Pointer to digits movlw D'10' ;10 digits to do movwf DCOUNT adjlp rlf INDF,f ;Shift digit and carry 1 bit left movlw D'10' subwf INDF,w ;Check and adjust for decimal overflow skpnc movwf INDF decf FSR,f ;Next digit decfsz DCOUNT,f goto adjlp decfsz MCOUNT,f ;Next bit goto b2dloop btfsc MTEMP,0 ;Check sign bsf DSIGN,0 ;Negative clrc return ;*** 32 BIT SIGNED DECIMAL TO BINARY *** ;Decimal DIGIT1 thro DIGIT(X) & DSIGN -> REGA ;Set DSIGN = 0 for positive, DSIGN = 1 for negative values ;Most significant digit in DIGIT1 ;Enter this routine with digit count in w register ;Return carry set if overflow ;Uses FSR register dec2bin movwf MTEMP ;Save digit count movlw D'32' ;Outer bit loop counter movwf MCOUNT d2blp1 movlw DIGIT1-1 ;Set up pointer to MSD movwf FSR movf MTEMP,w ;Inner digit loop counter movwf DCOUNT movlw D'10' clrc ;Bring in '0' bit into MSD d2blp2 incf FSR,f skpnc addwf INDF,f ;Add 10 if '1' bit from prev digit rrf INDF,f ;Shift out LSB of digit decfsz DCOUNT,f ;Next L.S. Digit goto d2blp2 rrf REGA3,f ;Shift in carry from digits rrf REGA2,f rrf REGA1,f rrf REGA0,f decfsz MCOUNT,f ;Next bit goto d2blp1 movf INDF,w ;Check for overflow addlw 0xFF skpc rlf REGA3,w skpnc return btfsc DSIGN,0 ;Check result sign call negatea ;Negative return ;UTILITY ROUTINES ;Add REGB to REGA (Unsigned) ;Used by add, multiply, addba movf REGB0,w ;Add lo byte addwf REGA0,f movf REGB1,w ;Add mid-lo byte skpnc ;No carry_in, so just add incfsz REGB1,w ;Add carry_in to REGB addwf REGA1,f ;Add and propagate carry_out movf REGB2,w ;Add mid-hi byte skpnc incfsz REGB2,w addwf REGA2,f movf REGB3,w ;Add hi byte skpnc incfsz REGB3,w addwf REGA3,f return ;Move REGA to REGC ;Used by multiply, sqrt movac movf REGA0,w movwf REGC0 movf REGA1,w movwf REGC1 movf REGA2,w movwf REGC2 movf REGA3,w movwf REGC3 return ;Clear REGB and REGA ;Used by sqrt clrba clrf REGB0 clrf REGB1 clrf REGB2 clrf REGB3 ;Clear REGA ;Used by multiply, sqrt clra clrf REGA0 clrf REGA1 clrf REGA2 clrf REGA3 return ;Check sign of REGA and convert negative to positive ;Used by multiply, divide, bin2dec, round absa rlf REGA3,w skpc return ;Positive ;Negate REGA ;Used by absa, multiply, divide, bin2dec, dec2bin, round negatea movf REGA3,w ;Save sign in w andlw 0x80 comf REGA0,f ;2's complement comf REGA1,f comf REGA2,f comf REGA3,f incfsz REGA0,f goto nega1 incfsz REGA1,f goto nega1 incfsz REGA2,f goto nega1 incf REGA3,f nega1 incf MTEMP,f ;flip sign flag addwf REGA3,w ;Return carry set if -2147483648 return ;Check sign of REGB and convert negative to positive ;Used by multiply, divide absb rlf REGB3,w skpc return ;Positive ;Negate REGB ;Used by absb, subtract, multiply, divide negateb movf REGB3,w ;Save sign in w andlw 0x80 comf REGB0,f ;2's complement comf REGB1,f comf REGB2,f comf REGB3,f incfsz REGB0,f goto negb1 incfsz REGB1,f goto negb1 incfsz REGB2,f goto negb1 incf REGB3,f negb1 incf MTEMP,f ;flip sign flag addwf REGB3,w ;Return carry set if -2147483648 return ;Shift left REGA and REGC ;Used by multiply, divide, round slac rlf REGA0,f rlf REGA1,f rlf REGA2,f rlf REGA3,f slc rlf REGC0,f rlf REGC1,f rlf REGC2,f rlf REGC3,f return ;Set all digits to 0 ;Used by bin2dec clrdig clrf DSIGN clrf DIGIT1 clrf DIGIT2 clrf DIGIT3 clrf DIGIT4 clrf DIGIT5 clrf DIGIT6 clrf DIGIT7 clrf DIGIT8 clrf DIGIT9 clrf DIGIT10 return ;} ;*** Keypad Subroutine *** ;{ CheckKeys bsf Column1 bcf Column4 btfss Row1 ; Yes, check rows retlw 'A' ; if row is off, store 2 in work reg btfss Row2 ; Check which row was pressed and fill Temp with appropriate value retlw 'B' ; btfss Row3 ; retlw 'C' ; btfss Row4 ; retlw 'D' ; COLUMN3 bsf Column4 bcf Column3 btfss Row1 ; Yes, check rows retlw '3' ; if row is off, store 2 in work reg btfss Row2 ; Check which row was pressed and fill Temp with appropriate value retlw '6' btfss Row3 ; retlw '9' ; btfss Row4 ; retlw '#' ; COLUMN2 bsf Column3 bcf Column2 btfss Row1 ; retlw '2' ; btfss Row2 ; retlw '5' ; btfss Row3 ; retlw '8' ; btfss Row4 ; retlw '0' ; COLUMN1 bsf Column2 bcf Column1 btfss Row1 ; retlw '1' btfss Row2 ; retlw '4' ; btfss Row3 ; retlw '7' ; btfss Row4 ; retlw '*' goto CheckKeys ;} ;*** LCD routines *** ;{ LCD_Init movlw 0x20 ; Set to 4 bit mode call LCD_Cmd ; movlw 0x28 ; Set display shift to 1 call LCD_Cmd ; movlw 0x06 ; Set display move right after character sent call LCD_Cmd ; movlw 0x0D ; Set display on, don't underline cursor but flash it call LCD_Cmd ; call LCD_Clr ; Clear display call LCD_CurOff return LCD_Cmd movwf TempLCD swapf TempLCD,W ; Send upper nibble andlw 0x0F ; Clear upper 4 bits of W (Not to interfere with RS,RW and E) movwf LCD_Port bcf LCD_Port,RS ; RS line to 0 bsf LCD_Port,E ; Pulse the E line high nop bcf LCD_Port,E movf TempLCD,W ; Send lower nibble andlw 0x0F ; Clear upper 4 bits of W movwf LCD_Port bcf LCD_Port,RS ; RS line to 0 bsf LCD_Port,E ; Pulse the E line high nop bcf LCD_Port,E call Delay5 return LCD_CharD addlw 0x30 ; Convert W to ASCII LCD_Char movwf TempLCD ; swapf TempLCD,W ; Send upper nibble andlw 0x0F ; Clear upper 4 bits of W movwf LCD_Port ; bsf LCD_Port,RS ; RS line to 1 bsf LCD_Port,E ; Pulse the E line high nop bcf LCD_Port,E movf TempLCD,W ; Send lower nibble andlw 0x0F ; Clear upper 4 bits of W movwf LCD_Port bsf LCD_Port,RS ; RS line to 1 bsf LCD_Port,E ; Pulse the E line high nop bcf LCD_Port,E call Delay5 return LCD_Line1 movlw 0x80 ; Move to 1st row, first column call LCD_Cmd return LCD_Line2 movlw 0xC0 ; Move to 2nd row, first column call LCD_Cmd return LCD_Line1W addlw 0x80 ; Move to 1st row, column W call LCD_Cmd return LCD_Line2W addlw 0xC0 ; Move to 2nd row, column W call LCD_Cmd return LCD_CurOn movlw 0x0D ; Set display on/off and cursor command call LCD_Cmd return LCD_CurOff movlw 0x0C ; Set display on/off and cursor command call LCD_Cmd return LCD_Clr movlw 0x01 ; Clear display call LCD_Cmd return ;} ;*** Delay Routines *** ;{ Delay255 movlw d'255' ; Delay 255 mS goto d0 Delay100 movlw d'100' ; Delay 100mS goto d0 Delay50 movlw d'50' ; Delay 50mS goto d0 Delay20 movlw d'20' ; Delay 20mS goto d0 Delay5 movlw d'5' ; Delay 5.000 ms (4 MHz clock) d0 movwf Count1 d1 movlw 0xC7 ; Delay 1mS movwf CountA movlw 0x01 movwf CountB Delay_0 decfsz CountA,F goto $+2 decfsz CountB,F goto Delay_0 decfsz Count1,F goto d1 return ;} ;*** End *** END
A rather old thread...!
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?