SUBINDO UM DEGRAU NO HELLO WORD–
SEQUENCIAL DE LEDS COM PIC16F628A
Agora que você sabe
como controlar uma saída digital, que tal controlar mais
de uma. Vamos programar o famoso sequencial vai e vem.
Crie um projeto e insira no arquivo main.c a listagem
abaixo. Compile e grave o microcontrolador. O jumper JP3
precisa estar fechado para esta experiência.
Listagem main.c
//****************************************************************************** // Projeto LEDs sequenciais "vai-e-vem" para placa PE-PIC16F628A // Desenvolvido por: Eng. Márcio José Soares // // V1.0 - 06/09/2022 // // Compilador: XC8 v2.45 // IDE : MPLABX 6.0 Linux // Plataforma: placa PE-PIC16F628A com PIC16F648A // Gravador : PICKIT3 // // Pinos utilizados: // RB4 : LED5 // RB5 : LED3 // RB6 : LED2 // RB7 : LED1 // //******************************************************************************
//****************************************************************************** // Bits de configuração #pragma config FOSC = INTOSCIO // Bits de seleção do oscilador (Oscilador interno: RA6 e RA7 como I/O) #pragma config WDTE = OFF // WDT disabilitado #pragma config PWRTE = ON // Power-up Timer disabilitado #pragma config MCLRE = ON // MCLR = I/O RA5 #pragma config BOREN = OFF // Brown-out Detect BOD disabilitado #pragma config LVP = OFF // Low-Voltage Programming desabilitado - I/O RB4 #pragma config CPD = OFF // Data EE Memory Code Protection desabilitado #pragma config CP = OFF // Flash Program Memory Code Protection desabilitado
//****************************************************************************** // Se nenhuma freqüência foi definida, assume 4MHz // Esta definição é exigida para calibrar as funções __delay_us() e __delay_ms() #define _XTAL_FREQ 4000000
//****************************************************************************** // Inclui arquivos #include <xc.h> #include <pic16f648a.h>
//****************************************************************************** // Definições importantes do módulo #define TRUE 1 #define LEDS PORTB #define TEMPO 250 //tempo em ms
//****************************************************************************** // Função principal // // Entradas - nenhuma // Saídas - nenhuma //****************************************************************************** void main(void) { uint8_t i; PORTA = 0; // zera ports PORTB = 0; INTCON = 0x00; // Todas as ints desligadas CMCON = 0x07; // desliga comparadores TRISA = 0xFF; // Configura PORT A - entrada TRISB = 0x00; // Configura PORT B - saída LEDS = 0; // limpa port while(TRUE){ for(i=0;i<4;i++){ LEDS = ((0x10 << i) & 0xF0); // faz shift left e limpa LSB __delay_ms(TEMPO); // temporiza } for(i=0;i<4;i++){ LEDS = ((0x80 >> i) & 0xF0); // faz shift rigth e limpa LSB __delay_ms(TEMPO); // temporiza } } return; }
|
Você percebeu que
LEDS assume o portB inteiro?! Nos laços for é inserido
um valor e realizado o deslocamento do mesmo um número
igual a “i” vezes a esquerda ou direita. Esse valor
também sofre um AND com F0H. Veja abaixo:
para:
i = 0 → LEDS = ((0x10
<< 0) & 0xF0) → LEDS = (0x10 & 0xF0) → LED
= 0x10 (0001 0000b);
i = 1 → LEDS = ((0x10
<< 1) & 0xF0) → LEDS = (0x20 & 0xF0) → LED
= 0x20 (0010 0000b);
i = 2 → LEDS = ((0x10
<< 2) & 0xF0) → LEDS = (0x40 & 0xF0) → LED
= 0x40 (0100 0000b);
i = 3 → LEDS = ((0x10
<< 3) & 0xF0) → LEDS = (0x80 & 0xF0) → LED
= 0x80 (1000 0000b);
e em seguida:
i = 0 → LEDS = ((0x80
>> 0) & 0xF0) → LEDS = (0x80 & 0xF0) → LED
= 0x80 (1000 0000b);
i = 1 → LEDS = ((0x80
>> 1) & 0xF0) → LEDS = (0x40 & 0xF0) → LED
= 0x40 (0100 0000b);
i = 2 → LEDS = ((0x80
>> 2) & 0xF0) → LEDS = (0x20 & 0xF0) → LED
= 0x20 (0010 0000b);
i = 3 → LEDS = ((0x80
>> 3) & 0xF0) → LEDS = (0x10 & 0xF0) → LED
= 0x10 (0001 0000b);
Obs.: O AND garante que a parte
menos significativa (LSB) do PORTB esteja sempre
zerada.
|