Testo esercizio:
Realizzare un sistema a microcontrollore con il PIC6F877A con le seguenti caratteristiche:
3 pulsanti/interruttori (S1, S2 e S3) e 2 diodi LED (DL1 e DL2). Decidi tu i pin I/O e il nome di eventuali variabili.
S1 (pulsante N.O. con R di pull-down) se premuto 4 volte accende DL1 (diodo LED alimentato con corrente di Sink);
S2 (pulsante N.O. con R di pull-down) se premuto 2 volte spegne DL1;
S3 (interruttore N.C. con R di pull-up) se premuto impedisce il cambio di stato di DL1 e segnala il suo stato di pressione accendendo DL2 (diodo LED alimentato con corrente di Sink);
schema:
diagramma di flusso:
sorgente in assembler:
; definizione dei pin del microcontrollore
;
; INGRESSI
; RA0 : pulsante S1 se premuto 4 volte accende DL1
; RA1 : pulsante S2 se premuto 2 volte spegne DL1
; RA2 : interruttore S3 se premuto N-dispari accende DL2 e impedisce lettura S1 e S2
; USCITE
; RB6 : diodo led DL1 si accende con '0'
; RB7 : diodo led DL2 si accende con '0'
;
#INCLUDE "p16F877A.inc"
LIST P=16F877A, F=INHX8M
__CONFIG 0X3F3A
;
; definizione delle variabili e abbinamento delle stesse alla locazione RAM
; nome delle variabili max 6 caratteri
CONT1 EQU 20H;
CONT2 EQU 21H;
RIT1 EQU 22H;
RIT2 EQU 23H;
;
;
ORG 00 ; scrive il programma dalla locazione 0 della program memory
GOTO INIZIO ; salta subroutine di interrupt
; subroutine che viene eseguita in caso di interrupt
ORG 04 ; INDIRIZZO SUBROUTINE INTERRUPT
;
;
;
RETFIE ; RITORNA AL PUNTO IN CUI L'INTERRUPT E' STATO ATTIVATO
;
INIZIO:
; questo codice viene eseguito quando il sistema viene alimentato o dopo un reset manuale
; imposto i pin I/O
BCF STATUS,6; passo al bank 1
BSF STATUS,5;
;
MOVLW 0x3F;
MOVWF TRISB;
MOVLW 0xFF;
MOVWF TRISA;
MOVWF TRISC;
MOVWF TRISD;
MOVWF TRISE;
;
BCF STATUS,5; passo al bank 0
CLRF CONT1; resetto contenuto variabili
CLRF CONT2;
;
MAIN:
BTFSS PORTB,2; vedo se S3 è premuto N-dispari
GOTO S1;
BCF PORTB,7; accendo DL2
GOTO MAIN;
;
S1:
BSF PORTB,7; spengo DL2
BTFSS PORTB,0; vedo se S1 è premuto
ANTS1:
BTFSC PORTB,0; creo loop fino a che tengo premuto S1
GOTO ANTS1;
CALL DELAY; ritardo 100 ms per impulsi spurii
GOTO S2; vado a leggere il puls. S2
INCF CONT1,1; incremento cont1 ad ogni pressione di S1
BTFSS CONT1,2; se a '1' è arrivato a 4
GOTO MAIN;
BCF PORTB,6; accendo DL1
GOTO AZZ; chiamo subroutine che azzera variabili
;
S2:
BTFSS PORTB,1; vedo se S2 è premuto
ANTS2:
BTFSC PORTB,1; creo loop fino a che tengo premuto S2
GOTO ANTS2;
CALL DELAY; ritardo 100 ms per impulsi spurii
GOTO MAIN;
INCF CONT2,1; incremento CONT2
BTFSS CONT2,1; controllo se arrivato a 2
GOTO MAIN;
BSF PORTB,6; spengo DL1
GOTO AZZ;
;
;subroutine che azzera le variabili
AZZ:
CLRF CONT1;
CLRF CONT2;
GOTO MAIN;
;
; 3 C.M. (ciclo macchina) x 256 x 256 x 0,5 ms
; 1 C.M. 0,5 us (microsecondi)
DELAY:
CLRF RIT1;
CLRF RIT2;
DELAY1:
DECFSZ RIT1,1;
GOTO DELAY1;
DECFSZ RIT2,1;
GOTO DELAY1;
RETURN;
END