hola necesito ayuda con un problema que no se como resolver , tengo un programa que muestra la tensión , un voltámetro la muestra es por el adc pero cuando pongo una carga se mueve mucho la muestra , como puedo hacer para mostrarla en el lcd que quede fija , por mas que haya pequeñas oscilaciones .
Código:
#include <16f886.h>
#device ADC=10
#use delay(internal = 8MHz)
#define LCD_DATA_PORT getenv("SFR:PORTC")
#include <flex_lcd.c>
#define LCD_RW_PIN PIN_C3
//#include <internal_eeprom.c>
int1 flagHayDatos=0;
float const ticks_us = 4.0; // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Interno)
//float const ticks_us = 8.0; // microsegundos por Tick del Timer 1 @ 8 MHz. (Osc. Cristal)
long int var2=0;
int8 flancos;
int8 flag_flanco;
int16 periodo1,periodo2,periodo3;
int16 tiempo_alto,tiempo_bajo,tiempo_total;
float us_alto,us_bajo,us_total,valor2,amper, duty;
int porcentaje, porcentaje2;
int frecuencia;
int16 valor_adc;
float voltaje;
int8 ciclo_activo=1;
void voltaje(void);
int16 cont3;
#INT_EXT
void sdi_externa_RB0 (void)
{
flancos++; // Incrementar la variable "flancos"
if(!flag_flanco) // Si el flanco del pulso es bajo...
{
if(flancos == 1) // Si el conteo de flancos es 1...
{
set_timer1(0); // Limpiar el Timer 1
periodo1 = get_timer1(); // "periodo1" tendrá el tiempo del pulso en alto.
}
if(flancos == 3) // Si el conteo de flancos es 3...
periodo3 = get_timer1(); // "periodo3" tendrá el tiempo del pulso en alto.
EXT_INT_EDGE(H_TO_L); // Establecer la interrupción por flanco de bajada.
flag_flanco = 1; // Indicar que el próximo flanco será de bajada.
}
else // Caso contrario. (Pulso en estado alto)...
{
periodo2 = get_timer1(); // "periodo2" tendrá el valor del pulso en bajo.
EXT_INT_EDGE(L_TO_H); // Establecer la interrupción por flanco de subida.
flag_flanco = 0; // Indicar que el próximo flanco será de subida.
if(flagHayDatos==0){ // Si los datos anteriores han sido procesados ...
flagHayDatos=1; // Indico que ya hay nuevos datos de flancos para calcular
}
}
if(flancos > 2)flancos = 0; // Si la variable "flancos" llega a 3, ponerla a 0.
}
void establecer_ciclo (int8 ciclo)
{
set_pwm1_duty(ciclo); // Establecer el ciclo activo
lcd_gotoxy(10,3);
// Obtener el porcentaje del ciclo activo.
porcentaje2 = (ciclo / 24.5) *10;
// Mostrar el porcentaje del ciclo activo para la carga.
printf(lcd_putc,"PWM:%02u%%",porcentaje2,);
voltaje();
}
void voltaje (void)
{
int16 valor_adc;
float voltaje;
set_adc_channel(0); // Establecer la lectura del canal ADC 10
delay_us(62);
valor_adc = read_adc(); // Tomar la lectura del voltaje.
voltaje = ((valor_adc * 18.0) / 1023);
lcd_gotoxy(11,1);
printf(lcd_putc,"V=%4.1fV ",voltaje);
delay_ms(30);
}
void pulsadores()
{
if (input(PIN_A4)==0)
{
while(!input(pin_a4)){
ciclo_activo ++; // Incrementar el ciclo activo.
if (ciclo_activo > 249) ciclo_activo = 249; // No permitir que el ciclo activo suba de 249
delay_ms(10);
establecer_ciclo(ciclo_activo);
}
}
if (input(PIN_A5)==0)
{
while(!input(pin_a5)){
ciclo_activo --; // Disminuir el ciclo activo.
delay_ms(10);
if (ciclo_activo <= 1) ciclo_activo = 2; // No permitir que el ciclo activo baje de 1
establecer_ciclo(ciclo_activo);
}
}
}
void energia()
{
// set_adc_channel(11);
// delay_us(50);
// ene = read_adc();
// if(ene<200)
if(input(pin_B4)==0){
cont3++;
delay_ms(1);
if (cont3 >10) {
write_eeprom(03,ciclo_activo );
delay_ms(50);
cont3 = 0;
}
}
}
void main()
{
ciclo_activo =read_eeprom(03);
establecer_ciclo(ciclo_activo);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,249,1); // 1000 Hz. @ 4 MHz.
set_pwm1_duty(1); // Ciclo activo al mínimo
setup_adc_ports(sAN1|san3|san11);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(int_ext);
ext_int_edge(0,L_TO_H);
enable_interrupts(global);
#ZERO_RAM // Limpiar RAM. (Variables en 0)
lcd_init();
establecer_ciclo(ciclo_activo);
while (true)
{
if(flagHayDatos==1){
if((periodo3 > periodo2) && (periodo2 > periodo1))
{
tiempo_alto = periodo2 - periodo1; // Obtener el periodo del pulso en estado alto.
tiempo_bajo = periodo3 - periodo2; // Obtener el periodo del pulso en estado bajo.
tiempo_total = tiempo_alto + tiempo_bajo; // Obtener el periodo de la frecuencia.
us_alto = ticks_us * tiempo_alto; // Obtener el periodo en microsegundos del pulso en alto.
us_bajo = ticks_us * tiempo_bajo; // Obtener el periodo en microsegundos del pulso en bajo.
us_total = ticks_us * tiempo_total; // Obtener los microsegundos en total de la frecuencia.
frecuencia = 1 / (us_total / 1000000); // Obtener la frecuencia.
duty = ((float) tiempo_bajo / (float)(tiempo_bajo + tiempo_alto));
porcentaje = (duty * 100) + 10; // Físicamente el + 0.5 puede no ser necesario. (Ajusta desviación pero consume ROM)
}
flagHayDatos=0;
}
lcd_gotoxy(1,1);
printf(lcd_putc,"Hz:%03u ",frecuencia);
if(porcentaje < 3)porcentaje = 0;
if(porcentaje > 95)porcentaje = 99;
lcd_gotoxy(1,2);
printf(lcd_putc,"Duty:%02u%% ",porcentaje );
flagHayDatos=0;
delay_ms(100); // Retardo para disminuir parpadeos en la pantalla. (No afecta interrupción externa.)
if(flagHayDatos==0){
frecuencia = 0;
porcentaje=0;
}
pulsadores();
voltaje();
energia();
set_adc_channel(1);
delay_us(30);
amper=0;
for(var2=0;var2<50;var2++)
{
amper=amper+ read_adc();
delay_us(62);
}
valor2 = amper / 50;
valor2 = valor2 * 20 / 1023;
lcd_gotoxy(11,2);
printf(lcd_putc,"A=%4.2f",valor2);
delay_ms(60);
}
}