Programació en C del PIC 18F45K20

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Exemple RL - Rotació de LED

Ara volem que els LED s'activin de manera seqüencial. Podríem fer un programa de l'estil dels anteriors on anéssim activant i desactivant els bits un darrera l'altre. Però volem fer un programa més compacte. Hi ha algunes formes de fer-ho.

Una manera és fent servir les instruccions de rotació de bits. Això és el que fa el següent programa:

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF				// CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30				// CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768					// CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC		// CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF				// CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF			// CONFIG5L
#pragma config CPB = OFF, CPD = OFF						// CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF			// CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF				// CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF		// CONFIG7L
#pragma config EBTRB = OFF							// CONFIG7H
#include "p18f45k20.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 18F45K20
#include <xc.h>					// Carrega el fitxer de funcions
unsigned char Valor;  				// Variable de 8 bits sense signe (0 a 255)
void main (void)
{
    TRISD = 0b00000000;     			// El port D és de sortida
    Valor = 1;           			// Inicialment posem 1 (activem LED 0)
    while (1)					// Bucle infinit
    {
        LATD = Valor;				// Copiem el valor al port (als LED)
        Valor = (Valor << 1) | (Valor >> 7);	// Desplacem els bits
        _delay(50000);	    			// Retard per permetre la visualització
    }
}

Per girar en sentit contrari nomñes cal permutar el 7 i el 1.

Anem a veure una manera alternativa de fer-ho. Igual que en decimal fer desplaçar els números un lloc a l'esquerra implica multiplicar per deu, en binari implica multiplicar per dos. Inicialitzarem una variable amb el valor 1 (LED 0) i a cada repetició l'anirem multiplicant per 2. Quan el valor sigui 128 (LED 7) ja no podem tornar a multiplicar per dos ja que sortiríem fora del rang; en aquest cas tornarem a posar un 1.

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF				// CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30				// CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768					// CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC		// CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF				// CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF			// CONFIG5L
#pragma config CPB = OFF, CPD = OFF						// CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF			// CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF				// CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF		// CONFIG7L
#pragma config EBTRB = OFF							// CONFIG7H
#include "p18f45k20.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 18F45K20
#include <xc.h>					// Carrega el fitxer de funcions
unsigned char Valor;  				// Variable de 8 bits sense signe (0 a 255)
void main (void)
{
    TRISD = 0b00000000;     			// El port D és de sortida
    Valor = 1;           			// Inicialment posem 1 (activem LED 0)
    while (1)					// Bucle infinit
    {
        LATD = Valor;				// Copiem el valor al port (als LED)
        if (Valor == 128)			// Si ja estem al LED 7, no podem rodar més
            Valor = 1;    			// tornem al LED 0
        else					// Si no estem al LED 7
            Valor = 2*Valor; 			// Multipliquem per 2 i passem al LED següent
        _delay(50000);	    			// Retard per permetre la visualització
    }
}

En aquest cas, el gir en sentit contrari s'aconsegueix dividint per dos i permutant els 1 pels 128.

Una tercera forma de fer-ho és tenir una variable que es vagi incrementant del 0 al 7 i fer-la servir de punter per llegir el valor que correspon a una llista. En aquesta llista hi haurà el valor que ccorrespon a cada posició. Aquesta llista és fixa, és a dir que no es modifica durant l'execució del programa. Per això la podem guardar a la memòria de programa.

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF				// CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30				// CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768					// CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC		// CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF				// CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF			// CONFIG5L
#pragma config CPB = OFF, CPD = OFF						// CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF			// CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF				// CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF		// CONFIG7L
#pragma config EBTRB = OFF							// CONFIG7H
#include "p18f45k20.h"				// Carrega el fitxer d'adreces i paràmetres del PIC 18F45K20
#include <xc.h>					// Carrega el fitxer de funcions
unsigned char LED;  				// Variable de 8 bits sense signe (0 a 255)
						// Tenim una llista amb els 8 valors que ja definim
						// i que es guarda a la posició 0x180 de la memòria de programa
const char Llista[8] @ 0x180 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
void main (void)
{
    TRISD = 0b00000000;     			// El port D és de sortida
    LED = 0;          				// Inicialment activem LED 0
    while (1)					// Bucle infinit
    {
        LATD = Llista[LED];			// Busquem a la llista el valor que enviem al port
        LED++;  			   	// Incrementem la variable
        if (LED == 8)				// Si hem arribat a 8 (ens hem passat)
            LED = 0;   				// Tornem a zero
        _delay(50000);	    			// Retard per permetre la visualització
    }
}

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.