嵌入式学习小组
直播中

李大帅

7年用户 161经验值
私信 关注

如何利用单个PIC输入监控15个触点?

利用单个PIC输入监控15个触点

回帖(1)

陈妙宙

2021-4-2 16:35:42
作为一个简单实用的示例,图1中的电路利用一个8位PIC微控制器控制一个4位LED显示器,显示出按下了哪个按钮。当任意按钮被按下时,比较器中断程序会立即作出响应。该程序会在VREF值之间进行循环,直至比较器输出COUT返回高电平,表明该按钮被按下。完整注释的汇编程序源代码总共不到100字。该代码并未作过度优化,从而可方便理解或易于转化到其他控制器上。




汇编程序源代码:
; MULTIBTN.ASM: sensing upto 15 pushbuttons with one I/O (pin6: GP1/CIN-)
; BENABADJI Noureddine - ORAN - Dec. 11...14th, 2013
;
        Errorlevel -302                ; avoid warning #302: Register in operand not in bank0.
                                                ; Ensure that bank bits are correct.
        List P = 12F683                     
#include "p12f683.inc"                        
        __CONFIG    _INTOSCIO&_MCLRE_OFF&_PWRTE_ON&_WDT_OFF&_FCMEN_OFF&_IESO_OFF&_BOD_ON&_CPD_OFF&_CP_OFF
#define         LED1        GPIO, 0        ; output bit0 of the 4-bit binary LED display
#define         LED2        GPIO, 2        ; output bit1 of the 4-bit binary LED display
#define         LED3        GPIO, 4        ; output bit2 of the 4-bit binary LED display
#define         LED4        GPIO, 5        ; output bit3 of the 4-bit binary LED display
;----------------------------- define variables ------------------------------
        CBLOCK        0x20        ; bank0 = [0x20...0x7F] = 94 bytes
;delay
        cnt1, cnt2, cnt3 ; counters
        ENDC
;------------------------------------------------------------------------------
BANK0        macro
        BCF        STATUS, RP0                 ; bank0
        endm
;------------------------------------------------------------------------------
BANK1        macro
        BSF        STATUS, RP0                 ; bank1
        endm
;------------------------------------------------------------------------------
SIregGEval8b        macro        file, val, jmpOk        ; if (file >= val) goto jmpOk ;
        MOVLW        val
        SUBWF        file, w                ; w = file - val
        BTFSC        STATUS, C
        GOTO        jmpOk                ; yes
        endm
;/////////////////////////////////////////////////////////////////////////////
;        MAIN PROGRAM
;/////////////////////////////////////////////////////////////////////////////
        ORG                0x00                        ; reset vector
        GOTO        Setup
        ORG                0X04                        ; interrupt vector
        GOTO        IntCmp
;/////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
LEDsOFF
        CALL        Delay256ms
        CLRF        GPIO        ; all LEDs off
        RETLW        0
;-----------------------------------------------------------------------------
Delay256ms
        CLRF        cnt2
        CLRF        cnt1
        NOP                                ; 1us
        DECFSZ        cnt1, f        ; 1us
        GOTO        $-2                ; 2us => 4*256 = 1024 us, approx. 1 ms internal delay loop
        DECFSZ        cnt2, f        ; approx. 256 ms external delay loop
        GOTO        $-4
        RETLW        0
;/////////////////////////////////////////////////////////////////////////////
Setup
        BANK1
        CLRF        TRISIO                 ; config. all I/O as outputs
        BCF        OPTION_REG, T0CS ; use pin5 as GP2, not TOCKI
        CLRF        ANSEL                 ; use all AN as digital I/O
        BANK0
        CLRF        GPIO                ; all LEDs off
        MOVLW        b'00000111'
        MOVWF        CMCON0                 ;comparator off
splash ; (initial test for LEDs)
        BSF                LED1
        CALL        LEDsOFF
        BSF                LED2
        CALL        LEDsOFF
        BSF                LED3
        CALL        LEDsOFF
        BSF                LED4
        CALL        LEDsOFF
;;;;;;;;;;
initializeComparator
        BANK1
        MOVLW        b'00001010'         ;config. GP1 as input (will be CIN-)
        MOVWF        TRISIO
        ;BANK0
        MOVLW        b'10100001'
        ;BANK1
        MOVWF        VRCON                 ;Vref on, low range, VR=0001 => ratio = 1/24
        BANK0
        MOVLW        b'00000100'
        MOVWF        CMCON0                 ;comparator on: CIN- = GP1; CIN+ = Vref; Cout internal
;;;;;;;;;
      
;enable interrupt
        BANK1
        BSF        INTCON, PEIE         ; enable interrupt on Comparator trip
        BSF        PIE1, CMIE                 ; enable interrupt on Comparator trip
        BANK0
        BSF        INTCON, GIE                 ; set general interrupt enable
        goto $                                 ; infinite loop (waiting for an interrupt)
;-----------------------------------------------------------------------------
; Comparator trip interrupt routine
;-----------------------------------------------------------------------------
IntCmp
;don't need to save any context, only interrupting a goto $
        BANK0
        MOVLW        .1
        MOVWF        cnt3
nextBtn
        INCF        cnt3, F
        SIregGEval8b cnt3, .16, whichBtn ; if (cnt3 >= 16) goto whichBtn ;
        MOVLW        b'10100000'
        ADDWF        cnt3, W
        BANK1
        MOVWF        VRCON                 ;Vref on, low range, VR=cnt3
        BANK0
        BTFSS        CMCON0, COUT         ; Cout == 1 ?
        GOTO        nextBtn
whichBtn
        DECF        cnt3, F
        BTFSC        cnt3, 0
        BSF                LED1
        BTFSC        cnt3, 1
        BSF                LED2
        BTFSC        cnt3, 2
        BSF                LED3
        BTFSC        cnt3, 3
        BSF                LED4
        CALL        LEDsOFF
      
endIntCmp
        MOVLW        b'10100001'
        BANK1
        MOVWF        VRCON                 ;Vref on, low range, VR=0001 => ratio = 1/24
        BANK0
        BCF        PIR1, CMIF                 ; clear comparator interrupt flag
        RETFIE
;-----------------------------------------------------------------------------
举报

更多回帖

发帖
×
20
完善资料,
赚取积分