📄 tenbit.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Project: Interfacing PICs
; Source File Name: TENBIT.ASM
; Devised by: MPB
; Date: 27-6-05
; Status: Working
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Demonstrates 10-bit voltage measurement
; using an external reference voltage of 4.096V,
; giving 4mV per bit, and an resolution of 0.1%.
; The result is converted to BCD for display
; as a voltage using the standard LCD routines.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESSOR 16F877
; Clock = XT 4MHz, standard fuse settings
__CONFIG 0x3731
; LABEL EQUATES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INCLUDE "P16F877A.INC"
; standard register labels
;----------------------------------------------------------
; User register labels
;----------------------------------------------------------
; GPR 20 - 2F allocated to included LCD display routine
count EQU 30 ; Counter for ADC setup delay
ADhi EQU 31 ; Binary input high byte
ADlo EQU 32 ; Binary input low byte
thos EQU 33 ; Thousands digit in decimal
huns EQU 34 ; Hundreds digit in decimal value
tens EQU 35 ; Tens digit in decimal value
ones EQU 36 ; Ones digit in decimal value
;----------------------------------------------------------
; PROGRAM BEGINS
;----------------------------------------------------------
ORG 0 ; Default start address
NOP ; required for ICD mode
;----------------------------------------------------------
; Port & display setup
BANKSEL TRISC ; Select bank 1
CLRF TRISD ; Display port is output
MOVLW B'10000011' ; Analogue input setup code
MOVWF ADCON1 ; Right justify result,
; Port A = analogue inputs
; with external reference
BANKSEL PORTC ; Select bank 0
CLRF PORTD ; Clear display outputs
MOVLW B'01000001' ; Analogue input setup code
MOVWF ADCON0 ; f/8, RA0, done, enable
CALL inid ; Initialise the display
;----------------------------------------------------------
; MAIN LOOP
;----------------------------------------------------------
start CALL getADC ; read input
CALL con4 ; convert to decimal
CALL putLCD ; display input
GOTO start ; jump to main loop
;-----------------------------------------------------------
; SUBROUTINES
;-----------------------------------------------------------
; Read ADC input and store
;-----------------------------------------------------------
getADC MOVLW 007 ; load counter
MOVWF count
down DECFSZ count ; and delay 20us
GOTO down
BSF ADCON0,GO ; start ADC..
wait BTFSC ADCON0,GO ; ..and wait for finish
GOTO wait
RETURN
;-----------------------------------------------------------
; Convert 10-bit input to decimal
;-----------------------------------------------------------
con4 MOVF ADRESH,W ; get ADC result
MOVWF ADhi ; high bits
BANKSEL ADRESL ; in bank 1
MOVF ADRESL,W ; get ADC result
BANKSEL ADRESH ; default bank 0
MOVWF ADlo ; low byte
; Multiply by 4 for result 0 - 4096 by shifting left.........
BCF STATUS,C ; rotate 0 into LSB and
RLF ADlo ; shift low byte left
BTFSS STATUS,C ; carry out?
GOTO rot1 ; no, leave carry clear
BSF STATUS,C ; rotate 1 into LSB and
rot1 RLF ADhi ; shift high byte left
BCF STATUS,C ; rotate 0 into LSB
RLF ADlo ; rotate low byte left again
BTFSS STATUS,C ; carry out?
GOTO rot2 ; no, leave carry clear
BSF STATUS,C ; rotate 1 into LSB and
rot2 RLF ADhi ; shift high byte left
; Clear BCD registers........................................
clrbcd CLRF thos ; zero thousands digit
CLRF huns ; zero hundreds digit
CLRF tens ; zero tens digit
CLRF ones ; zero ones digit
; Calclulate thousands low byte .............................
tholo MOVF ADhi,F ; check high byte
BTFSC STATUS,Z ; high byte zero?
GOTO hunlo ; yes, next digit
BSF STATUS,C ; set carry for subtract
MOVLW 0E8 ; load low byte of 1000
SUBWF ADlo ; and subtract low byte
BTFSC STATUS,C ; borrow from high bits?
GOTO thohi ; no, do high byte
DECF ADhi ; yes, subtract borrow
; Calculate thousands high byte..............................
thohi BSF STATUS,C ; set carry for subtract
MOVLW 003 ; load high byte of 1000
SUBWF ADhi ; subtract from high byte
BTFSC STATUS,C ; result negative?
GOTO incth ; no, inc digit and repeat
ADDWF ADhi ; yes, restore high byte
; Restore remainder when done ...............................
BCF STATUS,C ; clear carry for add
MOVLW 0E8 ; load low byte of 1000
ADDWF ADlo ; add to low byte
BTFSC STATUS,C ; carry out?
INCF ADhi ; yes, inc high byte
GOTO hunlo ; and do next digit
; Increment thousands digit and repeat.......................
incth INCF thos ; inc digit
GOTO tholo ; and repeat
; Calclulate hundreds .......................................
hunlo MOVLW 064 ; load 100
BSF STATUS,C ; set carry for subtract
SUBWF ADlo ; and subtract low byte
BTFSC STATUS,C ; result negative?
GOTO inch ; no, inc hundreds & repeat
MOVF ADhi,F ; yes, test high byte
BTFSC STATUS,Z ; zero?
GOTO remh ; yes, done
DECF ADhi ; no, subtract borrow
inch INCF huns ; inc hundreds digit
GOTO hunlo ; and repeat
remh ADDWF ADlo ; restore onto low byte
; Calculate tens digit......................................
subt MOVLW D'10' ; load 10
BSF STATUS,C ; set carry for subtract
SUBWF ADlo ; and subtract from result
BTFSS STATUS,C ; and check if done
GOTO remt ; yes, restore remainder
INCF tens ; no, count number of loops
GOTO subt ; and repeat
; Restore remainder.........................................
remt ADDWF ADlo ; yes, add 10 back on
MOVF ADlo,W ; load remainder
MOVWF ones ; and store as ones digit
RETURN ; done
;-----------------------------------------------------------
; Output to display
;-----------------------------------------------------------
putLCD BCF Select,RS ; set display command mode
MOVLW 080 ; code to home cursor
CALL send ; output it to display
BSF Select,RS ; and restore data mode
; Convert digits to ASCII and display.......................
MOVLW 030 ; load ASCII offset
ADDWF thos ; convert thousands to ASCII
ADDWF huns ; convert hundreds to ASCII
ADDWF tens ; convert tens to ASCII
ADDWF ones ; convert ones to ASCII
MOVF thos,W ; load thousands code
CALL send ; and send to display
MOVLW '.' ; load point code
CALL send ; and output
MOVF huns,W ; load hundreds code
CALL send ; and send to display
MOVF tens,W ; load tens code
CALL send ; and output
MOVF ones,W ; load ones code
CALL send ; and output
MOVLW ' ' ; load space code
CALL send ; and output
MOVLW 'V' ; load volts code
CALL send ; and output
MOVLW 'o' ; load volts code
CALL send ; and output
MOVLW 'l' ; load volts code
CALL send ; and output
MOVLW 't' ; load volts code
CALL send ; and output
MOVLW 's' ; load volts code
CALL send ; and output
RETURN ; done
;----------------------------------------------------------
; INCLUDED ROUTINES
;----------------------------------------------------------
; Include LCD driver routine
;
INCLUDE "LCDIS.INC"
;
; Contains routines:
; init: Initialises display
; onems: 1 ms delay
; xms: X ms delay
; Receives X in W
; send: sends a character to display
; Receives: Control code in W (Select,RS=0)
; ASCII character code in W (RS=1)
;
;----------------------------------------------------------
END ; of source code
;----------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -