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

📄 mplxkey.asm

📁 四通道的AD采样转换数据
💻 ASM
字号:
;*********************************************************************
;This program is to demonstrate how to multiplex four 7 segment LED
;digits and a 4X4 keypad using a PIC16C71. 
;The four digits will start as '0000' and when a key is hit
;it is displayed on the 7 segment leds as a hex value 0 to F. The last
;digit hit is always displayed on the right most led with the rest of
;the digits shifted to the left. The left most digit is deleted.
;The LEDs are updated every 20mS, the keypad is scanned at a rate of 20 mS.
;The RTCC timer is used in internal interrupt mode to generate the
;5 mS.
;
;                                       Stan D'Souza 5/8/93
;
;       Program:          MPLXKEY.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
KeyFlag equ     0x12            ;flags related to key pad
keyhit  equ     0       ;bit 0 --> key-press on
DebnceOn equ    1       ;bit 1 --> debounce on
noentry equ     2       ;no key entry = 0 
ServKey equ     3       ;bit 3 --> service key
Debnce  equ     0x13            ;debounce counter
NewKey  equ     0x14
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
loop
        btfsc   KeyFlag,ServKey ;key service pending
        call    ServiceKey      ;yes then service
        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
        movf    NewKey,W        ;get key value
        movwf   TempE           ;save in TempE
        swapf   MsdTime,W       ;move MSD out
        andlw   B'11110000'     ;clr lo nibble
        movwf   MsdTime         ;save back
        swapf   LsdTime,W       ;get Lsd
        andlw   B'00001111'     ;mask off lsd
        iorwf   MsdTime, F      ;and left shift 3rd
        swapf   LsdTime,W       ;get Lsd again
        andlw   B'11110000'     ;mask off 2nd
        iorwf   TempE,W         ;or with new lsd
        movwf   LsdTime         ;make Lsd
        bcf     KeyFlag,ServKey ;reset service 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         ;       /
        clrf    KeyFlag         ;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        ;if msb on then do
        call    ScanKeys        ;do a quick key scan
        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   KeyFlag,DebnceOn ;debounce on?
        goto    Scan1           ;no then scan keypad
        decfsz  Debnce, F       ;else dec debounce time
        return                  ;not over then return
        bcf     KeyFlag,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   KeyFlag,keyhit  ;last key released?
        goto    SKreturn        ;no then exit
        bsf     KeyFlag,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     KeyFlag,ServKey ;set service flag
        bsf     KeyFlag,DebnceOn ;set flag
        movlw   4
        movwf   Debnce          ;load debounce time
SKreturn
        call    RestorePorts    ;restore ports
        return
;
NoKey
        bcf     KeyFlag,keyhit  ;clr flag
        goto    SKreturn
;        
;GetKeyValue gets the key as per the following layout
;
;                  Col1    Col2    Col3    Col3       
;                  (RB3)   (RB2)   (RB1)   (RB0)
;
;Row1(RB4)           0       1       2       3
;
;Row2(RB5)           4       5       6       7
;
;Row3(RB6)           8       9       A       B
;
;Row4(RB7)           C       D       E       F
;
GetKeyValue
        clrf    TempC
        btfss   TempD,3         ;first column
        goto    RowValEnd
        incf    TempC, F
        btfss   TempD,2         ;second col.
        goto    RowValEnd
        incf    TempC, F
        btfss   TempD,1         ;3rd col.
        goto    RowValEnd
        incf    TempC, F        ;last col.
RowValEnd
        btfss   TempE,0         ;top row?
        goto    GetValCom       ;yes then get 0,1,2&3
        btfss   TempE,1         ;2nd row?
        goto    Get4567         ;yes the get 4,5,6&7
        btfss   TempE,2         ;3rd row?
        goto    Get89ab         ;yes then get 8,9,a&b
Getcdef
        bsf     TempC,2         ;set msb bits   
Get89ab
        bsf     TempC,3         ;       /
        goto    GetValCom       ;do common part
Get4567
        bsf     TempC,2
GetValCom
        movf    TempC,W
        addwf   PCL, F
        retlw   0
        retlw   1
        retlw   2
        retlw   3
        retlw   4
        retlw   5
        retlw   6
        retlw   7
        retlw   8
        retlw   9
        retlw   0a
        retlw   0b
        retlw   0c
        retlw   0d
        retlw   0e
        retlw   0f
;
;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
Update2ndLsd        
        swapf   LsdTime,W       ;get 2nd Lsd in w
        andlw   0x0f            ;mask rest
        goto    DisplayOut      ;enable display
Update3rdLsd
        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
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'01110111'     ;led drive for A
        retlw   B'01111100'     ;led drive for b
        retlw   B'00111001'     ;led drive for C
        retlw   B'01011110'     ;led drive for d
        retlw   B'01111001'     ;led drive for E
        retlw   B'01110001'     ;led drive for F

;
;

        end
;

        

⌨️ 快捷键说明

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