;********************************************************************** ; This file is a basic code template for assembly code generation * ; on the PICmicro PIC16F873. This file contains the basic code * ; building blocks to build upon. * ; * ; If interrupts are not used all code presented between the ORG * ; 0x004 directive and the label main can be removed. In addition * ; the variable assignments for 'w_temp' and 'status_temp' can * ; be removed. * ; * ; Refer to the MPASM User's Guide for additional information on * ; features of the assembler (Document DS33014). * ; * ; Refer to the respective PICmicro data sheet for additional * ; information on the instruction set. * ; * ; Template file assembled with MPLAB V4.00 and MPASM V2.20.00 * ; * ;********************************************************************** ; * ; Filename: xxx.asm * ; Date: * ; File Version: * ; * ; Author: * ; Company: * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; * ; * ;********************************************************************** ; * ; Notes: * ; * ; * ; * ; * ;********************************************************************** list p=16f873 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _RC_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. errorlevel -302 ;***** VARIABLE DEFINITIONS cblock 0x20 w_temp ; variable used for context saving status_temp ; variable used for context saving count temp temp1 lcdrs ; LCD RS setting adh ; A/D hi saving adl ; A/D lo saving R0 ; BCD hi |hi nible col 6, lo nible col 5 R1 ; BCD mid |hi nible col 4, lo nible col 3 R2 ; BCD lo |hi nible col 2, lo nible col 1 endc ;********************************************************************** ORG 0x000 ; processor reset vector nop ; clrf PCLATH ; ensure page bits are cleared goto init ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register bcf STATUS,RP0 ; ensure file register bank set to 0 movwf status_temp ; save off contents of STATUS register ; isr code can go here or be located as a call subroutine elsewhere bcf STATUS,RP0 ; ensure file register bank set to 0 movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ; ;******************************************************************** ; Binary To BCD Conversion Routine ; This routine converts a 16 Bit binary Number to a 5 Digit ; BCD Number. This routine is useful since PIC16C55 & PIC16C57 ; have two 8 bit ports and one 4 bit port ( total of 5 BCD digits) ; ; The 16 bit binary number is input in locations H_byte and ; L_byte with the high byte in H_byte. ; The 5 digit BCD number is returned in R0, R1 and R2 with R0 ; containing the MSD in its right most nibble. ; ; Performance : ; Program Memory : 35 ; Clock Cycles : 885 ; ; ; Program: B16TOBCD.ASM ; Revision Date: ; 1-13-97 Compatibility with MPASMWIN 1.40 ; input location ; adh hi byte ; adl lo byte ; results location ; R0 ; BCD hi | hi nible col 6, lo nible col 5 ; R1 ; BCD mid | hi nible col 4, lo nible col 3 ; R2 ; BCD lo | hi nible col 2, lo nible col 1 ; scratch location ; count ; temp ; ;*******************************************************************; ; ; scrach area: count,temp ; H_byte equ adh L_byte equ adl ; B2_BCD bcf STATUS,0 ; clear the carry bit movlw 16 movwf count ;scrach pad clrf R0 clrf R1 clrf R2 loop16 rlf L_byte, F rlf H_byte, F rlf R2, F rlf R1, F rlf R0, F ; decfsz count, F goto adjDEC RETLW 0 ; adjDEC movlw R2 movwf FSR call adjBCD ; movlw R1 movwf FSR call adjBCD ; movlw R0 movwf FSR call adjBCD ; goto loop16 ; adjBCD movlw 3 addwf 0,W movwf temp btfsc temp,0x03 ; test if result > 7 movwf 0 movlw 0x30 addwf 0,W movwf temp btfsc temp,7 ; test if result > 7 movwf 0 ; save as MSD RETLW 0 ; ;******************************************************************** ; Test Program ;********************************************************************* ;main movlw 0FF ; movwf H_byte ; movwf L_byte ; The 16 bit binary number = FFFF ; call B2_BCD ; After conversion the Decimal Number ; ; in R0,R1,R2 = 06,55,35 ; ;self goto self ; ; org 1FF ; goto main ; ; END init ;** WDT set ** banksel OPTION_REG movlw 0xFA ;prescaler 1/4 => 18ms * 4 = 72ms movwf OPTION_REG ;maybe 18ms is enough, but more rooms. clrwdt bcf TRISA,4 ;set unused RA4 output mode, don't care output level ;** LCD initialize ** banksel PORTB ;b2=E b1=RW b0=RS clrf PORTB ;E=0, RW=0(W), RS=0 banksel TRISB clrf TRISB ;PORTB(LCD control)=output banksel PORTB bsf PORTB,2 ;E=1 before set LCD data movlw 0x38 ;8b Bus, 2 lines, 5x7 dots movwf PORTC banksel TRISC clrf TRISC ;PORTC(LCD data bus)=output banksel PORTB clrf PORTB ;E=0 movlw 137 ;Wait for 4.1ms (10us/inst..15.6us@RT) movwf count ;4.1ms/(10us*3) decfsz count,1 goto $-1 bsf PORTB,2 ;E positive pulse clrf PORTB movlw 4 ;100us/(10us*3) movwf count decfsz count,1 goto $-1 bsf PORTB,2 ;E positive pulse clrf PORTB movlw 2 ;40us/(10us*3) movwf count decfsz count,1 goto $-1 bsf PORTB,2 ;E positive pulse clrf PORTB clrf lcdrs movlw 0x08 ;Display off, Cursol off, Blink off call lcdset movlw 0x01 ;Clear display (Display on) call lcdset movlw 0x0C ;Display on, Cursol off, Blink off call lcdset movlw 0x06 ;Entry mode: Increment, No shift call lcdset ;** AD converter initialize ** banksel ADCON1 movlw 0x88 ;fills form right, AN4 V+ V- AN1 AN0 movwf ADCON1 ;AN4...-15V, AN1...+15V, AN0...+5 movlw 0xEF ;RA4 (not in use, make impedance low) movwf TRISA banksel ADCON0 movlw 0xC1 ;RC clock, AD on movwf ADCON0 ; goto main ;Main main clrwdt ;-15V conversion bsf ADCON0,5 ;AN4 bsf ADCON0,2 ;AD start btfsc ADCON0,2 ;check if AD complete goto $-1 bcf ADCON0,5 movf ADRESH,0 movwf temp banksel ADRESL movf ADRESL,0 banksel ADCON0 movwf temp1 bcf STATUS,0 ; clear the carry bit rlf temp1,1 rlf temp,1 movf temp1,0 sublw (3 * 512) & 0xFF movwf adl btfss STATUS,0 incf temp,1 movf temp,0 sublw (3 * 512) >> 8 movwf adh call B2_BCD clrf lcdrs ;set LCD display position movlw 0x80 call lcdset incf lcdrs ;set char '-' movlw '-' call lcdset movf R1,0 movwf temp rrf temp,1 rrf temp,1 rrf temp,1 rrf temp,0 andlw 0x0f addlw '0' call lcdset movf R1,0 andlw 0x0f addlw '0' call lcdset movlw '.' call lcdset movf R2,0 movwf temp rrf temp,1 rrf temp,1 rrf temp,1 rrf temp,0 andlw 0x0f addlw '0' call lcdset movf R2,0 andlw 0x0f addlw '0' call lcdset movlw 'V' call lcdset ;+15V conversion bsf ADCON0,3 ;AN1 bsf ADCON0,2 ;AD start btfsc ADCON0,2 ;check if AD complete goto $-1 bcf ADCON0,3 movf ADRESH,0 movwf adh banksel ADRESL movf ADRESL,0 banksel ADCON0 movwf adl bcf STATUS,0 ; clear the carry bit rlf adl,1 rlf adh,1 call B2_BCD clrf lcdrs ;set LCD display position movlw 0xc2 call lcdset incf lcdrs ;set char '+' movlw '+' call lcdset movf R1,0 movwf temp rrf temp,1 rrf temp,1 rrf temp,1 rrf temp,0 andlw 0x0f addlw '0' call lcdset movf R1,0 andlw 0x0f addlw '0' call lcdset movlw '.' call lcdset movf R2,0 movwf temp rrf temp,1 rrf temp,1 rrf temp,1 rrf temp,0 andlw 0x0f addlw '0' call lcdset movf R2,0 andlw 0x0f addlw '0' call lcdset movlw 'V' call lcdset ;+5V conversion bsf ADCON0,2 ;AD0 start btfsc ADCON0,2 ;check if AD complete goto $-1 movf ADRESH,0 movwf adh banksel ADRESL movf ADRESL,0 banksel ADCON0 movwf adl call B2_BCD clrf lcdrs ;set LCD display position movlw 0xca call lcdset incf lcdrs ;set char '+' movlw '+' call lcdset ; movf R1,0 ; movwf temp ; rrf temp,1 ; rrf temp,1 ; rrf temp,1 ; rrf temp,0 ; andlw 0x0f ; addlw '0' ; call lcdset movf R1,0 andlw 0x0f addlw '0' call lcdset movlw '.' call lcdset movf R2,0 movwf temp rrf temp,1 rrf temp,1 rrf temp,1 rrf temp,0 andlw 0x0f addlw '0' call lcdset movf R2,0 andlw 0x0f addlw '0' call lcdset movlw 'V' call lcdset ; goto main ;LCD check lcdck clrf lcdrs movlw 0x80 ;Set DDRAM address call lcdset movlw 0x01 movwf lcdrs movlw 'B' ;Set LCD character call lcdset goto $ ; lcdset ;** LCD set subroutine ** banksel PORTC movwf PORTC movlw 0x06 ;E=1 RW=1(R) RS=0 movwf PORTB banksel TRISC decf TRISC,1 ;input from LCD banksel PORTB bcf PORTB,2 ;E=0 bsf PORTB,2 ;E=1 btfsc PORTC,7 ;check busy bit goto $-3 movf lcdrs,0 movwf PORTB ;E=0 RW=0(W) RS=0/1 banksel TRISC clrf TRISC ;output to LCD banksel PORTB bsf PORTB,2 ;E=1 bcf PORTB,2 ;E=0 return end