;********************************************************************** ; Title: Push-Button * * ; Filename: f684code.asm * ; Date: 28.01.2007 * ; Author: Stefan Bracher (http://stefan.bracher.info) * ;********************************************************************** ; A simple push-button LED switch. First time the button is * ; pressed, the LED goes on, the second time it goes off... * ; * ; Could be used to control the light in a room with several * ; switches in parallel. (Of course some additional circuitry * ; for the power part would be needed) * ;********************************************************************** list p=16f684 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The labels following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;***** VARIABLE DEFINITIONS w_temp EQU 0x71 ; variable used for context saving status_temp EQU 0x72 ; variable used for context saving temp equ 0x25 ; Temporary variable pa5_in equ 0x26 ; Input PA5 pa5_in_old equ 0x27 ; Input PA5(@ t=t-1) my_status equ 0x28 ; myStatus (1=on, 0=off) ;******MACROS**************** BANK1 MACRO BSF STATUS, RP0 ;MACRO TO SELECT BANK 1 ENDM BANK0 MACRO BCF STATUS, RP0 ;MACRO TO SELECT BANK 0 ENDM ;********************************************************************** ORG 0x000 ; processor reset vector (here the PIC starts) BANK0 ; Change to Bank 0 MOVLW 0h ; w=0h MOVWF pa5_in ; pa5_in=w (=0h) MOVWF pa5_in_old ; pa5_in_old=w (=0h) MOVWF my_status ; my_status=w (=0h) call port_con ; Call Function port_con goto MAIN ;******FUNCTIONS**************** port_con BANK0 ; Change to Bank0 (where PORTA and CMCONO are stored) CLRF PORTA ; Clear PORTA MOVLW B'00000111' ; w=B'00000111' MOVWF CMCON0 ; CMCONO=w (=B'00000111' -> COMPARATORS ARE OFF) BANK1 ; Change to Bank1 (where ANSEL and TRISA are stored) CLRF ANSEL ; clear ANSEL -> set digital I/O MOVLW B'00101000' ; B'00100000' MOVWF TRISA ; TRISA=w (=B'00101000' -> RA0, RA1, RA2, RA4=output) BANK0 ; Change to Bank0 retlw 0 ; Return with w=0 Turn_on MOVLW B'00001' ; w=B'00001' MOVWF PORTA ; PORTA=w (=B'00001' -> RA0 high) RETURN Turn_off MOVLW B'000000' ; w=B'00000' MOVWF PORTA ; PORTA=w (=B'00000' -> all low) RETURN READ_PORTA BTFSC PORTA, 5 ; If bit 5 in PORTA is 1 MOVLW 01h ; w=01h BTFSS PORTA, 5 ; If bit 5 in PORTA is 0 MOVLW 00h ; w=00h MOVWF pa5_in; ; pa5_in=w (-> write the input in RA5 in pa5_in) RETURN Status_OFF call Turn_off ; turn light off MOVLW 01h ; w=1 BTFSC temp, 0 ; if temp==1 MOVWF my_status ; my_status=w (=1) BTFSC temp, 0 ; if temp==1 MOVLW 00h ; w=0 BTFSC temp, 0 ; if temp==1 MOVWF temp ; temp=w (=0) (to avoid doublechanges of status) RETURN Status_ON call Turn_on ; turn light on MOVLW 00h ; w=0 BTFSC temp, 0 ; if temp==1 MOVWF my_status ; status=w (=0) BTFSC temp, 0 ; if temp==1 MOVWF temp; ; temp=w (=0) (to avoid doublechanges of status) RETURN ;**************************************************************************** ;****MAIN**************************************************************** MAIN call READ_PORTA ; Read PORTA (the input in RA5 is stored in pa5_in, see function READ_PORTA) MOVFW pa5_in_old ; w=pa5_in_old SUBWF pa5_in, 0 ; w=pa5_in-pa5_in_old MOVWF temp ; temp=w BTFSC temp, 1 ; if (temp==255)or(temp==2) MOVLW 00h ; w=0 MOVWF temp ; temp=w (-> temp=1 if the button is pressed down) BTFSS my_status, 0 ; If (Status==0) call Status_OFF ; BTFSC my_status, 0 ; If (Status==1) call Status_ON ; MOVFW pa5_in ; w=pa5_in MOVWF pa5_in_old ; pa5_in_old=w goto MAIN END ; directive 'end of program'