You are on page 1of 6

ECU 16F877A

#include <xc.h> //Biblioteca geral para os pic's 16f e 18f neste compilador xc8
#include <stdio.h> //Biblioteca para a escrita no display, utilizando o sprintf
#include "time.h" //Biblioteca de dia/mês/ano. Considerei necessário para a utilização da temporização
#include <math.h> //Biblioteca das funções matemáticas
#include <stdlib.h> //Biblioteca de conversãoi de tipos de dados (real para inteiro, por exemplo)
#include <stdbool.h> //Biblioteca para variáveis lógicas (booleanas, por exemplo)
#include "lcd.h" //Biblioteca baixada da internet para o display

#pragma config FOSC = HS //OSCILADOR EXTERNO DE 20MHz


#pragma config WDTE = OFF //TEMPORIZADOR DE WATCHDOG DESABILITADO
#pragma config PWRTE = OFF //TEMPORIZADOR DE ENERGIZAÇÃO DESATIVADO
#pragma config BOREN = OFF //Brown-out DESATIVADO
#pragma config LVP = OFF //RB3 É I/O DIGITAL, HV no pino MCLR deve ser usado para programar
#pragma config CPD = OFF //Proteção do código na memória EEPROM desativada
#pragma config WRT = OFF //Proteção da escrita da memória flash desativada
#pragma config DEBUG = OFF //Debugger no circuito desativado, RB6 e RB7 são pinos de I/O
#pragma config CP = OFF //Proteção do código da memória flash desativada
#define SAIDA361 PORTDbits.RD0 //Saída de pulsos 36+1
#define SAIDA121 PORTDbits.RD1 //Saída de pulsos 12+1
#define LED PORTAbits.RA3 //Saída de indicação que o programa foi gravado

#define _XTAL_FREQ 20000000 //Frequência do cristal de oscilação de 20MHz


#define in delays.h //Utilização da biblioteca de delay neste programa
void inicializa_AD() //Rotina que realiza a configuração da entrada analógica AN0
{
ADCON0 = 0b01000000; //Tosc = 8 (20MHZ , veja datasheet) ;habilita modulo de conversão
ADCON1 = 0X8E; //leitura do valor justificado a direita,apenas RA0 será de entrada de tensão()AN0.
ADIE = 1; //não habilita interrupção de conversão analogica
}
int leitura() //Rotina que realiza a configuração da entrada analógica AN0
{
long valor;
ADCON0 = 5; //solicita leitura
while(ADCON0 == 5);//espera terminar leitura
return((ADRESH<<8)+ ADRESL);
}

void main (void)


{
TRISD = 0x00;
TRISA = 0x01;
inicializa_AD();
Página 1
ECU 16F877A
leitura();

LCD lcd = { &PORTD, 2, 3, 4, 5, 6, 7 }; // PORT, RS, EN, D4, D5, D6, D7


LCD_Init(lcd);
unsigned char display1[21];
unsigned int cont = 2, cont2, ajuste, tempoint, tpint, contatempo = 0, conta = 3;
float temporeal;

//TESTE DE VALIDAÇÃO DO FUNCIONAMENTO DO DISPLAY E DA ENTRADA ANALÓGICA


ajuste = leitura();
sprintf(display1,"TESTE ENTRADA : %d",ajuste);
LCD_Clear();
LCD_Set_Cursor(0,0);
LCD_puts (display1);
//FIM

//LED DE INDICAÇÃO DE QUE O PROGRAMA FOI CARREGADO CORRETAMENTE


LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
sprintf(display1,"Indicacao concluida");
LCD_Set_Cursor(1,0);
LCD_puts (display1);
sprintf(display1,"com sucesso");
LCD_Set_Cursor(2,0);
LCD_puts (display1);
sprintf(display1,"loading step 2...");
LCD_Set_Cursor(3,0);
LCD_puts (display1);
//FIM

Página 2
ECU 16F877A
//AJUSTE PARA SE TER A REFERÊNCIA INICIAL DA CONTAGEM DE TEMPO,
//SE NÃO O PROGRAMA VAI INICIAR O PRIMEIRO CICLO SEM ESTA REFERÊNCIA
ajuste = leitura();
temporeal = (((float)ajuste)*150/1023)+10; // transformar a entrada analógica para frequência de 10 à 160Hz
temporeal = ((1/temporeal)-0.006)*100000; //transformar a frequência em tempo em microsegundos*10
tempoint = (int)temporeal;
while (tempoint%3 != 0) // para saber quantas vezes vai contar 15us
{
tempoint = tempoint+1; // para transformar o número em valor divisível por 3
}
contatempo = tempoint/3;
//FIM
while (1)
{
while (cont < 38)
{
SAIDA361 = 1;
__delay_ms(3);
while (conta != contatempo)
{
__delay_us(15);
conta = conta++;
}
conta = 0;
SAIDA361 = 0;
if (cont%6==0) //gera o pulso do 12+1 a cada 6 pulsos do 36+1
{
SAIDA121 = 1;
}
else
{
SAIDA121 = 0;
}
if (cont2==2) // realiza o pulso de falha do 12+1 após a falha do 36+1
// e a leitura da entrada analógica novamente
{
SAIDA121 = 1;
cont2 = 0;

if (temporeal < 1900.0) ////atualiza a entrada analógica para quando a frequência for maior que 40hz
(atualização mais lenta)
{
ajuste = leitura();
Página 3
ECU 16F877A
temporeal = (((float)ajuste)*150/1023)+10; // transformar a entrada analógica para frequência de
10 à 160Hz
temporeal = ((1/temporeal)-0.006)*100000; //transformar a frequência em tempo em
microsegundos*10
tempoint = (int)temporeal;
while (tempoint%3 != 0) // para saber quantas vezes vai contar 15us
{
tempoint = tempoint+1; // para transformar o número em valor divisível por 3
}
contatempo = tempoint/3;
}
}

if(cont == 37) //Realiza o pulso de falha do 36+1


//o valor de __delay_us deveria ser 5, mas teve melhor
//performance com 2.5
{
__delay_ms(1);
while (conta != contatempo)
{
__delay_us(2.5);
conta = conta++;
}
conta = 0;
SAIDA361 = 1;
__delay_ms(1);
while (conta != contatempo)
{
__delay_us(2.5);
conta = conta++;
}
conta = 0;
SAIDA361 = 0;
if(temporeal>=1900) // Correção de 250us do atrado que tem na leitura da entrada analógica
// Essa correção é necessária principalmente para frequências baixas, pois a
atualização ocorre na metade do 12+1
{
__delay_us(250);
}
else
{
__delay_ms(1);
}
while (conta != contatempo)
Página 4
ECU 16F877A
{
__delay_us(2.5);
conta = conta++;
}
conta = 0;
}
else
{
if(cont2==0 & cont == 2) // Correção de 2ms do atrado que tem na leitura da entrada analógica
// Essa correção é necessária principalmente para frequências altas
{
__delay_ms(1);
}
else
{
__delay_ms(3);
}

while (conta != contatempo)


{
__delay_us(15);
conta = conta++;
}
conta = 0;
}
cont++;
}
cont = 2;

if (temporeal >= 1900.0) //atualiza a entrada analógica para quando a frequência for menor que 40Hz
(atualização rápida lenta, pois a frequência é mais lenta)
{
ajuste = leitura();
temporeal = (((float)ajuste)*150/1023)+10; // transformar a entrada analógica para frequência de 10 à
160Hz
temporeal = ((1/temporeal)-0.006)*100000; //transformar a frequência em tempo em microsegundos*10
tempoint = (int)temporeal;
while (tempoint%3 != 0) // para saber quantas vezes vai contar 15us
{
tempoint = tempoint+1; // para transformar o número em valor divisível por 3
}
contatempo = tempoint/3;
}
if (cont2<2) //referência da falha do 12+1
{
Página 5
ECU 16F877A
cont2++;
}
}
}

Página 6

You might also like