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