Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

6
voti

Lampeggio led tramite Timer Interrupt - Parte 4

Indice

Introduzione

Questa è la quarta ed ultima parte dell'articolo Lampeggio led tramite Timer Interrupt.

Non lampeggia

Come ho scritto nell'ultima frase della terza parte dell'articolo, mi trovavo di fronte ad un led semiacceso, eppure mi sembrava di avere scritto correttamente il codice!
In MPLAB X IDE apro le proprietà del progetto, e nella configurazione seleziono in Hardware Tools la voce Simulator anzichè PICkit3 per provare a simulare il funzionamento del programma.
Metto alcuni breakpoint nel codice per far fermare l'esecuzione del programma e dare un'occhiata alle variabili e ai registri prima di ripartire: il codice funziona bene.

Cosa c'è allora che non fa funzionare il circuito nella pratica?

La soluzione

Il giorno seguente, mentre sistemo un po' le finestre in Firefox dove tengo aperti i siti che sto consultando per imparare la programmazione dei PIC, la mia attenzione viene catturata da un Webinar (abbreviazione di Web Seminar, seminario on-line) della Microchip intitolato "Flash, Damned LED! Flash I say!" (lampeggia, dannato led! Lampeggia ho detto!).

Faccio partire il video ed il relatore Jeff O'Keefe spiega che affronterà i comuni errori commessi dai principianti per far lampeggiare un led.
Non ero molto fiducioso di incontrare la soluzione al mio problema, e invece...

Chi controlla il pin

Chi controlla il pin

Il video arriva alla quarta slide che richiama dei concetti che già conoscevo, ma che non avevo a quanto pare ben assimilato.
Anche in questo caso il problema e la relativa soluzione erano banali! Non mi ero ricordato che i pin spesso svolgono più di una funzione e sono condivisi da più periferiche, sono multiplexati.

In particolare il pin RA0 scelto da me per collegare il led, svolge sia la funzione di ingresso/uscita digitale RA0, sia la funzione di ingresso/uscita analogico AN0. Per configurare correttamente questo pin dovevo agire su un secondo registro, oltre che sul noto TRIS: si tratta del registro ADCON1, ossia uno dei due registri usati per configurare il convertitore analogico/digitale. Come suggerisce la slide del seminario, con l'istruzione ADCON1 = 0b00000110; si impostano tutti i pin disponibili per il convertitore A/D come ingressi/uscite digitali.

Aggiungo in fretta quest'istruzione al mio codice, reimposto il programmatore PicKit3 e carico il programma sul mio PIC16F87. Ed ecco il led che lampeggia! Poi provo a cambiare il valore del TempoLampeggio e noto che funziona bene, il led lampeggia più o meno brevemente a seconda del valore. Finalmente ho realizzato quello che volevo.

Codice finale

#include <xc.h>

//DEFINE
#define TempoLampeggio 500
#define Led            PORTAbits.RA0


// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF         // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ON         // FLASH Program Memory Write Enable (Unprotected program memory may be written to by EECON control)

//VARIABILI
unsigned int Tempo = 0;

void main(void) {
    //IMPOSTAZIONE PORTE INPUT/OUTPUT
    //PORTA is a 6-bit wide, bi-directional port.
    TRISA = 0;
    TRISB = 0;
    TRISC = 0;
    //IMPOSTAZIONE PORTE: TUTTE DIGITALI
    ADCON1 = 0b00000110;

    //ACCENSIONE Led
    Led = 1;

    //IMPOSTARE PRESCALER
    // Generato da PicTimer 1.0.1.0
    // © Bernardo Giovanni - www.settorezero.com
    // Codice valido per Hitec-C

    // Fosc           :4MHz
    // Timer0 preload :6
    // Prescaler      :4
    // Interrupt time :1,0000mS

    // OPTION
    // bit 0 -> PS0    Prescaler Rate Select bit 0
    // bit 1 -> PS1    Prescaler Rate Select bit 1
    // bit 2 -> PS2    Prescaler Rate Select bit 2
    // bit 3 -> PSA    Prescaler assegnato a Timer0 (1=Watchdog Timer)
    // bit 4 -> T0SE   Timer0 Signal Edge: 0=low->high 1=high->low
    // bit 5 -> T0CS   Timer0 Clock Select: internal clock (1=T0CKI transition)
    // bit 6 -> INTEDG INTerrupt Edge (1=raise 0=fall)
    // bit 7 -> RBPU   PortB PullUp (0=off 1=on)

    OPTION_REG = 0b00000001;

    //IMPOSTARE INTERRUPT
    // INTCON
    // bit 0 -> RBIF   PortB Interrupt Flag
    // bit 1 -> INTF   RB0/INT Interrupt Flag
    // bit 2 -> T0IF   Timer0 Interrupt Flag
    // bit 3 -> RBIE   PortB Interrupt Enable (off)
    // bit 4 -> INTE   INT Interrupt Enable (off)
    // bit 5 -> TMR0IE Timer0 Interrupt Enable (on)
    // bit 6 -> PEIE   PEripheral Interrupt Enable (off)
    // bit 7 -> GIE    Global Interrupt Enable (on)

    INTCON = 0b10100000;

    //PRECARICARE IL TIMER
    // Preload Timer0
    // TMR0=8; // valore con correzione

    TMR0 = 8; // con correzione

    while (1) {

    }
}

//ROUTINE DI INTERRUPT

void interrupt isr(void) {
    //CONTROLLO SORGENTE INTERRUPT TIMER0 OVERFLOW
    if (T0IF) {
        //REIMPOSTAZIONE DEL PRECARIMENTO TIMER0
        TMR0 = 8;
        //INCREMENTO VARIABILE TEMPO E CONTROLLO VALORE
        //CON INVERSIONE STATO LED ED AZZERAMENTO TEMPO
        Tempo++;
        if (Tempo >= TempoLampeggio) {
            Led = !Led;
            Tempo = 0;
        }
        //AZZERAMENTO TIMER0 OVERFLOW
        T0IF = 0;
    }
}

Conclusioni

In questo articolo ho cercato di massimizzare il coinvolgimento del lettore condividendo il ragionamento, frammentando al massimo i passaggi teorici sperando che il lettore possa comprendere, e fare suo, il metodo di studio e soluzione.

4

Commenti e note

Inserisci un commento

di ,

just a tiny... bit!

Rispondi

di ,

:) sarebbe stato meglio dici?!

Rispondi

di ,

Who does control the pin?

!!

Rispondi

di ,

Mi fa piacere che sei riuscito a far lampeggiare questo benedetto led! Bel lavoro!

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.