PIC 12f675 ADC + comunicacion serial 16f84

Saludos compañeros del foro.

Me encuentro en la labor de realizar una lectura adc con el 12f675 para luego pasarlo a un 16f84 y representar este valor tomado en una barra de 8 leds.

expongo aqui el codigo de ejemplo que tome de una web foranea.

Código:
#include <12f675.h>
#define RED PIN_A4
#define GREEN PIN_A5
#device ADC=8
#use delay(clock=4000000)
//Value to save ADC reading
long Value;

void ReadMyAdc()
{
Value=read_adc(adc_read_only);
//If more then 50%
if (Value > 512)//Flash Green
{
     output_bit(GREEN,1);
      output_bit(RED,0);
      delay_ms (250);
   output_bit(GREEN,0);
   output_bit(RED,0);
   delay_ms(250);
}
if (Value < 513)//Flash Red
{
    output_bit(GREEN,0);
      output_bit(RED,1);
      delay_ms (250);
   output_bit(GREEN,0);
   output_bit(RED,0);
   delay_ms(250);   
}

}
void main()
{


set_tris_a(0xf);//RA0, RA1, RA2, RA3 as Inputs
               //RA4, RA5 as Outputs
setup_adc_ports(AN0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL );
set_adc_channel(0);
   while(TRUE)
   {
      ReadMyAdc();
   } 
}

Simulo con este diagrama:


pero no corre el programa, se queda en la linea de #device 12f675.

hay algo que este mal?.

ya para la parte de comunicacion serial no creo que halla problema, hay bastantes temas en este foro sobre eso, solo que me pregunto ¿Se puede emplear esta comunicacion entre dos pics sin el MAX232?, y tambien ¿que tal una interface PC-PIC a travez del puerto serial (DB9, DB25) pero sin el MAX232?.
 
A tu código le falta la palabra de configuración.
Si quieres usar el oscilador interno y usar el pin GP4 como salida, debes establecerla,
ya que ese pin es parte del oscilador y si no configuras que se usará como pin normal (I/O), no funcionará.
Así que tu palabra de configuración sería esta...
#fuses intrc_io, nomclr // Oscilador interno (GP4 = I/O) y sin Master Clear (Pin sólo entrada)
Luego, quieres leer un valor arriba de 512, pero estás usando el ADC a 8 bits, así sólo conseguirás 255 máximo.
Entonces cambia la configuración a 10 bits, para obtener una lectura de 1023 cómo máximo.
¿Se puede emplear esta comunicacion entre dos pics sin el MAX232?, y tambien ¿que tal una interface PC-PIC a travez del puerto serial (DB9, DB25) pero sin el MAX232?.
Si se pueden comunicar los PIC sin usar un MAX232 y también se puede hacer una interfaz PIC-PC sin el MAX232
De eso también hay temas en el Foro.

Saludos.
 
A tu código le falta la palabra de configuración.
Si quieres usar el oscilador interno y usar el pin GP4 como salida, debes establecerla,
ya que ese pin es parte del oscilador y si no configuras que se usará como pin normal (I/O), no funcionará.
Así que tu palabra de configuración sería esta...
#fuses intrc_io, nomclr // Oscilador interno (GP4 = I/O) y sin Master Clear (Pin sólo entrada)
Luego, quieres leer un valor arriba de 512, pero estás usando el ADC a 8 bits, así sólo conseguirás 255 máximo.
Entonces cambia la configuración a 10 bits, para obtener una lectura de 1023 cómo máximo.

Si se pueden comunicar los PIC sin usar un MAX232 y también se puede hacer una interfaz PIC-PC sin el MAX232
De eso también hay temas en el Foro.

Saludos.
Muchas gracias D@rkbytes.
Lo olvide por completo por que pense configurarlo ya en el programador al momento de grabarle el codigo al MCU.

con la linea de configuracion si arranca bien pero....

no cambia el valor de "Value" se queda fijo y se queda un solo led parpadeando, no importa lo que pase.

Cambie el ADC a 8 bits, modificando los ifs a 255 y 256 y entonces se queda el otro led (GP4) parpadeando (esto sin que que varie "Value") seguire revisando a ver si lo logro hacer andar par anetonces pasar a la comunicacion serial.

--------------------------------------------------------------------

y corrio!, solo que lo reescribi de 0, este si es un programa que escribi yo, no como el anterior.

Código:
/*programa sencillo con le 12f675
Lee el GP0 como analogo
y proyecta sobre ds leds (GP4, GP5)
si el resultado es mayor o menor de la mitad
del potenciometro */
#include <12f675.h>
#fuses NOWDT,NOMCLR,INTRC_IO//con reloj interno, sin MCLR
#device ADC=10 //si se usan 8 bits, cambiar el if a 255
#use delay(clock = 4000000) 
#define lector PIN_A0

double valor; //por que double?, no se... me marcaba error con int asi que le dije double.

void main(){
set_tris_a(1);//solo usare GP0 como entrada
setup_adc_ports(AN0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_ms(10);

while(TRUE){
valor=read_adc();
delay_ms(25);
   if (valor>512){
      output_bit(PIN_A5,0);//apago el que no uso
      output_bit(PIN_A4,1);//enciendo el que me intereza
      delay_ms(250);
      output_bit(PIN_A4,0);//y lo hago parpadear
      delay_ms(250);
   }//if
   else{
      output_bit(PIN_A4,0);//proceso contrario
      output_bit(PIN_A5,1);
      delay_ms(250);
      output_bit(PIN_A5,0);
      delay_ms(250);
  }//else
}//while

}//main

funciona muy bien, da unos saltos raros en el valor del adc (que si primero 2 y luego 5) y asi va subiendo, usare otro potenciometro mas grande.
Mañana monto este circuito y probare la comunicacion serial con el F84
 
Última edición:
Cambia el tipo de la variable "valor", al usar el tipo Double conseguirás una lectura de hasta 12615560
Utiliza por ejemplo ---> unsigned int16 valor;
Así obtendrás la lectura real que será de 1023 al valor máximo de lectura del ADC.

Cómo ya no estás usando funciones, declara esa variable dentro del main para que no sea global.

Saludos.
 
Cambia el tipo de la variable "valor", al usar el tipo Double conseguirás una lectura de hasta 12615560
Utiliza por ejemplo ---> unsigned int16 valor;
Así obtendrás la lectura real que será de 1023 al valor máximo de lectura del ADC.

Cómo ya no estás usando funciones, declara esa variable dentro del main para que no sea global.

Saludos.

muy cierto, en esto de computacion es de buena costumbre ahorrar recursos, se me han olvidado "las buenas costumbres", mira esto D@rkbytes.

para el 12f675
Código:
/*programa sencillo con le 12f675
Lee el GP0 como analogo
y proyecta sobre ds leds (GP4, GP5)
si el resultado es mayor o menor de la mitad
del potenciometro */
#include <12f675.h>
#fuses NOWDT,NOMCLR,INTRC_IO//con reloj interno, sin MCLR
#device ADC=10 //si se usan 8 bits, cambiar el if a 255
#use delay(clock = 4000000) 
#use rs232 (baud=9600,XMIT=PIN_A1,RCV=PIN_A2,BITS=8,PARITY=O)
            //Velocidad:                9600 bits por segundo (bps)
            //Pin de Transimisión:              PIN_A1
            //Pin de recepción                  PIN_A2
            //Numero bits de datos:                8
            //Tipo de paridad:                impar, solo pa probar

void main(){
unsigned int16 valor;
set_tris_a(1);//solo usare GP0 como entrada
setup_adc_ports(AN0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_ms(10);

while(TRUE){
valor=read_adc();
delay_ms(25);
putchar(1);
printf("%lu",valor);

}//while

}//main


para el 16f84

Código:
#include <16f84.h>
#fuses rc
#use delay (clock = 4M)
#use rs232(baud = 9600, Parity = O, RCV = PIN_A0, xmit = PIN_A1, BITS = 8)

#define LCD_ENABLE_PIN  PIN_B1
#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_B2
#define LCD_DATA4       PIN_B4
#define LCD_DATA5       PIN_B5
#define LCD_DATA6       PIN_B6
#define LCD_DATA7       PIN_B7
#include <lcd.c>

void main(){

lcd_init();
delay_ms(100);

unsigned int16 valor1;
lcd_gotoxy(1,1);
   printf(lcd_putc,"Valor = ");
   lcd_gotoxy(1,9);
while(TRUE){

   valor1 = getch();   
   printf(lcd_putc,"%lu",valor1);
   delay_ms(100);
}//while

}

y el circuito:



estube jugando con la comunicacion serial desde el 12f675 pero no logro que el 16f84 me muestre bien los datos (esto podria ser en porcentaje?, un valor decimal?, lo que sea).

da saltos de la nada, sin que mueva el potenciometro, y ya esa ultima prueba solo marca 1.

en fin he aprendido mucho (leer el adc, comunicacion serial, seteo de bits, manejar un lcd) me emociona mucho este nuevo lenguaje para mi (C)
 
Última edición:
estuve jugando con la comunicación serial desde el 12f675 pero no logro que el 16f84 me muestre bien los datos (esto podría ser en porcentaje?, un valor decimal?, lo que sea).

da saltos de la nada, sin que mueva el potenciómetro, y ya esa ultima prueba solo marca 1.
El problema es que en la comunicación serial RS-232 solamente puedes enviar un Byte.
Por lo tanto ahora para comunicarte con el 16F84A, tienes que bajar la resolución del ADC a 8 Bits.
Declara una variable int8 en el transmisor, y los datos mándalos sin formato, usando unicamente putc (valor);
Ya en el código del receptor le puedes dar formato para mostrar el valor en la pantalla.
Pero ahora la variable de recepción de datos la creas del tipo char.
Así sería el código entonces...
Código:
void main(){

char valor;

   lcd_init();
   lcd_putc("\fValor =");
   
while(true){
   valor = getc();
      lcd_gotoxy(9,1);
         printf(lcd_putc,"%03u",valor);
      delay_ms(100);
   }  // fin while
}  // fin main
Saludos.
 
El problema es que en la comunicación serial RS-232 solamente puedes enviar un Byte.
Por lo tanto ahora para comunicarte con el 16F84A, tienes que bajar la resolución del ADC a 8 Bits.
Declara una variable int8 en el transmisor, y los datos mándalos sin formato, usando unicamente putc (valor);
Ya en el código del receptor le puedes dar formato para mostrar el valor en la pantalla.
Pero ahora la variable de recepción de datos la creas del tipo char.
Así sería el código entonces...
Código:
void main(){

char valor;

   lcd_init();
   lcd_putc("\fValor =");
   
while(true){
   valor = getc();
      lcd_gotoxy(9,1);
         printf(lcd_putc,"%03u",valor);
      delay_ms(100);
   }  // fin while
}  // fin main
Saludos.

Muchisimas gracias por esa respuesta D@rkbytes :aplauso:

nunca pense que seria por ahi el problema, ya corregido (y aprendido)

me pregunto...
¿que pasaria si en esta linea

#use rs232 (baud=9600,XMIT=PIN_A1,RCV=PIN_A2,BITS=8,PARITY=O)

modifico BITS a 10?

lo digo por #DEVICE ADC=10

quiero decir, puedo modificar el valor de bits hasta el valor que necesite para transmitir data?

Estube montando el circuito pero tengo problemitas con los LCD, en tanto lo haga andar aviso.
 
¿que pasaria si en esta linea

#use rs232 (baud=9600,XMIT=PIN_A1,RCV=PIN_A2,BITS=8,PARITY=O)

modifico BITS a 10?

lo digo por #DEVICE ADC=10

quiero decir, puedo modificar el valor de bits hasta el valor que necesite para transmitir data?
No creo que el compilador te permita subir a 10 bits, haz la prueba y lo comprobarás.

Muchísimas gracias por esa respuesta D@rkbytes :aplauso:

nunca pensé que seria por ahí el problema, ya corregido (y aprendido)
De nada, saludos.
 
Atrás
Arriba