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

📄 mplxad.asm

📁 四通道的AD采样转换数据
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*********************************************************************
;This program is to demonstrate how to multiplex four 7 segment LED
;digits and a 4X4 keypad along with 4 A/D inputs using a PIC16C71. 
;The four digits will first display the decimal a/d value of ch0.
;When keys from 0 - 3 are hit the corresponding channel's a/d value
;is displayed in decimal.
;The LEDs are updated every 20mS, the keypad is scanned at a rate of 20 mS.
;All 4 channels are scanned at 20mS rate, so each channel gets scanned 
;every 80mS. A faster rate of scanning is possible as required by
;the users application.
;The RTCC timer is used in internal interrupt mode to generate the
;5 mS.
;
;                                       Stan D'Souza 5/8/93
;
;Corrected error in display routine.
;                                       Stan D'Souza 2/27/94
;
;       Program:          MPLXAD.ASM 
;       Revision Date:   
;                         1-15-97      Compatibility with MPASMWIN 1.40
;
;**********************************************************************
        LIST P=16C71
        ERRORLEVEL  -302
;
        include      <p16c71.inc>
;
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
;
Flag    equ     0x12            ;general purpose flag reg
#define keyhit  Flag,0          ;bit 0 --> key-press on
#define DebnceOn Flag,1         ;bit 1 -> debounce on
#define noentry Flag,2          ;no key entry = 0 
#define ServKey Flag,3          ;bit 3 --> service key
#define ADOver  Flag,4          ;bit 4 --> a/d conv. over
;
Debnce  equ     0x13            ;debounce counter
NewKey  equ     0x14
DisplayCh equ   0x15            ;channel to be displayed
;
ADTABLE equ     0x16            ;4 locations are reserved here
                                ;from 0x16 to 0x19
;
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    InitAd
        call    InitTimers
loop
        btfsc   ServKey         ;key service pending
        call    ServiceKey      ;yes then service
        btfsc   ADOver          ;a/d pending?
        call    ServiceAD       ;yes the service a/d
        goto    loop
;
;ServiceKey, does the software service for a keyhit. After a key service,
;the ServKey flag is reset, to denote a completed operation.
ServiceKey
        bcf     ServKey         ;reset service flag
        movf    NewKey,W        ;get key value
        sublw   3               ;key > 3?
        btfss   STATUS,C        ;no then skip
        return                  ;else ignore key
        movf    NewKey,W
        movwf   DisplayCh       ;load new channel
;
LoadAD
        movlw   ADTABLE         ;get top of table
        addwf   DisplayCh,W     ;add offset
        movwf   FSR             ;init FSR
        movf    0,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
        return
;
;This rountine essentially loads the ADRES value in the table location
;determined by the channel offset. If channel 0 then ADRES is saved
;in location ADTABLE. If channel 1 then ADRES is saved at ADTABLE + 1.
;and so on.
ServiceAD
        movf    ADCON0,W        ;get adcon0
        movwf   TempC           ;save in temp
        movlw   B'00001000'     ;select next channel
        addwf   ADCON0,W        ;       /
        btfsc   ADCON0,5        ;if <= ch3
        movlw   B'11000001'     ;select ch0
        movwf   ADCON0
        ;now load adres in the table
        movlw   ADTABLE
        movwf   FSR             ;load FSR with top
        rrf     TempC, F
        rrf     TempC, F
        rrf     TempC,W         ;get in w reg
        andlw   3               ;mask off all but last 2
        addwf   FSR, F          ;add offset to table
        movf    ADRES,W         ;get a/d value
        movwf   0               ;load indirectly
        bcf     ADOver          ;clear flag
        call    LoadAD          ;load a/d value in display reg.
        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         ;       /
        clrf    DisplayCh       ;show channel 0
        clrf    Flag            ;clr all flags
        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                  
;        
ServiceInterrupts
        btfsc   INTCON,T0IF     ;rtcc interrupt?
        goto    ServiceTMR0     ;yes then service
        clrf    INTCON          ;else clr all int
        bsf     INTCON,T0IE
        return
;
ServiceTMR0
        movlw   .96             ;initialize rtcc
        movwf   TMR0            
        bcf     INTCON,T0IF     ;clr int flag
        btfsc   PORTA,0        ;scan keys every 20 mS
        call    ScanKeys        ;when digit 1 is on
        btfsc   PORTA,3        ;scan a/d every 20mS 
        call    SampleAd        ;when digit 4 is on 
        call    UpdateDisplay   ;update display
        return                  
;
;
;ScanKeys, scans the 4X4 keypad matrix and returns a key value in
;NewKey (0 - F) if a key is pressed, if not it clears the keyhit flag.
;Debounce for a given keyhit is also taken care of.
;The rate of key scan is 20mS with a 4.096Mhz clock.
ScanKeys
        btfss   DebnceOn        ;debounce on?
        goto    Scan1           ;no then scan keypad
        decfsz  Debnce, F       ;else dec debounce time
        return                  ;not over then return
        bcf     DebnceOn        ;over, clr debounce flag
        return                  ;and return
Scan1                           
        call    SavePorts       ;save port values
        movlw   B'11101111'     ;init TempD
        movwf   TempD
ScanNext
        movf    PORTB,W        ;read to init port
        bcf     INTCON,RBIF     ;clr flag
        rrf     TempD, F        ;get correct column
        btfss   STATUS,C        ;if carry set?
        goto    NoKey           ;no then end
        movf    TempD,W         ;else output
        movwf   PORTB          ;low column scan line
        nop
        btfss   INTCON,RBIF     ;flag set? 
        goto    ScanNext        ;no then next
        btfsc   keyhit          ;last key released?
        goto    SKreturn        ;no then exit
        bsf     keyhit          ;set new key hit
        swapf   PORTB,W        ;read port        
        movwf   TempE           ;save in TempE
        call    GetKeyValue     ;get key value 0 - F
        movwf   NewKey          ;save as New key
        bsf     ServKey         ;set service flag
        bsf     DebnceOn        ;set flag
        movlw   4
        movwf   Debnce          ;load debounce time
SKreturn
        call    RestorePorts    ;restore ports
        return
;
NoKey
        bcf     keyhit          ;clr flag
        goto    SKreturn
;        
;GetKeyValue gets the key as per the following layout
;
;                  Col1    Col2    Col3    Col3       
;                  (RB3)   (RB2)   (RB1)   (RB0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -