Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

12/11/2013 #1


Problema con adc pic 16f716
Buenas tardes!!

Pasando al tema, estoy realizando un programa en CCS para obtener datos atreves de los puertos análogos del micro, pero tengo un problema al comparar los datos con una variable antes definida, creo que es error de sintaxis pero por mas que le muevo no puedo hacer que funcione y me veo en la necesidad de pedirles ayuda.

Explico mejor mi problema:

Código:
#include <16F716.h>
#Fuses XT, NOWDT
//#device ADC=10
#Use Delay(Clock=4 000 000)
#byte puerto_b = 06

long Dato1, Dato2, Dato3, Dato4, set, setb, sat, satb;


#separate
void x1(){
 set_adc_channel(0);   //lee canal 0
       delay_ms(10);
       Dato1=read_ADC();      
       delay_ms(20);
       
if(dato1>setb){
         output_high(pin_B0);  
                  output_low(pin_B1);
                  output_low(pin_B3);
                  }
       else{
       output_low(pin_B0);
         output_low(pin_B1);
                  output_low(pin_B3);
       } 
}

#separate
void mhr23(){

 set_adc_channel(0);  
       delay_ms(10);
       Dato1=read_ADC();      
       delay_ms(20);

 if(dato1<sat)
         output_high(pin_B0);  
       else{
       output_low(pin_B0);
       }
       if(dato1>satb)
         output_high(pin_B0);
}

#separate
void cto(){
 set_adc_channel(0);   //lee canal 0
       delay_ms(10);
       Dato1=read_ADC();      
       delay_ms(20);

 set_adc_channel(1);   //lee canal 1
       delay_ms(10);
       Dato2=read_ADC();      
       delay_ms(20);

 if(dato1<set)
         output_high(pin_B2);  
       else{
       output_low(pin_B2);
       }
       if(dato1>setb)
         output_high(pin_B2);
         
       ////////////////////////
         
       if(dato2<set)
         output_high(pin_B3);  
       Else{
       output_low(pin_B3);
       }
       if(dato2>setb)
         output_high(pin_B3);

}

#separate
Void main(){
dato5=0;
dato6=0;
dato7=0;
dato8=0;
   
   setup_ADC_ports( ALL_ANALOG );   ///declaras en pin AN0 como entrada Analog
   setup_ADC(ADC_Clock_Div_32);  ///Configuras la velocidad de muestreo
   sat=0xE1;
   satb=0xD5;
   set=0xE8;
   setb=0xEF;

   while(True){
     if (input(pin_b4)==0)
      {
      x1();
                      
   } 
   else if(input(pin_b5)==1){
   mhr23();
   }
   else {
    cto();
   }
  } 
 }

el problema esta en que la rutina de x1 y de cto si funcionan pero al comparar con otra variable por ejemplo paso de comparar set a sat y ya no funciona la rutina, solo la rutina x1 y cto, bueno espero me haya explicado bien y me puedan ayudar de antemano gracias!!.

PD: soy novato programando sorry por los horrores de código .
21/02/2015 #2

Avatar de lordsoft

Problema con adc pic 16f716
Hola a todos. Me dirijo a ustedes luego de agotar mis ojos leyendo foros en inglés y manuales.
Estoy trabajando con un voltímetro con un PIC16F716 usando el ADC del PIC.
En proteus corre bien, pero a la hora de pasar el .hex al micro en un protoboard con un PICkit2, no hace ni pío.
Pensando que el código estaba mal, hice un código sencillo para encender un LED por el puerto B, pero al cargarlo al PIC tampoco funciona.

Este es el código en C de CCS:
Código:
#include <16F716.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#BYTE portb=6       //puerto B en 06h
#BYTE porta=5       //puerto A en 05h 
#BYTE trisa=133     //TRISA en 85h
#BYTE trisb=134     //TRISB en 86h

void main()
{
trisb=0;

while(true) {
portb=255;
delay_ms(300);
portb=0;
delay_ms(300);

}
}
En el protoboard está todo cableado correctamente.
Como es solo un LED, estoy alimentando con los 5V del PICkit2
El cristal que uso es de 4Mhz y los capacitores de 22pF, una Resistencia de 10K entre MCLR y 5V y el LED con resistencia de 330 a RB0. No hace nada.

¿Alguien podría ayudarme a encontrar que es lo que anda mal?
De antemano, gracias.
21/02/2015 #3

Avatar de TRILO-BYTE

no se si yo sea un mal prgramador pero jamas declaro los tris de los pic en CCS

yo hubiera dejado el codigo asi


#include <16F716.h>
#FUSES XT,NOWDT
#use delay(clock=4M)

void main()
{

while(true) {
output_b(255);
delay_ms(300);

output_b(0);
delay_ms(300);

}
}


el pic16f716 es un pic bastante facil de usar ami me gusta mucho por que es muy barato

---------- Actualizado después de 2 minutos ----------

respecto al ADC tambien es muy facil declararlo solo hay que seguir las instrucciones del CCS
lo que leas en el ADC lo puedes guardar en un registro de 8 bits que puede ser un CHAR
y lo puedes reflejar directamente en el puerto del pic
21/02/2015 #4
Moderador

Avatar de D@rkbytes

lordsoft dijo: Ver Mensaje
En el protoboard está todo cableado correctamente.
Como es solo un LED, estoy alimentando con los 5V del PICkit2
El cristal que uso es de 4Mhz y los capacitores de 22pF, una Resistencia de 10K entre MCLR y 5V y el LED con resistencia de 330 a RB0. No hace nada.
El código que pones debería funcionar sin problemas, y el código que puso papirrin haría lo mismo pero usando las instrucciones del PICC Compiler.
TRILO-BYTE dijo: Ver Mensaje
No sé si yo sea un mal programador, pero jamás declaro los TRIS de los PIC en CCS
No es necesario en algunos casos.
Lo que si es necesario, es darles un estado inicial a los pines configurados como salida.
Definir un puerto puede servir para realizar esto por ejemplo:
Código PHP:
void main (void)
{
   
trisb 0;
   
portb 0;

   while (
true)
   {
      
portb =~ portb;
      
delay_ms(300);
   }

Que tendría el mismo efecto, pero con menos código.

lordsoft dijo: Ver Mensaje
¿Alguien podría ayudarme a encontrar que es lo que anda mal?
Prueba quitando los capacitores del cristal, porque algunos los tienen internos y los externos pueden bloquear la oscilación.
Si no consigues que funcione, prueba con otro cristal.
También asegúrate de que el pin 4 si tenga +5V al igual que el pin 14. Y obvio, el pin 5 a negativo.
21/02/2015 #5

Avatar de lordsoft

Probé tu código, sigue pasando lo mismo, al menos ya se que el oscilador funciona bien (adjunto imagen osciloscopio entre GND y OSC1) La verdad no sé que puede ser si no es el oscilador.
Imágenes Adjuntas
Tipo de Archivo: jpg ScreenShotxd039.jpg (71,5 KB (Kilobytes), 9 visitas)
22/02/2015 #6
Moderador

Avatar de D@rkbytes

Si el cristal es de 4MHz, debes obtener 2MHz en la salida, pin 15.
Ese PIC no tiene nada extraordinario para que no puedas lograr que funcione ese código.
Si dices que tienes todo bien conectado, entonces el PIC murió.

¿Qué pasa con el puerto A?
¿Ya probaste ese puerto?
En PICC de CCS, y en la versión que tengo, (5.027) no es necesario establecer con setup_adc_ports() que los pines con ADC sean digitales para realizar una prueba del puerto A.
A menos que sí se especifique para usar el ADC.
ADCON1 será 0b00000111 (o sea: Digital I/O) si no se utiliza setup_adc_ports(parámetros);

Otra cosa que ha sucedido con PICC Compiler, es que ha tenido problemas con algunas definiciones.
Puedes probar actualizando la versión que estás usando actualmente.
22/02/2015 #7

Avatar de lordsoft

Ahora funciona, cambie el cristal y el fuse para oscilador RC y funciona. Tambien noté (ahora que funciona) cierta holgura entre las resistencias y el proto que me apaga el led y no pasa nada, quizas eso esté pasando con el voltimetro, trataré de armar todo de nuevo y comentar. Probaré denuevo con cristal de 4mhz y uno de 27mhz

Funciona con XT y HS.
Consulta, en CCS 5.015 al usar el Project Wizard y establecer el oscilador no se donde configura los Fuses, genera un archivo .h pero en el tampoco se encuentra dicha configuración. ¿cómo lo hace? porque cargue un example code de un blink e igual funciona.
22/02/2015 #8
Moderador

Avatar de D@rkbytes

El fuse RC es precisamente para usar un oscilador externo RC (Resistencia y Capacitor)
Con un cristal no debería funcionar.

Yo no uso el wizard, establezco todas las configuraciones en el archivo main.
Pero es aquí:Tipo de PIC y oscilador.jpg
Y se genera el archivo *.h con lo siguiente:
Código:
#include <16F716.h>
#device ADC=16
#use delay(crystal=4MHz)
Agrega #device ADC=16
Y si no se va a usar el ADC, sale sobrando.
Así sucede con otros PIC, agrega cosas que no se van a usar.
Por eso es que prefiero editar mis opciones yo mismo.
22/02/2015 #9

Avatar de lordsoft

Cambié también el oscilador por uno RC

Es exactamente lo que me sale a mi, pero no veo como configura los fuses ahí en el .h
23/02/2015 #10
Moderador

Avatar de D@rkbytes

Se está haciendo con #use delay(crystal=4MHz)
Cuando se usa este tipo de configuración, se le está diciendo al compilador que se usará un cristal de 4MHz.
Entonces el compilador sabrá que debe usar fuse XT (_XT_OSC en ensamblador.)
También quedan otros fuses por defecto: 16F716 Fuses con cristal 4MHz.jpg
Si te fijas, los fuses que se establecen son correctos para el funcionamiento.

Si no tienes muchos conocimientos, puedes usar el wizard para otras configuraciones más.
Y también puedes editarlo después de haber sido creado.
En la barra desplegable del lado izquierdo, "Files" das doble click sobre el archivo "main.h" y lo editas.
Por ejemplo así, de la forma habitual:
Código:
#include <16F716.h>
#fuses   XT
#use    delay(clock = 4000000)
De esta otra forma se obtendrá el mismo resultado en la configuración de fuses.

Y si lo deseas, puedes omitir el fuse BROWNOUT y BORV agregando lo siguiente:
#fuses XT, NOBROWNOUT, BORV25
Quedando la palabra de configuración de esta forma: 16F716 Fuses sin Brownout Reset.jpg
El fuse PUT o _PWRTE_ON es conveniente que esté habilitado, pues se logra que el PIC se mantenga en estado de reset durante unos 72ms cuando es alimentado y con esto esperar a que se estabilice la tensión.

Entonces, tú decides si usar el wizard o establecer por ti mismo la configuración del PIC.
23/02/2015 #11

Avatar de lordsoft

OK gracias amigo veo entonces que el delay de ccs 5 no es el mismo de antaño. Entendido lo del Power on timer pero ¿donde ves ese cuadrito con los fuses que muestras?
23/02/2015 #12
Moderador

Avatar de D@rkbytes

lordsoft dijo: Ver Mensaje
¿Dónde ves ese cuadrito con los fuses que muestras?
Con el WinPic800. Es un buen programa gratuito para grabar dispositivos seriales.
25/02/2015 #13

Avatar de lordsoft

Gracias, solo usé alguna vez el ICprog, no el winpic800 Voy a mirarlo y usar su funcion para chequear los fuses.
09/03/2015 #14

Avatar de lordsoft

Hola de nuevo, les cunto que tengo lista la pcb del voltimetro pero ahora em ocurre algo raro: al meter tension directo por RA1 al pic y mostrar el valor en el display funca todo bien, pero al meter la tensión por un divisor de tensión de 100k-10k, tomando la señal en el punto de union de las resisencias, de forma de medir lo que cae en la R de 10k marca siempre 0 y toda la tensión cae en la R de 100k como si la impedancia de entrada del pic fuese muy baja, alguien podría decirme que sucede en este caso?
09/03/2015 #15


Creo que esto te podría explicar el problema.

Imágenes Adjuntas
Tipo de Archivo: gif DATASHEET.GIF (27,9 KB (Kilobytes), 60 visitas)
09/03/2015 #16
Moderador

Avatar de D@rkbytes

lordsoft dijo: Ver Mensaje
Al meter tensión directo por RA1 al pic y mostrar el valor en el display funca todo bien, pero al meter la tensión por un divisor de tensión de 100k-10k, tomando la señal en el punto de unión de las resistencias, de forma de medir lo que cae en la R de 10k marca siempre 0
¿Cual es el voltaje máximo que quieres medir?
09/03/2015 #17

Avatar de lordsoft

Probe con 10k y 1k y sigue pasando lo mismo.
Deseo medir el voltaje de una fuente 0-30v así cuando hayan 30V en la entrada en la R menor habrán 30/11 V
09/03/2015 #18
Moderador

Avatar de D@rkbytes

No, así no está bien tu divisor.
Estudia sobre el divisor de tensión y determina que resistencias debes usar para obtener el voltaje que necesites conforme a la tensión de referencia del PIC.

Y aparte algo debe tener tu programa, es mejor que lo adjuntes para revisarlo.
09/03/2015 #19

Avatar de lordsoft

Si la tension de referencia del pic está ajustada a 0V:

Por divisor de tensión V2= Vin*R2/(R1+R2)

Si quiero medir hasta 30V sin llevar al limite al pic puedo usar R1=100k R2=10k
V2=V(RA1)=30*1K/(100K+10K) = 30/11 V = 2.72V
Código:
#include <16f716.h> //pic16f716
#device adc=8       //ADC 8 bits
#FUSES NOWDT
#FUSES NOBROWNOUT 
#FUSES XT           
#use delay(clock=3800000)
#BYTE portb=6       //puerto B en 06h
#BYTE porta=5       //puerto A en 05h 
#BYTE trisa=133     //TRISA en 85h
#BYTE trisb=134     //TRISB en 86h

#DEFINE del 5
#DEFINE time 200

    int16 unidades (int16 numero) ;
    int16 decenas (int16 numero) ;
    int16 centenas (int16 numero) ;
    int16 miles (int16 numero) ;
    void print_seg (int16 value) ;
    
void main() 
{
   
   int16 lectura,vi,r1,r2;

   r1=100; //R1=100k
   r2=10; //R2=1K
 
   trisa=17; 
   trisb=0x00; 

   
   setup_adc_ports(AN0_AN1_AN3); 
   delay_us(20);
   setup_adc(ADC_CLOCK_DIV_2); 
   delay_us(20); 
   while (true)
   {

         set_adc_channel(1);
         delay_us(50);
         lectura=read_adc();
         delay_us(50);
         vi=1.9607*((r1+r2)/r2)*lectura;

         print_seg(vi);
      }
      
   }

int16 unidades(int16 numero)
{
   int16 unidades = 0;
   unidades = numero % 10;
   return unidades;
}
int16 decenas(int16 numero)
{
   int16 decenas = 0;
   decenas = (numero / 10) % 10;
   return decenas;
}
int16 centenas(int16 numero)
{
   int16 centenas = 0;
   centenas = (numero / 100) % 10;
   return centenas;
}
int16 miles(int16 numero)
{
   int16 miles = 0;
   miles = (numero / 1000) % 10;
   return miles;
}
void print_seg(int16 value)
{
   portb=16+unidades(value);
   bit_clear(porta,4); //Pone a 0 RA4 para prender punto dec.
   delay_ms(del);
   bit_set(porta,4);
   portb=32+decenas(value);
   delay_ms(del);
   portb=64+centenas(value);
   delay_ms(del);
   portb=128+miles(value);
   delay_ms(del);
}
09/03/2015 #20
Moderador

Avatar de D@rkbytes

Prueba ahora el programa adjunto con algunas modificaciones.
No tengo el PIC16F716 que estás usando, así que no lo puedo probar físicamente.
Con algún otro PIC tal vez funcione y posiblemente luego realice el montaje.

PD:
El esquema está diseñado de esa forma porque se incluye la simulación y así es como funciona mejor.
Físicamente, se tienen que sustituir los inversores por transistores NPN.

Suerte.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.