Programação do Microcontrolador do CLP PIC16F628A

Microcontrolador PIC16F628A

O seguinte post mostra como é feito a programação do Microcontrolador do CLP PIC, e para isso vamos programar o microcontrolador PIC16F628A, sendo aplicado ao projeto da PCB anterior, ou seja, do CLP PIC.
O nosso objetivo é mostrar como programar o microcontrolador PIC16F628A, utilizando a ferramenta de desenvolvimento o MPLABX IDE, junto com o compilador XC8, as duas ferramentas são da Microchip. O código será desenvolvido tendo como base a última versão do CLP PIC Wantronics.

Criando o projeto

Inicialmente devemos instalar o MPLABX, que pode ser facilmente encontrado no site da Microchip para download. Também será necessário instalar o compilador, também da Microchip, o XC8.

Para criar o projeto, devemos ir em File; New Project, selecionar o microcontrolador utilizado no CLP PIC, o PIC16F628A, depois devemos selecionar o compilador XC8 e a ferramenta para gravação. Também devemos dar um nome ao projeto.

New Project
Selecionando o PIC16F628A
Selecionando o gravado PICKIT3
Selecionando o compilador XC8
Nomeando o projeto

Após criar um nome para o projeto e clicar em Finish, na tela inicial será mostrado a estrutura do nosso projeto com novas pastas.

Projeto Criado

Antes de programar, devemos clicar com o botão direito do mouse na pasta Sources Files, e adicionar um novo arquivo do tipo main.c, e após esses passos estamos prontos para iniciar a programação do microcontrolador.

Programação do microcontrolador PIC16F628A

Após criar e adicionar um arquivo main.c, será apresentado a seguinte tela.

Source file

Agora devemos configurar os fuses bits, de acordo com as necessidades do nosso projeto. Para isso vamos em Production, e em Set Configuration Bits, e será apresentado a seguinte janela.

Configuração dos fuses bits

Em azul, a própria IDE diz quando algum bit teve a sua configuração alterada. Após configurar os bits de acordo com as necessidades do projeto, basta clicar em Generate Source Code, copiar o código e colocar no código fonte do projeto, o código ficará assim:

/*
 * File:   CLP_Wantronics.c
 * Author: wandery
 *
 * Created on 2 de Maio de 2021, 19:58
 */

// PIC16F628A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled)
#pragma config CPD = ON         // Data EE Memory Code Protection bit (Data memory code-protected)
#pragma config CP = ON          // Flash Program Memory Code Protection bit (0000h to 07FFh code-protected)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

void main(void) {
    return;
}

É possível fazer as alterações dos fuses bits diretamente no código, caso necessário.

Neste momento, devemos conhecer a frequência do cristal do circuito oscilador, e também devemos conhecer os GPIOS do microcontrolador que estão conectados as entradas e quais estão conectados nas saídas no CLP PIC, para que possamos fazer as configuração corretamente do microcontrolador.

GPIO PIC16F628A

Desta forma, podemos escrever um código que permita o teste de todas as entradas e saídas de forma simples, abaixo fica o código completo para o CLP PIC, para ser gravado no microcontrolador PIC16F628A.

/*
 * File:   CLP_Wantronics.c
 * Author: wandery
 *
 * Created on 2 de Maio de 2021, 19:58
 */

// PIC16F628A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled)
#pragma config CPD = ON         // Data EE Memory Code Protection bit (Data memory code-protected)
#pragma config CP = ON          // Flash Program Memory Code Protection bit (0000h to 07FFh code-protected)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 4000000   //Define a frequência do cristal oscilador

void main(void) {
    int rele[6];            // Variável para mudar o estado dos relés
    const int tempo = 250; // Varíavel para filtro das entradas
    
    CMCON = 0x07;        // Desliga os comparadores de tensão
    TRISA = 0x00;
    TRISB = 0x3F;
    PORTA = 0x00;       // Desliga todos os relés
    PORTBbits.RB7 = 0;  // Desliga o relé 4
    
    for (int i = 0; i < 6; i++) {
        rele[i] = 0;
    }
    
    while (1){
        PORTAbits.RA4 = rele[0];
        PORTAbits.RA3 = rele[1];
        PORTAbits.RA2 = rele[2];
        PORTBbits.RB7 = rele[3];
        PORTAbits.RA0 = rele[4];
        PORTAbits.RA1 = rele[5];
        
        if (PORTBbits.RB0 == 1) {
            rele[0] =~ rele[0];
            __delay_ms (tempo);
        } 
        if (PORTBbits.RB1 == 1) {
            while (PORTBbits.RB1);
            rele[1] =~ rele[1];
            __delay_ms (tempo);
        }
        if (PORTBbits.RB2 == 1) {
            rele[2] =~ rele[2];
            while (PORTBbits.RB2);
            __delay_ms (tempo);
        }
        if (PORTBbits.RB3 == 1) {
            rele[3] =~ rele[3];
            __delay_ms (tempo);
        }
         if (PORTBbits.RB5 == 1) {
            rele[4] =~ rele[4];
            __delay_ms (tempo);
        }
        if (PORTBbits.RB4 == 1) {
            rele[5] =~ rele[5];
            __delay_ms (tempo);
        }
    }
}

Conclusão

Para concluir, infelizmente durante o projeto foi escolhido o GPIO RA4 como saída. Quando a placa foi gravada, e durante os testes iniciais do firmware, quando era aplicado uma tensão na primeira entrada, a primeira saída não acionava como o esperado. Adicionando um resistor de pull-up ao terminal o circuito funcionou normalmente. Consultando o datasheet do microcontrolador, foi observado que o terminal do RA4 possui uma saída open drain, e que para funcione como um GPIO digital é necessário a utilização de um resistor de pull-up.

RA4 PIC16F628A
RA5 PIC16F628A

Outro detalhe foi com relação ao registrador CMCON, para que o circuito funcionasse corretamente foi necessário desabilitar os comparadores de tensão do microcontrolador PIC16F628A, caso contrário o microcontrolador apresentava um comportamento anormal.

Para mais informações sobre o microcontrolador PIC, e sobre o CLP PIC Wantronics, abaixo segue alguns links uteis.

https://www.microchip.com/wwwproducts/en/PIC16F628A
https://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

Por enquanto é isso, até o próximo post.