Estou precisando fazer um programa que meça o ciclo de trabalho em um acelrometro nos eixos x e y, para isso tentei fazer pela interrupção capture dos modulos CCP 1 e 2, porém , quando tento expor o resultado no display de lcd, o resultado fica uma porcaria no lcd, acredito porque fica entrando na interrupção qdo ele deveria expor no display.
Então fiz um programa que fizesse a mesma coisa , mas por recenseamento, mas ainda assim, na posição que é para dar zero no display, ele fica oscilando demais, e eu não estou conseguindo um resultado correto.
O funcionamento dele é basicamente calcular uma rsposta através da seguinte equação, fornecida pelo fabricante:
g = (duty - 0.5) / 0.125
Tanto para o eixo x quanto para o eixo y. A variável duty é diferente para cada um.
Também pus uns leds para indicar o lado para o qual o acelerômetro está sendo movido ou inclinado, são eles: LF, L, LR e LL.
Segue o código:
/*Versão 2 do programa para utilização do sensor*/
#include <16f877.h> //Dispositivo utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP //Fusíveis
#use delay(clock=4000000) //definção de clock utilizado
//------------- Inclusão dos arquios utilizados ------------------------
#include <math.h> //Bibliotec para expor os dados no LCD
//----------------------------------------------------------------------
//---------------- Definição das portas e sua utilização --------------
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
//----------------------------------------------------------------------
//----------- Definição dos endereços dos registros das portas ---------
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09
//----------------------------------------------------------------------
//--------------- Definição de vaiáveis globais ------------------------
float tonx=0,toffx=0,ax=0,tony=0,toffy=0,ay=0,dutyy=0,dutyx=0;
unsigned long t_onx=0,t_offx=0,t_ony=0,t_offy=0;
int x=0, y=0, contador=0, errox=0,erroy=0,erro=0;
//----------------------------------------------------------------------
//-------------------- Definição de flags ------------------------------
#bit pwmx = portc.2
#bit pwmy = portc.1
#bit rs = porte.0
#bit enable = porte.1
//----------------------------------------------------------------------
//-------------------- Definição de atuadores --------------------------
#bit LB = portb.4
#bit LR = portb.3
#bit LF = portb.5
#bit LL = portb.2
//----------------------------------------------------------------------
//------------------- Protótipos das funções ---------------------------
void main ();
void limpa_lcd();
void inicializa_lcd();
void comando_lcd(int caracter);
void trata_dado();
void escreve_display(long dado);
//----------------------------------------------------------------------
//---------------------- Funções utilizadas ----------------------------
//--------------------- Função de inicialização do LCD -----------------
void limpa_lcd()
{
comando_lcd(0x01); // limpeza do lcd
delay_ms(2);
}
//----------------------------------------------------------------------
//------------------- Função e inicialização do LCD --------------------
void inicializa_lcd()
{
comando_lcd(0x30);
delay_ms(4);
comando_lcd(0x30);
delay_us(100);
comando_lcd(0x30);
comando_lcd(0x38);
limpa_lcd();
comando_lcd(0x0C);
comando_lcd(0x06);
}
//----------------------------------------------------------------------
//----------------- Função de enviar instrução ao LCD ------------------
void comando_lcd(int caracter)
{
rs = 0;
portd = caracter;
enable = 1;
delay_us(1);
enable = 0;
delay_us(40);
}
//----------------------------------------------------------------------
//----------------------- Escrever no display --------------------------
void escreve_display (long dado)
{
rs = 1;
portd = dado;
enable = 1;
delay_us(1);
enable = 0;
delay_us(200);
}
//----------------------------------------------------------------------
//----------------------- Tratamento do dado ---------------------------
void trata_dado()
{
//Definição de variáveis locais
//Não há variáveis locais
//Condições para a impressão dos resultados ou retorno de ERRO!
//if (contador == 1000)
//{
// LR = 0;
// LL = 0;
if (erro==1)
{
limpa_lcd();
comando_lcd(0x80);
printf (escreve_display," ERRO! ");
}
else
{
comando_lcd(0x82);
printf (escreve_display," Ax = %1.3f G ",ax);
comando_lcd(0xC2);
printf (escreve_display," Ay = %1.3f G ");
if (ax>=0.1)
{
LR = 1;
LL = 0;
}
if (ax<=-0.1)
{
LL = 1;
LR = 0;
}
if ((ax<0.1) && (ax>-0.1))
{
LL = 0;
LR = 0;
}
if ((ay<0.1) && (ay>-0.1))
{
LB = 0;
LF = 0;
}
if (ay>=0.1)
{
LF = 1;
LB = 0;
}
if (ay<=-0.1)
{
LB = 1;
LF = 0;
}
}
}
//----------------------------------------------------------------------
//--------------------- Programa principal -----------------------------
void main ()
{
//Definição de variáveis locais
//Não há variáveis locais
//Definição da direção dos dados
set_tris_b (0x00);
set_tris_c (0x0F);
set_tris_d (0x00);
set_tris_e (0x04);
portb=0;
portc=0;
portd=0;
porte=0;
//Inicializção dos LED's de direção
LF = 0;
LF = 0;
LL = 0;
LB = 0;
//Inicialização do LCD
limpa_lcd();
inicializa_lcd();
delay_ms(15);
//Inicialização dos temporiadores
setup_timer_1(T1_internal);
inicio:
for(;;)
{
erro = errox = erroy =0;
if (pwmx==0)
{
set_timer1(0);
while(pwmx!=1);
}
t_onx = get_timer1();
if (pwmx==1)
{
set_timer1(0);
while(pwmx!=0);
}
t_offx = get_timer1();
if (pwmy==0)
{
set_timer1(0);
while(pwmy!=1);
}
t_ony = get_timer1();
if (pwmy==1)
{
set_timer1(0);
while(pwmy!=0);
}
t_offy = get_timer1();
//Cálculo de Ax
tonx = t_onx;
toffx = t_offx;
dutyx = tonx / (tonx + toffx);
ax = (dutyx - 0.5) / 0.125;
if (ax>3.5)
{
erro = 1;
}
//Cálculo de Ay
tony = t_ony;
toffy = t_offy;
dutyy = tony / (tony + toffy);
ay = (dutyy - 0.5) / 0.125;
if (ay>3.5)
{
erro = 1;
}
trata_dado();
}
}
Desculpem o incômodo e obrigado desde já!
