Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC calculator

Status
Not open for further replies.
__config 0x3D18 means 0011 1101 0001 1000

15 = 0 = not used
14 = 0 = not used
13 = 1 = Flash Code protect off
12 = 1 = unused so ignore

11 = 1 = unused so ignore
10 = 1 = unused so ignore
9 = 0 = unused so ignore
8 = 1 = Data Code protect=off

7 = 0 = Use MCLR for programming
6 = 0 = Brown out reset disabled
5 = 0 = MCLR is I/O
4 = 1 = (100) internal Osc.

3 = 1 = powerup timer disabled
2 = 0 = watchdog disabled
1 = 0 = FOSC1 = internal oscillator (100)
0 = 0 = FOSC0 = internal oscillator (100)

so bit 4,1 and 0 being 1,0,0 respectively, means
INTRC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC/CLKIN

I also tried
__config Ox2109
which means 0010 0001 0000 1001
so bit 4,1 and 0 being 0,0,1 respectively, means
XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN

Still there was no display on the Lcd, so which of this configurations must I use for bit 4,1 and 0:

FOSC2:FOSC0: Oscillator Selection bits(4)
111 = ER oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, Resistor on RA7/OSC1/CLKIN
110 = ER oscillator: I/O function on RA6/OSC2/CLKOUT pin, Resistor on RA7/OSC1/CLKIN
100 = INTRC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
011 = EC: I/O function on RA6/OSC2/CLKOUT pin, CLKIN on RA7/OSC1/CLKIN
010 = HS oscillator: High speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
001 = XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
000 = LP oscillator: Low power crystal on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
 
Last edited:
Why not just do this, also you just suggested Clock Out twice.
Code:
	__CONFIG	_CONFIG1,   _PWRTE_ON  & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_OFF  & _LVP_OFF & _CP_OFF & _MCLRE_OFF
 
when I use

__CONFIG _CONFIG1, _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOR_OFF & _LVP_OFF & _CP

I get the following erros on MPLAB

Release build of project `D:\SEKOLO\forum\mplab\lcd_copy.disposable_mcp' started.
Language tool versions: MPASMWIN.exe v5.30.01, mplink.exe v4.30.01
Thu Dec 09 20:41:43 2010
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F628A "lcd_copy.asm" /l"lcd_copy.lst" /e"lcd_copy.err"
Error[113] D:\SEKOLO\FORUM\MPLAB\LCD_COPY.ASM 8 : Symbol not previously defined (_CONFIG1)
Error[108] D:\SEKOLO\FORUM\MPLAB\LCD_COPY.ASM 8 : Illegal character (,)
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `D:\SEKOLO\forum\mplab\lcd_copy.disposable_mcp' failed.
Language tool versions: MPASMWIN.exe v5.30.01, mplink.exe v4.30.01
Thu Dec 09 20:41:44 2010
----------------------------------------------------------------------
BUILD FAILED
 
Thanks man for the new version, Maybe this time there is something wrong with how I have setup, MPLAB. I still get the same error

Release build of project `D:\SEKOLO\forum\mplab\lcd_copy.disposable_mcp' started.
Language tool versions: MPASMWIN.exe v5.37, mplink.exe v4.37, mplib.exe v4.37
Sat Dec 11 13:30:27 2010
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F628A "lcd_copy.asm" /l"lcd_copy.lst" /e"lcd_copy.err"
Error[113] D:\SEKOLO\FORUM\MPLAB\LCD_COPY.ASM 9 : Symbol not previously defined (_CONFIG1)
Error[108] D:\SEKOLO\FORUM\MPLAB\LCD_COPY.ASM 9 : Illegal character (,)
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `D:\SEKOLO\forum\mplab\lcd_copy.disposable_mcp' failed.
Language tool versions: MPASMWIN.exe v5.37, mplink.exe v4.37, mplib.exe v4.37
Sat Dec 11 13:30:28 2010
----------------------------------------------------------------------
BUILD FAILED
 
Code:
	List	P=16F628a		
	#include	"P16F628a.INC"	
	__config	_PWRTE_ON  & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_ON & _LVP_OFF & _CP_OFF & _MCLRE_OFF

I blame me for that one, sorry :D
Try this code
 
Yeah, there is no errors now. The code I am using I copied it from . I think the way I built the circuit is not the same as that circuit shown on the previous link. Whats wrong with my circuit because there is still no massege displayed.

I changed the code on the configuration part
I introduced
__config _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_ON & _LVP_OFF & _CP_OFF & _MCLRE_OFF

insteat of
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)
 

Attachments

  • circuitt.jpg
    circuitt.jpg
    75.6 KB · Views: 371
Birdman0_o I wld like to know if you ever use proteus on some of your projects. If so I wld like to know which version are you using. I am using Proteus 7.1. it came to my sense that maybe I should use the new version 7.6. I m still downloading it. after I have instlled it and tested the program I wld let you know. Could you please test mine on your proteus and see what you will get. Thank you very much
 
The pull up resistor is wrong...why won't you listen to me?
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 achieved
 
good day every one... someone can gave me a circuit diagram and code source, using pic16f877a ask a calculator... for my project in micro-controller... tnx
 
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...!
 
Awfully stupid way of wasting my time. :facepalm:
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top