Medição de ciclo de PWM com o pic 16F877

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Medição de ciclo de PWM com o pic 16F877

Mensagempor mdaj » 01 Fev 2010 21:44

Boa noite, gente, Estou começando com programação em pic em C agora (tenho ALGUMA failiaridade com o asm da motorola, mas no pci sou um ignorante de marca maior... rs). Estou trabalhando com o 16F877

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á!

:lol:
mdaj
Bit
 
Mensagens: 31
Registrado em: 20 Jan 2010 07:26

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x