Problema conversor AD PIC16F88

#1
Hola,

Estoy tratando de hacer un circuito simple con Pic16F88. Se trata de comparar la tension leida en el canal AN0, y si pasa de cierto valor, que se apague el led en B0. El codigo es el siguiente:
Fichero cabecera:

Código:
#include <16F88.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES PUT                      //Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES DEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(clock=8000000)
#define LED1   PIN_B0
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)
Main:

Código:
#include "C:\Documents and Settings\PIC\Shock_Switch.h"
#byte PORTB = 0x06
#byte PORTA = 0x05

void main()
{

   setup_adc_ports(sAN0|sAN1|sAN2|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_8MHZ|OSC_INTRC);
   
   
   
   
   
   // TODO: USER CODE!!
   
   unsigned int16 tensionX=0; 
   unsigned int16 poti=100;
   
   
   set_tris_b(0x00); //0b0000000// Configuramos el puerto B como salida.
   PORTB=0b00000000;
   
   while(true)
   {
       PORTB=0b00000001;  
         
       set_adc_channel(0); //elegimos el canal que vamos a leer.
       delay_us(10);  // esperamos 10uS necesarios para el ADC.
       tensionX = read_adc();//leemos el valor del eje x del acelerometro.
       delay_ms(1);
       
       //set_adc_channel(2); //elegimos el canal que vamos a leer.
       //delay_us(10);  // esperamos 10uS necesarios para el ADC.
       //tensionY = read_adc();//leemos el valor del eje y del acelerometro.
       //delay_us(10);
       
       while(tensionX > poti)
       {
         PORTB=0b00000000;
         //delay_ms(1000);
         //PORTB=0b00000000;
         //delay_ms(1000);
         //PORTB=0b00000001;
         //delay_ms(1000);
       } 
   
   
   }
  

}
Si alguien puede darme alguna pista...

Disculpar se me habi olvidado comentar que no funciona :)
 
#2
¿Si cuando sale del while (tensionx>posi) vuelves a encender la luz, como quieres que se apague?
 
#5
Gracias Basalto. Entiendo, lo he hecho con un if y parece que va bien. Ademas he puesto un R pull-down en la patilla A0, aunque no se si esto es totalmente necesario. Todavia no tengo instalado el proteus y no puedo adjuntar esquematico, pero creo que se entiende lo que digo.

Un saludo
 
#6
Gracias Basalto. Entiendo, lo he hecho con un if y parece que va bien. Ademas he puesto un R pull-down en la patilla A0, aunque no se si esto es totalmente necesario. Todavia no tengo instalado el proteus y no puedo adjuntar esquematico, pero creo que se entiende lo que digo.

Un saludo
Ten cuidado con la resistencia, en el datasheet pone: "The maximum recommended impedance for analog
sources is 10 kΩ." http://ww1.microchip.com/downloads/en/devicedoc/30487c.pdf PAG. 117.
 
#7
Hola de nuevo, He intentado complicar un poco mas la cosa y tal vez me he pasado. He intentado que cuando el valor de un acelerometro sea mayor q aproximadamente 2v (400), se llame a una funcion que active el led durante 200ms, pero que si este valor supera 600, lo active mas tiempo. Aqui el codigo:
Código:
#include "C:\Documents and Settings\Escritorio\Proyectos PIC\Shock_Switch2\Shock_Switch2.h"
#include <math.h>
#include <stdio.h>
#byte PORTB = 0x06
#byte PORTA = 0x05

void Golpe(unsigned int16 X,unsigned int16 Y,unsigned int16 P);



void main()
{

   setup_adc_ports(sAN0|sAN1|sAN2|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_8MHZ|OSC_INTRC);

   // TODO: USER CODE!!

   
   unsigned int16 tensionX=0; 
   unsigned int16 tensionY=0;
   unsigned int16 poti=400;
   
   
   set_tris_b(0x00); //0b0000000// Configuramos el puerto B como salida.
   PORTB=0b00000000;
   
   while(true)
   {
         
         
       set_adc_channel(0); //elegimos el canal que vamos a leer.
       delay_us(10);  // esperamos 10uS necesarios para el ADC.
       tensionX = read_adc();//leemos el valor del eje x del acelerometro.
       
       
       set_adc_channel(1); //elegimos el canal que vamos a leer.
       delay_us(10);  // esperamos 10uS necesarios para el ADC.
       tensionY = read_adc();//leemos el valor del eje y del acelerometro.
       
       
       //set_adc_channel(2); //elegimos el canal que vamos a leer.
       //delay_us(10);  // esperamos 10uS necesarios para el ADC.
       //poti = read_adc();//leemos el valor del potenciometro.
       
       
       if(tensionX >= poti || tensionY >= poti)
       {
         void Golpe(tensionX,tensionY,poti);  
         
         
         
       }
       else
         PORTB=0b00000000;
            
   
   
   }
  

}
void Golpe(unsigned int16 X,unsigned int16 Y,unsigned int16 P)
{
   unsigned int16 AuxPoti;
   PORTB=0b00000001;
   delay_ms(200);
   AuxPoti=P + 200;
   if(X >= AuxPoti || Y >= AuxPoti)
    delay_ms(5000);
   
}
Y no consigo el el led se encienda. Compila bien pero...
 
#8
Elimina las resistencias que has puesto en los pines ANx, el CAD tiene una impedancia de entrada lo suficientemente alta como para no preocuparse por las corrientes de entrada.

Supongo que has puesto con el led una resistencia limitadora de 470 o 680 ohm, prueba a cambiar el pin del led a otro del puertoB por si lo hubieses quemado.

En la primera comparación estas utilizando 400, que son 1,95 V. Pon el polímetro en la patilla de AN0 con respecto a masa mira su tensión, lo mismo con AN1 y comprueba si alguno de los dos supera los 1,95 V.

Un saludo
 
#9
Hola, ya he eliminado las R de los canales analogicos, la tension supera lo 2v y el led esta ok. Digo esto porque cuando hago este pequeño cambio:

Código:
if((tensionX >= poti) || (tensionY >= poti))
       {
         void Golpe(tensionX,tensionY,poti);  
         PORTB=0b00000001;
         
         
       }
Si se enciende el Led. Por eso creo que el problema esta en la funcion Golpe, pero no se... Crees q el codigo esta bien?
 
#10
Yo no programo en CCS para PIC, utilizo el HI-TECH por lo que no te puedo ayudar en la sintaxis. Pero puedes probar en no utilizar la función:

if((tensionX >= poti) || (tensionY >= poti))
{
PORTB=0b00000001;

delay_ms(200);
AuxPoti=poti + 200;
if(tensionX >= AuxPoti || tensionY >= AuxPoti)
delay_ms(5000);


}
 

Temas similares

Arriba