Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

09/09/2011 #1

Avatar de zealot2

Que compilador usar para este codigo y
Muy buenas family. Por favor no quiero que lo lean todo, solo un paseo por encima.
1- Yo programo en CC5, nunca he hecho nada en asm para pics, por lo que no tengo ni la menor idea de como compilar este codigo, o sea, con que programa.
2- El otro lio, y el mas grave, es que este codigo esta escrito para un PIC16F628, y necesito imperiosamente modificarlo para un PIC16F877, debe poderse hacer porque el 16f628 no tiene nada que no tenga el 16f877.

Yo tengo el .hex del codigo que pondre a continuacion, cuando lo puse en proteus con el PIC16F628 como es logico funciona, pero cuando lo pongo con el PIC16F877, da errores de acceso a memoria que no existe, se pude modificar?, es solo cambiar las referencias distintas a los pines, ayuda por favor. Gracias

Código:
---------------------------------------------------------------------------------------------------------------

;CAPMET737.ASM 21AUG03 - COPYRIGHT JOHN BECKER - EPE IND/CAP/FREQ METER



;PIC16F628, 3.2768MHz, WDT OFF, POR ON, XTAL XS



;Config register bits

; CP1 CP0 CP1 CP0 NIL CPD LVP BOR MCL OS2 POR WDT OS1 OS0

;  1   1   1   1   1   1   0   0   1   0   0   0   0   1

;N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off

;respectively - refer to PIC '627/8 data sheet



#DEFINE BANK0 BCF $03,5

#DEFINE BANK1 BSF $03,5



        List P = PIC16F628, R=DEC; 

        __CONFIG   h'3F21'



        include P16F628.inc



        CBLOCK

REGA0				;lsb

REGA1

REGA2

REGA3				;msb



REGB0				;lsb

REGB1

REGB2

REGB3				;msb



REGC0				;lsb

REGC1

REGC2

REGC3				;msb



DSIGN				;Digit Sign. 0=positive,FF(or non zero)=negative

DIGIT1				;MSD

DIGIT2

DIGIT3

DIGIT4

DIGIT5				;Decimal digits

DIGIT6

DIGIT7

DIGIT8

DIGIT9

DIGIT10				;LSD

MTEMP

MCOUNT

DCOUNT



LOOP

LOOPA

RSLINE

STORE

SLOWIT

POINT

TIMEMSB

OVERFLOW

STORE2

LARGE

NANO

CAPREF3

CAPREF2

CAPREF1

CAPREF0

INDREF3

INDREF2

INDREF1

INDREF0

TIMEOUT

SWITCH

ZERO

INDCORRECT

CAPCORRECT

CORRECTLOC

        ENDC



PROMVAL  EQU $70   ; accessed via both BANKS



               ; locations up to $7F are available



; **************



        .ORG 0

        goto GIEOFF

        .ORG 4          ; Interrupt vector address

        goto GIEOFF

        .ORG 5          ; Start of program memory



GIEOFF: BCF INTCON,GIE  ; turn off global interrupts

        BTFSC INTCON,GIE

        goto GIEOFF

        goto START



TABLCD: addwf PCL,F     ;LCD initialisation table

        retlw %00110011 ;initialise lcd - first byte

        retlw %00110011 ;2nd byte (repeat of first)

        retlw %00110010 ;set for 4-bit operation

        retlw %00101100 ;set for 2 lines

        retlw %00000110 ;set entry mode to increment each address

        retlw %00001100 ;set display on, cursor off, blink off

        retlw %00000001 ;clear display

        retlw %00000010 ;return home, cursor & RAM to zero

                        ;end inititalisation table



TITLE:  addwf PCL,F

        retlw ' '

        retlw 'E'

        retlw 'P'

        retlw 'E'

        retlw ' '

        retlw 'L'

        retlw 'C'

        retlw 'F'

        retlw ' '

        retlw 'M'

        retlw 'E'

        retlw 'T'

        retlw 'E'

        retlw 'R'

        retlw ' '

        retlw ' '

        retlw ' '



TITLEB: addwf PCL,F

        retlw ' '

        retlw 'W'

        retlw 'A'

        retlw 'I'

        retlw 'T'

        retlw 'I'

        retlw 'N'

        retlw 'G'

        retlw ' '

        retlw 'T'

        retlw 'I'

        retlw 'M'

        retlw 'I'

        retlw 'N'

        retlw 'G'

        retlw ' '





OVERFLOWED:  addwf PCL,F

        retlw 'O'

        retlw 'V'

        retlw 'E'

        retlw 'R'

        retlw 'F'

        retlw 'L'

        retlw 'O'

        retlw 'W'



CALIB:  addwf PCL,F

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw 'N'

        retlw 'U'

        retlw 'L'

        retlw 'L'

        retlw 'E'

        retlw 'D'

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '



TIMEDOUT: addwf PCL,F

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw 'T'

        retlw 'I'

        retlw 'M'

        retlw 'E'

        retlw ' '

        retlw 'O'

        retlw 'U'

        retlw 'T'

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '



CAPTIME: addwf PCL,F

        retlw ' '

        retlw ' '

        retlw ' '

        retlw 'C'

        retlw 'A'

        retlw 'P'

        retlw 'A'

        retlw 'C'

        retlw 'I'

        retlw 'T'

        retlw 'O'

        retlw 'R'

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '



INDTIME: addwf PCL,F

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw 'I'

        retlw 'N'

        retlw 'D'

        retlw 'U'

        retlw 'C'

        retlw 'T'

        retlw 'O'

        retlw 'R'

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '





CORRECTMSG: addwf PCL,F

        retlw ' '

        retlw 'C'

        retlw 'O'

        retlw 'R'

        retlw 'R'

        retlw 'E'

        retlw 'C'

        retlw 'T'

        retlw 'I'

        retlw 'O'

        retlw 'N'

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '

        retlw ' '





;*******************



START:  clrf PORTA

        clrf PORTB

        movlw $07

        movwf CMCON



        BANK1

        movlw %11000000

        movwf TRISB

        movlw %00011100     ; RA0,RA1 as output

        movwf TRISA

        movlw %10000110     ; timer 1:128, pull-ups off

        movwf OPTION_REG

        BANK0



        clrf INTCON

        call PAUSIT

        call LCDSET

        call PAUSIT



        movlw %00000000     ; T1 ext osc disable (bit3=0), T1 stopped (bit0=0), internal clock (bit1=0), bit2 dont care

        movwf T1CON



        btfsc PORTA,2       ; is S3 (RA2) pressed?

        goto CORRECTIT



        call LCD1

        bsf RSLINE,4



        clrf LOOP

TITLE2: movf LOOP,W

        call TITLE

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TITLE2



        clrf INTCON

        clrf POINT

        clrf CAPREF3

        clrf CAPREF2

        clrf CAPREF1

        clrf CAPREF0

        clrf INDREF3

        clrf INDREF2

        clrf INDREF1

        clrf INDREF0



        movlw 0

        call PRMGET

        movwf INDCORRECT

        movlw 1

        call PRMGET

        movwf CAPCORRECT



        call PAUSIT         ; delay

        call PAUSIT         ; delay



        clrf INTCON

        movlw 255

        movwf SWITCH



;****************** START OF MAIN



MAIN:   clrf TIMEOUT

        movf PORTA,W

        andlw %00010000

        xorwf SWITCH,W

        btfsc STATUS,Z

        goto MAIN2



        movf PORTA,W

        andlw %00010000

        movwf SWITCH



        call LCD21

        bsf RSLINE,4

        clrf LOOP

TITLE3: movf LOOP,W

        call TITLEB

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TITLE3



        call LCD1

        bsf RSLINE,4

        clrf LOOP

        btfsc PORTA,4

        goto TIMOUT4



MAIN3:  movf LOOP,W

        call CAPTIME

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto MAIN3

        goto MAIN2



MAIN4:  movf LOOP,W

        call INDTIME

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TIMOUT4

        goto MAIN4



MAIN2:  btfsc SWITCH,4

        goto INDUCT

        goto CAPACITOR



; *****************



; QBASIC ROUTINE ILLUSTRATING INDUCTANCE FORMULA



;CLS

;DEFDBL A-Z

;PRINT "Formula:  L = ((1000000000 / (2 * PI * F) ^ 2)) / C"

;PRINT



;PI = 22 / 7

;F = 389305: PRINT "Frequency = "; F

;C = 200: C = (C * C) / (C + C): PRINT "Capacitance = "; C



;Process:

;L = F * 44: PRINT L

;L = INT(L / 7): PRINT L

;L = INT(1000000000 / L): PRINT L

;L = L * L: PRINT L

;L = INT(L / 10):

;L = L / 1000

;PRINT "Inductance = "; L; "uH"



; **************



INDUCT: movlw %00000001     ; set for correct osc

        movwf PORTA



        call INDTIMER       ; get osc frequency

        call COPY_TIME_REGA



        clrf POINT

        clrf LARGE



        movf TMR1H,W

        andlw %11000000

        iorwf TIMEMSB,W     ; is timing value less than 16384?

        btfsc STATUS,Z

        call LARGEVALUE     ; yes

        btfsc TIMEOUT,0

        goto TIMEEND



        call LCD1           ; set address

        bsf RSLINE,4        ; set RS for data send

        call BIN2DEC

        call SHOWITALL

        movlw 'H'

        call LCDOUT

        movlw 'z'

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT



        call COPY_TIME_REGA



        movlw 44            ; multiply freq x 44 (22 x 2) (2 x PI = 44/7)

        call MULTIPLYSMALL  ; REGA * 44 -> REGA        



        movlw 7             ; divide by 7

        call DIVIDESMALL    ; REGA / 7 -> REGA



        call COPY_REGA_REGB ; copy answer into REGB

        call DIVIDEBILLION  ; 1,000,000,000 / REGB -> REGA



        call COPY_REGA_REGB ; copy answer into REGB

        call MULTIPLY       ; REGA * REGB -> REGA (squaring REGA)

        movf STATUS,W

        andlw 1

        movwf OVERFLOW



        movlw '2'

        movf OVERFLOW,F

        btfss STATUS,Z

        goto SHOWOVERFLOW



        movlw 10            ; divide by 10

        call DIVIDESMALL    ; REGA / 100 -> REGA

        movf STATUS,W

        andlw 1

        movwf OVERFLOW



        movlw 'C'

        movf OVERFLOW,F

        btfss STATUS,Z

        goto SHOWOVERFLOW



        movf INDCORRECT,W   ; multiply by correction factor

        call MULTIPLYSMALL  ; REGA * REGB -> REGA

        movf STATUS,W

        andlw 1

        movwf OVERFLOW



        movlw 'A'

        movf OVERFLOW,F

        btfss STATUS,Z

        goto SHOWOVERFLOW



        movlw 100           ; divide by 100

        call DIVIDESMALL    ; REGA / 100 -> REGA

        movf STATUS,W

        andlw 1

        movwf OVERFLOW



        movlw 'B'

        movf OVERFLOW,F

        btfss STATUS,Z

        goto SHOWOVERFLOW



        btfsc PORTA,2       ; is S3 (RA2) pressed?

        call CALIBIND



        movf LARGE,F

        btfsc STATUS,Z

        call SUBTRACTINDREF



        movlw 4

        movwf POINT



        call LCD21          ; set address

        bsf RSLINE,4        ; set RS for data send



        call BIN2DEC        ; converts binary in REGA to decimal in DIGIT



        movf LARGE,F

        btfsc STATUS,Z

        call CHECKMILLI



        call SHOWITALL



        movf LARGE,F

        btfss STATUS,Z

        goto IND2



        movlw 'u'

        movf NANO,F

        btfss STATUS,Z

        movlw 'm'

        call LCDOUT

IND2:   movlw 'H'

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT



        goto MAIN



; ***************



CAPACITOR: movlw %00000010  ; set for correct osc

        movwf PORTA



        clrf TIMEMSB

        call INDTIMER



        call COPY_TIME_REGA



        clrf POINT

        clrf LARGE



        movf TMR1H,W

        andlw %11111110

        iorwf TIMEMSB,W     ; is timing value less than 512?

        btfsc STATUS,Z

        call LARGEVALUE     ; yes



        btfsc ZERO,0

        goto TIMEEND



        call LCD1           ; set address

        bsf RSLINE,4        ; set RS for data send

        call BIN2DEC

        call SHOWITALL

        movlw 'H'

        call LCDOUT

        movlw 'z'

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT



        call COPY_TIME_REGA



        movlw 22             ; multiply freq x PI (R = 1k) (ignoring 3 zeros)

        call MULTIPLYSMALL

        movlw 7

        call DIVIDESMALL



        call COPY_REGA_REGB ; copy answer into REGB

        call DIVIDEBILLION  ; REGA / REGB -> REGA



        movf CAPCORRECT,W   ; multiply by correction factor

        call MULTIPLYSMALL  ; REGA / REGB -> REGA

        movlw 100           ; divide by 100

        call DIVIDESMALL    ; REGA / 100 -> REGA



        btfsc PORTA,2       ; is S3 (RA2) pressed?

        call CALIBCAP



        movf LARGE,F

        btfsc STATUS,Z

        call SUBTRACTCAPREF



        call LCD21          ; set address

        bsf RSLINE,4        ; set RS for data send

        call BIN2DEC

        call CHECKNANO



        call SHOWITALL



        movlw 'u'

        movf LARGE,F

        btfss STATUS,Z

        goto CAP2



        movlw 'n'

        movf NANO,F

        btfsc STATUS,Z

        movlw 'p'

CAP2:   call LCDOUT

        movlw 'F'

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        call LCDOUT

        movlw ' '

        goto MAIN



; **************



LARGEVALUE:

        clrf TIMEOUT

        incf LARGE,F

        movlw %00000000     ; stop timer 1

        movwf T1CON

        clrf TMR1L          ; reset timer 1

        clrf TMR1H

        bcf PIR1,0          ; clear timer rollover flag



        movf PORTB,W        ; get current status of RB6

        andlw %01000000

        movwf STORE         ; store it



        clrf SLOWIT

        bsf T1CON,0         ; start timer 1



WAITB1:

        movf PORTA,W

        andlw %00010000

        xorwf SWITCH,W

        btfss STATUS,Z

        return



WAITB2: movf PORTB,W        ; get current status of RB6

        andlw %01000000

        movwf STORE2        ; temp store it



        xorwf STORE,W       ; compare with prev val of RB6

        btfsc STATUS,Z      ; is it equal?

        goto WAITB1         ; yes

        movf STORE2,W       ; no, different, so store val

        movwf STORE



        call OSCILLATE      ; get timing between two changes of RB6 (1 full cycle)

        btfsc TIMEOUT,0

        return



        call COPY_TIME_REGA

        movlw 122

        call MULTIPLYSMALL  ; REGA * 122 -> REGA multiply freq x 122 to get time re 3.2768MHz xtal (1000000/819200 =1.22)



        movlw 100           ; divide by 100

        call DIVIDESMALL    ; REGA / 100 -> REGA



        call COPY_REGA_REGB ; copy answer into REGB

        call DIVIDEBILLION  ; 1,000,000,000 / REGB -> REGA 



        movf REGA0,W        ; copy answer back into TIMER

        movwf TMR1L

        movf REGA1,W

        movwf TMR1H

        movf REGA2,W

        movwf TIMEMSB

        movlw 4

        movwf POINT

        return



; ***********



CHECKNANO: clrf NANO

        movf DIGIT1,W

        iorwf DIGIT2,W

        iorwf DIGIT3,W

        iorwf DIGIT4,W

        iorwf DIGIT5,W

        iorwf DIGIT6,W

        andlw %00001111

        btfsc STATUS,Z

        return

        bsf NANO,0

        movlw 4

        movwf POINT

        return



; ***********



CHECKMILLI: clrf NANO

        movf DIGIT1,W

        iorwf DIGIT2,W

        iorwf DIGIT3,W

        iorwf DIGIT4,W

        iorwf DIGIT5,W

        andlw %00001111

        btfsc STATUS,Z

        return

        bsf NANO,0

        movlw 7

        movwf POINT

        return



; *************



CALIBCAP: movf REGA0,W

        movwf CAPREF0

        movf REGA1,W

        movwf CAPREF1

        movf REGA2,W

        movwf CAPREF2

        movf REGA3,W

        movwf CAPREF3

        call SHOWCALIB

        return



CALIBIND: movf REGA0,W

        movwf INDREF0

        movf REGA1,W

        movwf INDREF1

        movf REGA2,W

        movwf INDREF2

        movf REGA3,W

        movwf INDREF3

        call SHOWCALIB

        return



; **************



SHOWCALIB: call LCD1

        bsf RSLINE,4



        clrf LOOP

CALIB2: movf LOOP,W

        call CALIB

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto CALIB2

        call PAUSIT

        return



; **************



SUBTRACTCAPREF: ; subtract ref from current val

                ; REGA - REGB -> REGA ;Return carry set if overflow

        movf CAPREF3,W

        movwf REGB3

        movf CAPREF2,W

        movwf REGB2

        movf CAPREF1,W

        movwf REGB1

        movf CAPREF0,W

        movwf REGB0

        call SUBTRACT

        movf STATUS,W

        andlw 1

        movwf OVERFLOW

        return



SUBTRACTINDREF: ; subtract ref from current val

                ; REGA - REGB -> REGA ;Return carry set if overflow

        movf INDREF3,W

        movwf REGB3

        movf INDREF2,W

        movwf REGB2

        movf INDREF1,W

        movwf REGB1

        movf INDREF0,W

        movwf REGB0

        call SUBTRACT

        movf STATUS,W

        andlw 1

        movwf OVERFLOW

        return



; **************



INDTIMER: movlw %00000110   ; T1 ext osc sync off (bit 2) timer1 off

        movwf T1CON         ; uses T1 ext clock input via RB6 and measures

                            ; number of clock pulses during 25 cycles of TMR0

        BANK1

        movlw %10000110     ; timer 1:128, pullups off

        movwf OPTION_REG

        BANK0



        clrf TMR1L          ; reset timer 1

        clrf TMR1H

        clrf TIMEMSB

        bcf PIR1,0          ; clr timer rollover flag



        movlw %00000111     ; T1 ext osc sync off (bit 2) timer1 on

        movwf T1CON



        movlw 25            

        movwf SLOWIT

        clrf TMR0

        bcf INTCON,2

TIMEIT: btfss PIR1,0        ; has timer 1 overflowed?

        goto TIMIT2

        bcf PIR1,0

        incf TIMEMSB,F

TIMIT2: btfss INTCON,2      ; has timer 0 overflowed?

        goto TIMEIT

        bcf INTCON,2

        decfsz SLOWIT,F

        goto TIMEIT



        movlw %00000000

        movwf T1CON

        return



; ****************



OSCILLATE:   clrf ZERO

        clrf T1CON

        clrf TMR1H

        clrf TMR1L

        bcf PIR1,0

        bsf T1CON,0         ; start timer 1



        clrf TIMEMSB

        bsf T1CON,0         ; start timer 1

OSCA1:

        movf PORTA,W

        andlw %00010000

        xorwf SWITCH,W

        btfss STATUS,Z

        return



        btfsc PIR1,0        ; has timer 1 overflowed?

        call INCMSB         ; yes



OSCA1A: movf PORTB,W        ; is RB6 same as before?

        andlw %01000000

        movwf STORE2

        xorwf STORE,W

        btfsc STATUS,Z

        goto OSCA1          ; yes

        movf STORE2,W       ; no, so continue for next cycle

        movwf STORE



OSCA2:

        movf PORTA,W

        andlw %00010000

        xorwf SWITCH,W

        btfss STATUS,Z

        return



        btfsc PIR1,0        ; has timer 1 overflowed?

        call INCMSB         ; yes



OSCA2A: movf PORTB,W        ; is RB6 same as before?

        andlw %01000000

        movwf STORE2

        xorwf STORE,W

        btfsc STATUS,Z

        goto OSCA2          ; yes

        movlw %00000000     ; no, stop timer 1

        movwf T1CON

        return



INCMSB: incf TIMEMSB,F

        decf SLOWIT,F

        bcf PIR1,0

        clrf TMR1H

        clrf TMR1L

        movf SLOWIT,F

        btfsc STATUS,Z

        bsf ZERO,0

        return



;******** LCD ROUTINES **********



LCD1:   movlw %10000000

        goto LCDLIN

LCD5:   movlw %10000101

        goto LCDLIN

LCD6:   movlw %10000110

        goto LCDLIN

LCD8:   movlw %10001000

        goto LCDLIN

LCD9:   movlw %10001001

        goto LCDLIN

LCD13:  movlw %10001101

        goto LCDLIN

LCD15:  movlw %10001111

        goto LCDLIN



LCD21:  movlw %11000000

        goto LCDLIN

LCD25:  movlw %11000101

        goto LCDLIN

LCD26:  movlw %11000110

        goto LCDLIN

LCD28:  movlw %11001000



LCDLIN: BCF RSLINE,4



LCDOUT: movwf STORE

        movlw 50

        movwf LOOPA

DELAYIT: decfsz LOOPA,F

        goto DELAYIT

        call SENDIT



SENDIT: swapf STORE,F

        movf STORE,W

        andlw 15

        iorwf RSLINE,W

        movwf PORTB

        BSF PORTB,5

        nop 

        nop

        BCF PORTB,5

        RETURN



; *************



PAUSIT: movlw 25

        movwf SLOWIT

        bcf INTCON,2

PAUSE:  btfss INTCON,2

        goto PAUSE

        bcf INTCON,2

        decfsz SLOWIT,F

        goto PAUSE

        return



PAUSIT2: clrf TMR0

        movlw 10

        movwf SLOWIT

        bcf INTCON,2

PAUSE2: btfss INTCON,2

        goto PAUSE2

        bcf INTCON,2

        decfsz SLOWIT,F

        goto PAUSE2

        return



;..............



LCDSET: clrf LOOP       ;clr LCD set-up loop

        clrf RSLINE     ;clear RS line for instruction send

LCDST2: movf LOOP,W     ;get table address

        call TABLCD     ;get set-up instruction

        call LCDOUT     ;perform it

        incf LOOP,F     ;inc loop

        btfss LOOP,3    ;has last LCD set-up instruction now been done?

        goto LCDST2     ;no

        return





CLRLINE1: call LCD1     ;set address for line 1 cell 1

        bsf RSLINE,4    ;set RS for data send

        clrf LOOP       ;

CLRL1:  movlw ' '       ;clear cell

        call LCDOUT     ;

        incf LOOP,F     ;inc loop

        btfss LOOP,4    ;has last LCD letter been sent?

        goto CLRL1      ;no

        return



CLRLINE2: call LCD21

        bsf RSLINE,4

        movlw 16

        movwf LOOP

CL2:    movlw ' '

        call LCDOUT

        decfsz LOOP,F

        goto CL2

        return



; ***********



SHOWITALL: movlw DIGIT1

        movwf FSR

        movlw 10

        movwf LOOP

SHOW2:  movf INDF,W

        call LCDOUT

        movf LOOP,W

        xorwf POINT,W

        btfss STATUS,Z

        goto SHOW3

        movlw '.'

        call LCDOUT

SHOW3:  incf FSR,F

        decfsz LOOP,F

        goto SHOW2

        return



; ***********



COPY_TIME_REGA:

        movf TIMEMSB,W

        movwf REGA2

        movf TMR1H,W

        movwf REGA1

        movf TMR1L,W

        movwf REGA0

        clrf REGA3

        return



; *********



MULTIPLYSMALL:

        movwf REGB0

        clrf REGB1

        clrf REGB2

        clrf REGB3

        call MULTIPLY

        movf STATUS,W

        andlw 1

        movwf OVERFLOW

        return



; *************



DIVIDESMALL:

        movwf REGB0

        clrf REGB1

        clrf REGB2

        clrf REGB3

        call DIVIDE

        movf STATUS,W

        andlw 1

        movwf OVERFLOW

        return



; ***********



DIVIDEBILLION:

        movlw $3B      ; divide 1,000,000,000 ($3B9ACA00) by the answer

        movwf REGA3

        movlw $9A

        movwf REGA2

        movlw $CA

        movwf REGA1

        movlw $00

        movwf REGA0

        call DIVIDE

        movf STATUS,W

        andlw 1

        movwf OVERFLOW

        return



; ***********



COPY_REGA_REGB:

        movf REGA0,W    

        movwf REGB0

        movf REGA1,W

        movwf REGB1

        movf REGA2,W

        movwf REGB2

        movf REGA3,W

        movwf REGB3

        return



; *********** PETER HEMSLEY'S 32-BIT MATHS ROUTINES *******



;*** SIGNED MULTIPLY ***

;REGA * REGB -> REGA

;Return carry set if overflow



multiply

	clrf	MTEMP		;Reset sign flag

	call	chksgna		;Make REGA positive

	skpc

	call	chksgnb		;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





; *************



;*** 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	chksgna		;Make dividend (REGA) positive

	skpc

	call	chksgnb		;Make divisor (REGB) positive

	skpnc

	return			;Overflow



	clrf	REGC0		;Clear remainder

	clrf	REGC1

	clrf	REGC2

	clrf	REGC3



	movlw	D'32'		;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



;*** 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





;*** SIGNED BINARY TO DECIMAL ***

;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN

;DSIGN = 0 if REGA is positive, FF if negative

;Return carry set if overflow

;Uses FSR register



bin2dec

        call    clrdig          ;Clear all digits

        clrf    MTEMP           ;Reset sign flag

	call	chksgna		;Make REGA positive

	skpnc

        goto BLANKIT            ;Overflow



	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'

	addwf	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

	comf	DSIGN,f		;Negative

	clrc



BLANKIT: movlw 48

        iorwf DIGIT1,F

        iorwf DIGIT2,F

        iorwf DIGIT3,F

        iorwf DIGIT4,F

        iorwf DIGIT5,F

        iorwf DIGIT6,F

        iorwf DIGIT7,F

        iorwf DIGIT8,F

        iorwf DIGIT9,F

        iorwf DIGIT10,F



        movlw 10          ; blank leading zeros

        movwf LOOP

        movlw DIGIT1

        movwf FSR

BLANK:  movf LOOP,W

        xorwf POINT,W

        btfsc STATUS,Z

        return

        movf INDF,W

        andlw 15

        btfss STATUS,Z

        return

        bcf INDF,4

        incf FSR,F

        decfsz LOOP,F

        goto BLANK

        movlw 48

        iorwf DIGIT10,F

        return



; **************



;Negate REGA

;Used by chksgna, multiply, divide, mod, bin2dec, dec2bin



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 REGA and convert negative to positive

;Used by multiply, divide, bin2dec



chksgna	rlf	REGA3,w

	skpc

	return			;Positive





;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



;Shift left REGA and REGC

;Used by multiply, divide



slac	rlf	REGA0,f

	rlf	REGA1,f

	rlf	REGA2,f

	rlf	REGA3,f

	rlf	REGC0,f

	rlf	REGC1,f

	rlf	REGC2,f

	rlf	REGC3,f

	return



;Check sign of REGB and negative convert to positive

;Used by multiply, divide, mod



chksgnb	rlf	REGB3,w

	skpc

	return			;Positive



;Negate REGB

;Used by chksgnb, subtract, multiply, divide, mod



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



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



;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





;*** SIGNED SUBTRACT ***

;REGA - REGB -> REGA

;Return carry set if overflow



subtract

	call	negateb		;Negate and add

	skpnc

	return			;Overflow



;*** 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



; *************



SHOWOVERFLOW: movwf OVERFLOW

        call CLRLINE2

        call LCD21

        bsf RSLINE,4



;        movf INDCORRECT,W      ; author's test section

;        movwf REGA0

;        movf LARGE,W

;        movwf REGA0

;        clrf REGA1

;        clrf REGA2

;        clrf REGA3

;        call BIN2DEC

;        call SHOWITALL



        clrf LOOP

OVER2:  movf LOOP,W

        call OVERFLOWED

        call LCDOUT

        incf LOOP,F

        btfss LOOP,3

        goto OVER2

        movlw ' '

        call LCDOUT

        movf OVERFLOW,W

        call LCDOUT

        goto MAIN



; ***********



CHECKZERO:

        movf TMR1H,W

        iorwf TMR1L,W

        iorwf TIMEMSB,W

        movf STATUS,Z

        andlw $00000100

        movwf OVERFLOW



TIMEEND: movlw %00000000      ; stop timer 1

        movwf T1CON

        clrf TMR1H

        clrf TMR1L

        clrf TIMEMSB

        call LCD21

        bsf RSLINE,4

        clrf LOOP

TIMOUT2: movf LOOP,W

        call TIMEDOUT

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TIMOUT2



        call LCD1

        bsf RSLINE,4

        clrf LOOP

        btfsc PORTA,4

        goto TIMOUT4



TIMOUT3: movf LOOP,W

        call CAPTIME

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TIMOUT3

        goto MAIN



TIMOUT4: movf LOOP,W

        call INDTIME

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto TIMOUT4

        goto MAIN





; ******* WRITE DATA TO EEPROM ROUTINE modified for PIC16F62x devices ********

          ;according to data sheet page 93 (is the same as for 16F87x devices

	  ; except that PIR2 of '87x has become PIR1 for '62x and page 2/3 not used)

	

                        ;This routine is entered with W holding

                        ;the eeprom byte address at which data

                        ;is to be stored. The data to be stored

                        ;is held in PROMVAL, which is located in both pages at or above $70

SETPRM: 

        BANK1

        movwf EEADR     ;copy W into EEADR to set eeprom address

        movf PROMVAL,W  ;get data value from PROMVAL and hold in W

        movwf EEDATA    ;copy W into eeprom data byte register

        bsf EECON1,WREN ;enable write flag



MANUAL: movlw $55       ;these lines cause the action required by

        movwf EECON2    ;by the eeprom to store the data in EEDATA

        movlw $AA       ;at the address held by EEADR.

        movwf EECON2

        bsf EECON1,WR   ;set the ``perform write'' flag

        BANK0



CHKWRT: btfss PIR1,EEIF ;wait until bit 4 of PIR2 is set

        goto CHKWRT

        bcf PIR1,EEIF   ;clear bit 4 of PIR2

        return



;******** READ DATA FROM EEPROM ROUTINE modified for PIC16F62x devices ****

;         the data sheet page 93 is wrong!  This routine here works!



                        ;This routine is entered with W holding

                        ;the eeprom byte address to be read.

PRMGET: BANK1

        movwf EEADR     ;copy W into EEADR to set eeprom address

        bsf EECON1,RD   ;enable read flag

        movf EEDATA,W   ;read eeprom data now in EEDATA into W

        BANK0

        return



; ***********



CORRECTIT:

        call LCD1

        bsf RSLINE,4

        btfss PORTA,4

        goto CAPCRT

        

INDCRT: movlw 'I'

        call LCDOUT

        movlw 'N'

        call LCDOUT

        movlw 'D'

        call LCDOUT

        clrf CORRECTLOC

        goto CORRECT2



CAPCRT: movlw 'C'

        call LCDOUT

        movlw 'A'

        call LCDOUT

        movlw 'P'

        call LCDOUT

        movlw 1 

        movwf CORRECTLOC



CORRECT2: clrf LOOP

CORRECT3: movf LOOP,W

        call CORRECTMSG

        call LCDOUT

        incf LOOP,F

        btfss LOOP,4

        goto CORRECT3



COR3:   call SHOWCORRECT

    

COR4:   btfsc PORTA,2       ; is S3 (RA2) still pressed?

        goto COR4           ; yes

        call PAUSIT



COR5:   btfss PORTA,2       ; is S3 (RA2) pressed?

        goto COR5           ; no



        btfsc PORTA,4

        goto COR7



COR6:   call INCIT

        call SHOWCORRECT

        call PAUSIT2

        call PAUSIT2

        goto COR5



COR7:   call DECIT

        call SHOWCORRECT

        call PAUSIT2

        call PAUSIT2

        goto COR5



INCIT:  movf CORRECTLOC,W

        call PRMGET

        movwf PROMVAL

        addlw 1

        movwf PROMVAL

        xorlw 200

        btfsc STATUS,Z

        decf PROMVAL,F

        movf CORRECTLOC,W

        call SETPRM

        return



DECIT:  movf CORRECTLOC,W

        call PRMGET

        movwf PROMVAL

        decf PROMVAL,F

        btfsc STATUS,Z

        incf PROMVAL,F

        movf CORRECTLOC,W

        call SETPRM

        return



; **********



SHOWCORRECT:

        movf CORRECTLOC,W

        call PRMGET

        movwf REGA0

        clrf REGA1

        clrf REGA2

        clrf REGA3



        call LCD21

        bsf RSLINE,4



        call BIN2DEC



        movf DIGIT8,W

        call LCDOUT

        movf DIGIT9,W

        call LCDOUT

        movf DIGIT10,W

        call LCDOUT

        return



; **************



        .org $2100             ; data eeprom values



        DE 100,100,0,0,0,0





        END
11/09/2011 #2
Moderador

Avatar de D@rkbytes

Ok saludos. es un hecho que este código es ensamblador así que compilalo con el MPASM
Te bajas la suite desde http://www.microchip.com/ que incluye el editor MPLAB IDE
12/09/2011 #3

Avatar de zealot2

Muchas gracias Darkbytes. Pero yo se perfectamente que es código de ensamblador, lo que necesito saber es cual compilador de ensamblador entendería este código?, ya que por ejemplo para aplicaciones de windows, no todos los compiladoes tienen la misma sintaxis en cuanto a etiquetas y esas cosas. Lo que necesito saber es en que compilador correría este código. gracias y disculpame la molestia.

Ahora me acabo de percatar despues de haber descargado el MPASM que no soporte ni el 16f628 ni el 16f877, pero que clase de compilador es ese dios mio!!!!!!!!!
12/09/2011 #4

Avatar de Eduardo

zealot2 dijo: Ver Mensaje
...Ahora me acabo de percatar despues de haber descargado el MPASM que no soporte ni el 16f628 ni el 16f877, pero que clase de compilador es ese dios mio!!!!!!!!!
Quedate tranquilo que los soporta.
12/09/2011 #5

Avatar de zealot2

Amigos, el codigo que puse arriva, les puedo decir con seguridad que los prove en MPASM y en el MPLAB, y en ambos me dio montones de errores. Por supuesto en MPASM por el P16F628.INC que no existe, y en el MPLAB a pesar de si existir y qu es lo especifique, tampoco compilo, entonces, que hago?
12/09/2011 #6

Avatar de dinoelectro

Para poder contestar a tu pregunta seria bueno que indicaras que mensaje te sale en MPLAB cuando lo mandas a compilar...
12/09/2011 #7
Moderador

Avatar de D@rkbytes

zealot2 dijo: Ver Mensaje
Muchas gracias Darkbytes. Pero yo se perfectamente que es código de ensamblador, lo que necesito saber es cual compilador de ensamblador entendería este código?, ya que por ejemplo para aplicaciones de windows, no todos los compiladoes tienen la misma sintaxis en cuanto a etiquetas y esas cosas. Lo que necesito saber es en que compilador correría este código. gracias y disculpame la molestia.

Ahora me acabo de percatar despues de haber descargado el MPASM que no soporte ni el 16f628 ni el 16f877, pero que clase de compilador es ese dios mio!!!!!!!!!
Ok saludos.
Como este es un foro de electrónica me fui directamente a contestar por el compilador MPASM para lenguaje ensamblador de PICMICRO ya que para ensamblador de software de PC yo uso el MASM32 v10 y se me hace raro que el MPASM que te descargaste no soporte el 16F628 ni el 16F877 yo uso esos actualmente en el MPLAB IDE v8 y si que los soporta.

zealot2 dijo: Ver Mensaje
Amigos, el codigo que puse arriva, les puedo decir con seguridad que los prove en MPASM y en el MPLAB, y en ambos me dio montones de errores. Por supuesto en MPASM por el P16F628.INC que no existe, y en el MPLAB a pesar de si existir y qu es lo especifique, tampoco compilo, entonces, que hago?
Cheque tu código y tiene algunos errores.
El problema esta en que algunas etiquetas a las cuales el programa hace llamada
estaban escritas con minuscula, y el compilador lo has de tener configurado para detectar entre minusculas y mayusculas.
Eran BIN2DEC MULTIPLY DIVIDE y SUBTRACT mas algunos errores en la sintaxis númerica.
Aqui te mando las correcciones que le hize para poder compilarlo junto con el archivo HEX compilado con MPASM
Archivos Adjuntos
Tipo de Archivo: rar CAPMET737.rar (10,0 KB (Kilobytes), 5 visitas)
13/09/2011 #8

Avatar de zealot2

Muchas gracias Darkbytes, voy a tirarle con tu correcion a ver si tengo suerte.

Si Eduardo, ahora vaje un MPASM y veo que si los soporta, gracias brother.
13/09/2011 #9
Moderador

Avatar de D@rkbytes

zealot2 dijo: Ver Mensaje
Muchas gracias Darkbytes, voy a tirarle con tu correcion a ver si tengo suerte.

Si Eduardo, ahora vaje un MPASM y veo que si los soporta, gracias brother.
Ok. Saludos y suerte.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.