⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mplxch0.asm

📁 四通道的AD采样转换数据
💻 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 + -