Autor Tema: PIC16F886 y los puertos analogicos  (Leído 7659 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
PIC16F886 y los puertos analogicos
« en: 17 de Septiembre de 2009, 18:31:24 »
Hola a todos,

Hoy traigo una pregunta que a lo mejor alguien me puede resolver, pero que de momento no he podido encontrar por ningun lado.

Se me ha ocurrido hacer un diseño con el PIC16f886 y sus 11 entradas analogicas, con un codigo muy basico en CCS y que despues simulo en Proteus.
Ahora me ha surgido un problema, a traves del puerto serie y con el virtual terminal del proteus voy viendo los valores de las entradas analogicas, pero las entradas AN11, AN12 y AN13 no funcionan, es mas si en CCS uso la funcion set_adc_channel(11) set_adc_channel(12) o set_adc_channel(13), proteus lanza un mensaje:

"Write to ADCON0 register selects channel 11. Threre is no such channel in PIC16F886 device."
"Attempt to sample non-existant ADC channel 11 (zero assumed)"

Alguien sabe si esto se debe a un fallo en el modelo del PIC16F886 en proteus o por el contrario es un error en la libreria del CCS.

Saludos.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: PIC16F886 y los puertos analogicos
« Respuesta #1 en: 17 de Septiembre de 2009, 19:06:12 »
postea el codigo, has intentado escribir directamente en el ADCON0 para elegir el canal?
intentá asi, definiendo el ADCON0

BYTE ADCON0=0X1F
 
cuando vayas a leer el ADC antes escribis  sobre ADCON0 el canal que necesitas (bits 5 al 2) y luego realizar la lectura del canal...

saludos
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #2 en: 18 de Septiembre de 2009, 05:46:18 »
Este es el codigo, como podeis ver es muy simple, esta hecho para CCS:


#include <16F886.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOWRT                    //Program memory not write protected
#FUSES BORV40                   //Brownout reset at 4.0V

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define delay 25

void main()
{
int8 a=0;
unsigned int16 recbuf[11];
unsigned int16 recbuf_ant[11];

   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);

while(TRUE)
{
   set_adc_channel(0);
   delay_us(delay);
   recbuf[0]=read_adc();

   set_adc_channel(1);
   delay_us(delay);
   recbuf[1]=read_adc();

   set_adc_channel(2);
   delay_us(delay);
   recbuf[2]=read_adc();

   set_adc_channel(3);
   delay_us(delay);
   recbuf[3]=read_adc();

   set_adc_channel(4);
   delay_us(delay);
   recbuf[4]=read_adc();

   set_adc_channel(8);
   delay_us(delay);
   recbuf[5]=read_adc();

   set_adc_channel(9);
   delay_us(delay);
   recbuf[6]=read_adc();

   set_adc_channel(10);
   delay_us(delay);
   recbuf[7]=read_adc();

   set_adc_channel(11);
   delay_us(delay);
   recbuf[8]=read_adc();

   set_adc_channel(12);
   delay_us(delay);
   recbuf[9]=read_adc();

   set_adc_channel(13);
   delay_us(delay);
   recbuf[10]=read_adc();

   for(a=0;a<=10;a++)
      {
      if(recbuf[a]!=recbuf_ant[a])
         {
         printf("recbuf[%d]=%Lu\r\n",a,recbuf[a]);
         recbuf_ant[a]=recbuf[a];
         }
      }
}
}

Saludos

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: PIC16F886 y los puertos analogicos
« Respuesta #3 en: 18 de Septiembre de 2009, 12:28:18 »
lo probaste en circuito armado? puede ser que funcione, sino, pienso que es un bug del CCS, y se tendría que hacer con defines de los registros, y seleccionarlo por ese medio

saludos
.

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #4 en: 18 de Septiembre de 2009, 17:05:03 »
No, no lo he montado, solo lo he programado y simulado con proteus, normalmente primero lo simulo y cuando tengo certeza que su funcionamiento, entonces lo monto.

Saludos

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: PIC16F886 y los puertos analogicos
« Respuesta #5 en: 18 de Septiembre de 2009, 17:22:19 »
proteus no es una herramienta de la cual hay que confiar mucho

te recomiendo que lo montes para descartar error del CCS
.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: PIC16F886 y los puertos analogicos
« Respuesta #6 en: 18 de Septiembre de 2009, 18:26:49 »
La librería 16f886.h nunca permite que se ingrese el número del puerto directamente, es decir, no puedes poner

Código: [Seleccionar]
set_adc_channel(1);
Tienes que usar los defines de la librería para que funcione correctamente.

Código: [Seleccionar]
// Constants used in SETUP_ADC_PORTS() are:
#define sAN0            1       //| A0
#define sAN1            2       //| A1
#define sAN2            4       //| A2
#define sAN3            8       //| A3

...

#define sAN11       0x80000     //| B4
#define sAN12      0x100000     //| B0
#define sAN13      0x200000     //| B5
#define NO_ANALOGS      0       // None
#define ALL_ANALOG   0x1F00FF    // A0 A1 A2 A3 A5 E0 E1 E2 B0 B1 B2 B3 B4 B5

Lo valores que veías en el PRINTF también eran erróneos ya que solo debes elegir un puerto a la vez y al poner '5' por ejemplo estás eligiendo el puerto 0 y 3 al mismo tiempo.

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #7 en: 19 de Septiembre de 2009, 07:50:42 »
Siento no estar de acuerdo contigo, siguiendo tus recomendaciones el proteus si que se vuelve loco.

Mi codigo tal y como está funciona correctamente excepto las tres ultimas entradas analogicas, el problema en mi opinion es que o bien el CCS o bien el proteus no esta gestionando correctamente los registros ADCON0 y ADCON1 y como a este nivel todos los registros estan ocultos al programador, no se bien que valores estan tomando. En ensamblador el programador tiene todo el control de los registros pero en C no sabe realmente los valores que toman.

Saludos

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: PIC16F886 y los puertos analogicos
« Respuesta #8 en: 19 de Septiembre de 2009, 10:26:37 »
cargando en proteus el .cof que genera CCS, se puede hacer una especie de debug paso a paso, puedes ver las variables que tu creaste y los registros del micro
.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: PIC16F886 y los puertos analogicos
« Respuesta #9 en: 19 de Septiembre de 2009, 14:11:59 »
Citar
y como a este nivel todos los registros estan ocultos al programador, no se bien que valores estan tomando. En ensamblador el programador tiene todo el control de los registros pero en C no sabe realmente los valores que toman.
CCS tambien te muestra el codigo ASM que genera ahi puede revisar q valores se estan cargando en el ADCON0 y ADCON1
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: PIC16F886 y los puertos analogicos
« Respuesta #10 en: 19 de Septiembre de 2009, 14:13:35 »
Otro error que veo en el programa es que nunca estableces el valor I/O del tris de cada pin a usar como analógico.

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #11 en: 19 de Septiembre de 2009, 15:02:32 »
Si, ahi tienes razon, pero ya le puse los parametros del TRIS y sigue igual.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: PIC16F886 y los puertos analogicos
« Respuesta #12 en: 19 de Septiembre de 2009, 17:34:32 »
Hola de nuevo

Probé el programa con ligeras modificaciones... usando el set_adc_channel como tú lo haces (yo estaba mal)...

Código: [Seleccionar]
#include <16F886.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOWRT                    //Program memory not write protected
#FUSES BORV40                   //Brownout reset at 4.0V

#use standard_io(A)
#use standard_io(B)

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define delay 25

void main()
{
int8 a=0;
int16 recbuf[11];

set_tris_a(0xFF);
set_tris_b(0xFF);
set_tris_c(0xFF);

setup_adc_ports(ALL_ANALOG | VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32);
   
while(TRUE)
{
   set_adc_channel(0);
   delay_us(delay);
   recbuf[0]=read_adc();

   set_adc_channel(1);
   delay_us(delay);
   recbuf[1]=read_adc();

   set_adc_channel(2);
   delay_us(delay);
   recbuf[2]=read_adc();

   set_adc_channel(3);
   delay_us(delay);
   recbuf[3]=read_adc();

   set_adc_channel(4);
   delay_us(delay);
   recbuf[4]=read_adc();

   set_adc_channel(8);
   delay_us(delay);
   recbuf[5]=read_adc();

   set_adc_channel(9);
   delay_us(delay);
   recbuf[6]=read_adc();
   
   set_adc_channel(10);
   delay_us(delay);
   recbuf[7]=read_adc();
   
   set_adc_channel(11);
   delay_us(delay);
   recbuf[8]=read_adc();
   
   set_adc_channel(12);
   delay_us(delay);
   recbuf[9]=read_adc();
   
   set_adc_channel(13);
   delay_us(delay);
   recbuf[10]=read_adc();

   for(a=0;a<11;++a)
         printf("recbuf[%u]=%Lu\r\n",a,recbuf[a]);
}
}

El compilador CCS elige correctamente el canal a medir, especialmente los 11, 12 y 13, llenando correctamente ADCON0 con el valor CHS<3:0> = 1011 para canal 11 por ejemplo.

Cuando Proteus pasa por la selección del canal 11, 12 o 13 avisa que ese analógico no existe en el modelo 886, pero eso es un error. Asumo que es un bug del modelo 886 de Proteus, porque CCS compila correctamente. Si lo llegas a probar físicamente nos avisas si funciona.



En una segunda prueba cambié el set_adc_channel a 5, recordando que el 886 no tiene AN5 y Proteus no se queja de ninguna manera, aunque se sigue quejando con el 11, 12 y 13.

Es muy seguro que sea un bug y que por implementar el 886 de manera rápida, la gente de Proteus haya ignorado que AN5, An6 y AN7 no existen en el modelo, pero sí existen AN11, 12 y 13.

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #13 en: 20 de Septiembre de 2009, 07:06:15 »
Finalmente me voy a decicir a montarlo.

Tan pronto como lo haya probado posteare los resultados ya que seguramente a alguien le será de ayuda saber si realmente el Proteus tiene un bug en el pic16f886.

Gracias a todos

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: PIC16F886 y los puertos analogicos
« Respuesta #14 en: 26 de Septiembre de 2009, 15:57:18 »
Hola a todos,

Hoy he montado el circuito con el pic16f886 y efectivamente el problema estaba en PROTEUS, el circuito funciona correctamente, asi que por mi parte cierro este tema.

Saludos