?? mplxch0.asm
字號:
;*********************************************************************
;This program is to demonstrate how to multiplex four 7 segment LED
;and sample ch0 of the a/d in a PIC16C71. The a/d value is displayed
;as a 3 digit decimal value of the a/d input (0 - 255).
;The LEDs are updated every 20mS, the a/d is sampled every 20 mS.
;The RTCC timer is used in internal interrupt mode to generate the
;5 mS.
;
; Stan D'Souza 5/8/93
;
;
;
; Program: MPLXCH0.ASM
; Revision Date:
; 1-15-97 Compatibility with MPASMWIN 1.40
;
;**********************************************************************
LIST P=16C71
ERRORLEVEL -302
;
include <p16c71.inc>
;
BcdMsd equ 26
Bcd equ 27
TempC equ 0x0c ;temp general purpose regs
TempD equ 0x0d
TempE equ 0x0e
PABuf equ 0x20
PBBuf equ 0x21
Count equ 0x0f ;count
MsdTime equ 0x10 ;most significant Timer
LsdTime equ 0x11 ;Least significant Timer
ADFlag equ 0x12 ;flags related to key pad
ADOver equ 5 ;bit 5 --> a/d over
WBuffer equ 0x2f
StatBuffer equ 0x2e
OptionReg equ 1
PCL equ 2
;
push macro
movwf WBuffer ;save w reg in Buffer
swapf WBuffer, F ;swap it
swapf STATUS,W ;get status
movwf StatBuffer ;save it
endm
;
pop macro
swapf StatBuffer,W ;restore status
movwf STATUS ; /
swapf WBuffer,W ;restore W reg
endm
;
org 0
goto Start ;skip over interrupt vector
;
org 4
;It is always a good practice to save and restore the w reg,
;and the status reg during a interrupt.
push
call ServiceInterrupts
pop
retfie
;
Start
call InitPorts
call InitTimers
call InitAd
loop
btfsc ADFlag,ADOver ;a/d over?
call UpdateAd ;yes then update
goto loop
;
UpdateAd
btfss ADCON0,ADIF ;a/d done?
return ;no then leave
movf ADRES,W ;get a/d value
movwf L_byte
clrf H_byte
call B2_BCD
movf R2,W ;get LSd
movwf LsdTime ;save in LSD
movf R1,W ;get Msd
movwf MsdTime ;save in Msd
bcf ADCON0,ADIF ;clr interrupt flag
bcf ADCON0,ADON ;turn off a/d
bcf ADFlag,ADOver ;clr flag
return
;
;
;
InitPorts
bsf STATUS,RP0 ;select pg 1
movlw 3 ;make RA0-3 digital I/O
movwf ADCON1 ; /
clrf TRISA ;make RA0-4 outputs
clrf TRISB ;make RB0-7 outputs
bcf STATUS,RP0 ;select page 0
clrf PORTA ;make all outputs low
clrf PORTB ; /
bsf PORTA,3 ;enable MSB digit sink
return
;
;
;The clock speed is 4.096Mhz. Dividing internal clk. by a 32 prescaler,
;the rtcc will be incremented every 31.25uS. If rtcc is preloaded
;with 96, it will take (256-96)*31.25uS to overflow i.e. 5mS. So the
;end result is that we get a rtcc interrupt every 5mS.
InitTimers
clrf MsdTime ;clr timers
clrf LsdTime ; /
bsf STATUS,RP0 ;select pg 1
movlw B'10000100' ;assign ps to rtcc
movwf OptionReg ;ps = 32
bcf STATUS,RP0 ;select pg 0
movlw B'00100000' ;enable rtcc interrupt
movwf INTCON ;
movlw .96 ;preload rtcc
movwf TMR0 ;start counter
retfie
;
;
InitAd
movlw B'11000000' ;rc osc, ch 0 for a/d
movwf ADCON0
return
;
;
ServiceInterrupts
btfsc INTCON,T0IF ;rtcc interrupt?
goto ServiceTMR0 ;yes then service
clrf INTCON
bsf INTCON,T0IE
return
;
ServiceTMR0
movlw .96 ;initialize rtcc
movwf TMR0
bcf INTCON,T0IF ;clr int flag
btfss PORTA,0 ;last digit?
call SampleAd ;then sample a/d
call UpdateDisplay ;else update display
return
;
;
SampleAd
call SavePorts
call DoAd ;do a ad conversion
AdDone
btfsc ADCON0,GO ;ad done?
goto AdDone ;no then loop
bsf ADFlag,ADOver ;set a/d over flag
call RestorePorts ;restore ports
return
;
;
DoAd
clrf PORTB ;turn off leds
bsf STATUS,RP0 ;select pg 1
movlw 0x0f ;make port a hi-Z
movwf TRISA ; /
bcf STATUS,RP0 ;select pg 0
bsf ADCON0,ADON ;start a/d
movlw .125
call Wait
bsf ADCON0,GO ;start conversion
return
;
;
Wait
movwf TempC ;store in temp
Next
decfsz TempC, F
goto Next
return
;
;SavePorts, saves the porta and portb condition during a key scan
;operation.
SavePorts
movf PORTA,W ;Get sink value
movwf PABuf ;save in buffer
clrf PORTA ;disable all sinks
movf PORTB,W ;get port b
movwf PBBuf ;save in buffer
movlw 0xff ;make all high
movwf PORTB ;on port b
bsf STATUS,RP0 ;select page 1
bcf OptionReg,7 ;enable pull ups
movlw B'11110000' ;port b hi nibble inputs
movwf TRISB ;lo nibble outputs
bcf STATUS,RP0 ;page 0
return
;
;RestorePorts, restores the condition of porta and portb after a
;key scan operation.
RestorePorts
movf PBBuf,W ;get port n
movwf PORTB
movf PABuf,W ;get port a value
movwf PORTA
bsf STATUS,RP0 ;select page 1
bsf OptionReg,7 ;disable pull ups
clrf TRISA ;make port a outputs
clrf TRISB ;as well as PORTB
bcf STATUS,RP0 ;page 0
return
;
;
UpdateDisplay
movf PORTA,W ;present sink value in w
clrf PORTA ;disable all digits sinks
andlw 0x0f
movwf TempC ;save sink value in tempC
bsf TempC,4 ;preset for lsd sink
rrf TempC, F ;determine next sink value
btfss STATUS,C ;c=1?
bcf TempC,3 ;no then reset LSD sink
btfsc TempC,0 ;else see if Msd
goto UpdateMsd ;yes then do Msd
btfsc TempC,1 ;see if 3rdLsd
goto Update3rdLsd ;yes then do 3rd Lsd
btfsc TempC,2 ;see if 2nd Lsd
goto Update2ndLsd ;yes then do 2nd lsd
UpdateLsd
movf LsdTime,W ;get Lsd in w
andlw 0x0f ; /
goto DisplayOut ;enable display
Update2ndLsd
call Chk2LsdZero ;msd = 0 & 2 lsd 0?
btfss STATUS,Z ;yes then skip
swapf LsdTime,W ;get 2nd Lsd in w
andlw 0x0f ;mask rest
goto DisplayOut ;enable display
Update3rdLsd
call ChkMsdZero ;msd = 0?
btfss STATUS,Z ;yes then skip
movf MsdTime,W ;get 3rd Lsd in w
andlw 0x0f ;mask low nibble
goto DisplayOut ;enable display
UpdateMsd
swapf MsdTime,W ;get Msd in w
andlw 0x0f ;mask rest
btfsc STATUS,Z ;msd != 0 then skip
movlw 0x0a
DisplayOut
call LedTable ;get digit output
movwf PORTB ;drive leds
movf TempC,W ;get sink value in w
movwf PORTA
return
;
;
LedTable
addwf PCL, F ;add to PC low
retlw B'00111111' ;led drive for 0
retlw B'00000110' ;led drive for 1
retlw B'01011011' ;led drive for 2
retlw B'01001111' ;led drive for 3
retlw B'01100110' ;led drive for 4
retlw B'01101101' ;led drive for 5
retlw B'01111101' ;led drive for 6
retlw B'00000111' ;led drive for 7
retlw B'01111111' ;led drive for 8
retlw B'01100111' ;led drive for 9
retlw B'00000000' ;blank led drive
;
;
Chk2LsdZero
call ChkMsdZero ;msd = 0?
btfss STATUS,Z ;yes then skip
return ;else return
swapf LsdTime,W ;get 2nd lsd
andlw 0x0f ;mask of LSD
btfss STATUS,Z ;0? then skip
return
retlw .10 ;else return with 10
;
ChkMsdZero
movf MsdTime,W ;get Msd in w
btfss STATUS,Z ;= 0? skip
return ;else return
retlw .10 ;ret with 10
;
;
;
count equ 26
temp equ 27
;
H_byte equ 20
L_byte equ 21
R0 equ 22 ; RAM Assignments
R1 equ 23
R2 equ 24
;
;
B2_BCD bcf STATUS,0 ; clear the carry bit
movlw .16
movwf count
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,3 ; test if result > 7
movwf 0
movlw 30
addwf 0,W
movwf temp
btfsc temp,7 ; test if result > 7
movwf 0 ; save as MSD
RETLW 0
;
;
end
;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -