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

📄 elmp.asm

📁 pic单片机对红外设备控制得一个源程序
💻 ASM
字号:
; ELMP PIC code *bugfixed version*
; cyrano@algonet.se

; This code will scan a 4x4 keypad and transmit "scan-codes" when a key is
; pressed or released (at 9600bps, 8N1). It will also handle the power relay
; when standby mode is used, and hopefully some day it will handle RC5 code
; for IR remote controls...
;
; No voltage converter (such as MAX232) is needed, a "1" is sent as 0v and
; a "0" is sent as 5v, this will be accepted by most modern motherboards..

; 9600bps serial send code: done!
; Keypad scanning code: done! and fixed  :-)
; Standby handling code: not done
; IR remote code: not done


        PROCESSOR 16C84

; pins...

#define serdatapin PORTA,3
#define IRdatapin PORTA,4
#define relaypin PORTA,2

#define trisb_keyrow1 H'EF'
#define trisb_keyrow2 H'DF'
#define trisb_keyrow3 H'BF'
#define trisb_keyrow4 H'7F'

#define keycol1 PORTB,0
#define keycol2 PORTB,1
#define keycol3 PORTB,2
#define keycol4 PORTB,3

; Standard Register Files...

TMR0    equ     H'01'
PCL     equ     H'02'
STATUS  equ     H'03'
FSR     equ     H'04'
PORTA   equ     H'05'
PORTB   equ     H'06'
EEDATA  equ     H'08'
EEADR   equ     H'09'
PCLATH  equ     H'0A'
INTCON  equ     H'0B'
OPTION_ equ     H'81'
TRISA   equ     H'85'
TRISB   equ     H'86'
EECON1  equ     H'88'
EECON2  equ     H'89'

; User defined variables...

W_TEMP  equ     H'0C'
S_TEMP  equ     H'0D'

BITCNT  equ     H'0E'
SERBYTE equ     H'0F'

COUNT   equ     H'10'

KEYS1   equ     H'11'
KEYS2   equ     H'12'
TMPKEY  equ     H'13'

TEMP    equ     H'14'
TEMP2   equ     H'15'



; Macros....

#define bank0   bcf STATUS,5    ;select bank 0 (clear bit 5 of STATUS reg.)
#define bank1   bsf STATUS,5    ;select bank 1 (set bit 5 of STATUS reg.)


; Code starts here ---------------------------------------------------

        ORG     0               ; Main program start vector
        GOTO    start           ; Jump to the code!

; ISR (Interrupt Service Routine)

        ORG     4
        MOVWF   W_TEMP          ; Save working reg. (W)
        SWAPF   STATUS, W       ; Copy STATUS reg to W and swap nibbles
        MOVWF   S_TEMP          ; Save STATUS register

        bank0

        MOVLW   H'A0'           ; load a "magic number" into TMR0
        MOVWF   TMR0

;        BTFSC   serdatapin     ; this simple test code will generate
;        GOTO    clearit        ; infinite "010101...". Good for testing
;setit   BSF     serdatapin     ; If all settings are correct, this should
;        GOTO    done           ; be recieved as a bunch of "U" at the PC.
;clearit BCF     serdatapin     ; If you get some "U" and some other chars,
;done                           ; baudrate is slightly off, adjust "magic"

; comment the code below if you uncomment the test code

        MOVF    BITCNT,W
        BTFSC   STATUS,2        ; test zero flag
        GOTO    done            ; just skip ahead
        SUBLW   1               ; is it time for the start bit (bit 0x01)?
        BTFSC   STATUS,2        ; let's find out!
        GOTO    strtbit
        MOVF    BITCNT,W
        SUBLW   H'A'            ; is it time for the stop bit (bit 0x0A)?
        BTFSC   STATUS,2        ; let's find out!
        GOTO    stopbit

        INCF    BITCNT
        RRF     SERBYTE,F       ; it's data byte time!
        BTFSC   STATUS,0        ; our data bit is now in the carry
        GOTO    clearit
        GOTO    setit

strtbit INCF    BITCNT          ; start bit done, next time data!
setit   BSF     serdatapin      ; output 5v (RS-232 "0")
        GOTO    done
stopbit CLRF    BITCNT          ; we're ready for another byte
clearit BCF     serdatapin      ; output 0v (RS-232 "1")
done

; end comment

        BCF     INTCON,2        ; clear (timer) interrupt flag
        SWAPF   S_TEMP, W       ; Swap saved STATUS back into W
        MOVWF   STATUS          ; Put it back in STATUS reg.
        SWAPF   W_TEMP, F       ; Swap nibbles of W_TEMP
        SWAPF   W_TEMP, W       ; Again, this time placing the result in W
        RETFIE                  ; Return from ISR
 
; XMIT
; Put a byte into W and call this to transmit it, check that BITCNT is 0 first

xmit    MOVWF   SERBYTE         ; put the byte in the "buffer"
        CLRF    BITCNT
        INCF    BITCNT          ; set BITCNT = 1 (start transmit!)
        RETURN


start   CLRF    BITCNT          ; don't send anything just yet...
        bank1                   
        CLRF    TRISB^80H       ; Make PORTB all outputs
        DECF    TRISB^80H       ; Make PORTB all inputs
        BCF     serdatapin      ; set serial data pin to output
        BSF     IRdatapin       ; set IR remote pin to input
        BCF     relaypin        ; power relay control pin = output!
        bank0
        MOVLW   H'FF'           
        MOVWF   PORTB           ; Make PORTB all ones
        BSF     serdatapin      ; idle state
        BCF     relaypin        ; set it low to turn on the relay

        bank1
        MOVLW   B'10001000'
        MOVWF   OPTION_^80H     ; timer 0 internal clock 1:1, pullup disabled
        bank0

        BSF     INTCON,5        ; enable timer interrupt      
        BSF     INTCON,7        ; globally allow interrupts

        CLRF    KEYS1           ; All 16 keys released to start with
	CLRF	KEYS2

; Below comes some pretty ugly code, but it does work so I leave it alone :-)

loop

        CLRF    TMPKEY
        CLRF    TEMP

        bank1
        MOVLW   trisb_keyrow1
        MOVWF   TRISB^80H       ; row 1 of keypad active
        bank0
        BTFSC   keycol1         ; check key (1,1)
        BSF     TMPKEY,0
        BTFSC   keycol2         ; check key (2,1)
        BSF     TMPKEY,1
        BTFSC   keycol3         ; etc...
        BSF     TMPKEY,2
        BTFSC   keycol4
        BSF     TMPKEY,3

        bank1
        MOVLW   trisb_keyrow2
        MOVWF   TRISB^80H       ; row 2 of keypad active
        bank0
        BTFSC   keycol1         ; check key (1,2)
        BSF     TMPKEY,4
        BTFSC   keycol2         ; check key (2,2)
        BSF     TMPKEY,5
        BTFSC   keycol3         ; etc...
        BSF     TMPKEY,6
        BTFSC   keycol4
        BSF     TMPKEY,7

        MOVF    TMPKEY,W        ; save the keys, so we can update KEYS1
        MOVWF   TEMP2
        MOVF    KEYS1,W
        XORWF   TMPKEY,F
        BTFSC   STATUS,2
        GOTO    same1           ; zero flag set = no change on first 8 keys

keylp1  RRF     TMPKEY,F        
        BTFSS   STATUS,0
        GOTO    skip1
        RRF     KEYS1,F
        BTFSC   STATUS,0
        GOTO    clear1
        BSF     STATUS,0
        BSF     TEMP,4
        GOTO    invdne1
clear1  BCF     STATUS,0
invdne1 RLF     KEYS1,F

wait1   MOVF    BITCNT,W
        BTFSS   STATUS,2
        GOTO    wait1
        MOVF    TEMP,W
        CALL    xmit
        BCF     TEMP,4
skip1   RRF     KEYS1,F
        INCF    TEMP
        MOVLW   8
        SUBWF   TEMP,W
        BTFSS   STATUS,2
        GOTO    keylp1
        MOVF    TEMP2,W
        MOVWF   KEYS1
same1
	MOVLW	H'08'
	MOVWF	TEMP
        CLRF    TMPKEY
        bank1
        MOVLW   trisb_keyrow3
        MOVWF   TRISB^80H       ; row 3 of keypad active
        bank0
        BTFSC   keycol1         ; check key (1,3)
        BSF     TMPKEY,0
        BTFSC   keycol2         ; check key (2,3)
        BSF     TMPKEY,1
        BTFSC   keycol3         ; etc...
        BSF     TMPKEY,2
        BTFSC   keycol4
        BSF     TMPKEY,3

        bank1
        MOVLW   trisb_keyrow4
        MOVWF   TRISB^80H       ; row 4 of keypad active
        bank0
        BTFSC   keycol1         ; check key (1,4)
        BSF     TMPKEY,4
        BTFSC   keycol2         ; check key (2,4)
        BSF     TMPKEY,5
        BTFSC   keycol3         ; etc...
        BSF     TMPKEY,6
        BTFSC   keycol4
        BSF     TMPKEY,7

        MOVF    TMPKEY,W
        MOVWF   TEMP2
        MOVF    KEYS2,W
        XORWF   TMPKEY,F
        BTFSC   STATUS,2
        GOTO    same2           
keylp2  RRF     TMPKEY,F
        BTFSS   STATUS,0
        GOTO    skip2
        RRF     KEYS2,F
        BTFSC   STATUS,0
        GOTO    clear2
        BSF     STATUS,0
        BSF     TEMP,4
        GOTO    invdne2
clear2  BCF     STATUS,0
invdne2 RLF     KEYS2,F

wait2   MOVF    BITCNT,W
        BTFSS   STATUS,2
        GOTO    wait2
        MOVF    TEMP,W
        CALL    xmit
        BCF     TEMP,4
skip2   RRF     KEYS2,F
        INCF    TEMP
        MOVLW   16
        SUBWF   TEMP,W
        BTFSS   STATUS,2
        GOTO    keylp2
        MOVF    TEMP2,W
        MOVWF   KEYS2
same2


        goto loop


        END

⌨️ 快捷键说明

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