Autor Tema: Ayuda con int AD, lenguaje C  (Leído 5592 veces)

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

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Ayuda con int AD, lenguaje C
« en: 14 de Febrero de 2010, 02:23:30 »
Saludos a todos.

Tengo este problema, hice este programita sencillo pero que no me esta funcionando, lo que hace el programa lee una entrada analoga por RA0, uso interrupciones, luego este valor leido lo envio al LCD uso la libreria "flex_lcd.c" .
El lcd me muesta el mensaje VALOR pero no muestra el valor leido, hasta ahora solo lo estoy simulando en proteus, dejo el codigo para que me ayuden , gracias y saludos.

#include <16f876.h>
#fuses HS,NOWDT,NOPUT
# DEVICE ADC=8 //ADC usa 8 bit
#use delay(clock=20000000) // defino el crystal a utilizar
#use fast_io(C)
#define LCD_RS PIN_B1
#define LCD_RW PIN_B2
#define LCD_E PIN_B3
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#include "flex_lcd.c"

#byte port_a= 0x05
#byte port_c= 0x08

int flag_int_ad=0, i=0;

/************************************************** **************
/********************* RUTINA DE INTERRUPCION AD ****************/
# INT_AD

void AD_isr(){
flag_int_ad=1;
i=Read_ADC(ADC_READ_ONLY); // lee el valor digital del ADC
}

/************************************************** **************
/*********************** PROGRAMA PRINCIPAL ********************/
void main(){

    set_tris_a(0x01); /* el pin RA0 como entrada */
    set_tris_b(0); /* el portb como salida */
    set_tris_c(0); /* el portc como salida */

    lcd_init(); /* inicializo en LCD */

enable_interrupts(INT_AD); // hab. int AD
enable_interrupts(GLOBAL); // hab. int global
SETUP_ADC(ADC_CLOCK_INTERNAL); // config para que el a/d funcione con reloj del uC
SETUP_ADC_PORTS(AN0); // RA0 será analógico
SET_ADC_CHANNEL(0); // vamos a usar el canal RA0

lcd_gotoxy(1,1); /* inicia en la primera linea del LCD */
printf(lcd_putc,"Valor"); /* muestra en el LCD */
delay_ms(1);

   while(1){
      if(flag_int_ad==1){
      output_c(i); /* muestro en el portc el valor leido */
      lcd_gotoxy(1,2); /* inicia en la segunda linea del LCD */
      printf(lcd_putc,i); /* envio al LCD el valor leido */
       }
      while(flag_int_ad==0){
      }
   }
}

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda con int AD, lenguaje C
« Respuesta #1 en: 14 de Febrero de 2010, 04:54:55 »
La interrupción del ADC salta cuando ha terminado de hacer la conversión, pero para ello, antes ha de iniciarla.

Te recomiendo que en tu programa, antes del while, pongas esto:
 Read_ADC(ADC_START_ONLY);

Y en la interrupción, hagas lo siguiente:
void AD_isr(){
flag_int_ad=1;
i=Read_ADC(ADC_READ_ONLY); // lee el valor digital del ADC
Read_ADC(ADC_START_ONLY);
}

De esta manera, cada vez que leas un dato, lanzas el ADC para capturar el siguiente. Si necesitas cambiar la frecuencia de captura y hacerla más lenta, saca el último READ_ADC de la interrupción y lo pones dentro de tu bucle While, detrás de las operaciones que quieras realizar.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Ayuda con int AD, lenguaje C
« Respuesta #2 en: 14 de Febrero de 2010, 10:10:19 »
Ademas de lo expuesto por Nocturno....

En el programa hay algo que no entiendo del todo. No le encuentro el sentido a la variable "flag_int_ad".
Veo que la usa dentro del while, para cuando esté en 1 hacer la representación en el LCD. Pero el tema es que nunca la está llevando a 0. Digo, cuando se ingresó por primera vez a la interrupción se pone en 1, pero se queda así para siempre porque en ningún lugar se pone a 0. Para llevarla a 0 habría que agregar una línea al final del if que borre dicha variable y así se ingresaría en el ciclo "while (flag_in_ad == 0)"
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Ayuda con int AD, lenguaje C
« Respuesta #3 en: 14 de Febrero de 2010, 11:55:00 »
Mas alla de lo que te aconseja Manolo, creo que no muestra en el display por una razon muy fuerte, no tienes el indicador de que quieres mostrar en el printf.
Es raro deberia haberte dado un error al compilar :shock:

Código: C
  1. while(1){
  2.       if(flag_int_ad==1){
  3.       output_c(i); /* muestro en el portc el valor leido */
  4.       lcd_gotoxy(1,2); /* inicia en la segunda linea del LCD */
  5.       printf(lcd_putc,i); /* envio al LCD el valor leido */
  6.        }
  7.       while(flag_int_ad==0){
  8.       }

Deberia ser asi:

Código: C
  1. while(1){
  2.       if(flag_int_ad==1){
  3.       output_c(i); /* muestro en el portc el valor leido */
  4.       lcd_gotoxy(1,2); /* inicia en la segunda linea del LCD */
  5.       printf(lcd_putc "%u",i); /* envio al LCD el valor leido */   <<<<<<<<< aqui modificacion
  6.        }
  7.       while(flag_int_ad==0){
  8.       }
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #4 en: 17 de Febrero de 2010, 23:52:30 »
Gracias a todos por sus respuestas.

Antes que nada pido disculpas a todos por la demora tuve algunos problemas.
Bueno ahora lo nuestro, Angelgris me hace una muy buena observacion respecto al flag_int_ad el cual corregi de inmediato se me paso, zorry.  Por otro lado existe alguna diferencia en poner printf(lcd_putc, "%u",i) y poner printf(lcd_putc "%u",i) fijense en la coma  el compilador lo considera igual.
El programa ya esta funcionando, gracias Nocturno por tus concejos, pero aparecio otro problema el cual explico: el proteus esta simulando bien ya puedo ver los valores en el lcd (de 0 a 255) pero cada vez que RA0 recibe de 2.5v a menos  el primer digito de derecha a izq. se queda en el lcd,  dejo una imagen deberia de estar 51 pero esta 511 el sgte es 25 pero aparece 251 etc si subo a mas de 2.5 se corrige ademas el potenciometro esta de color plomo esto significa algo? ver imagen espero se me haya entendido.
Gracias a todos y saludos.

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #5 en: 17 de Febrero de 2010, 23:54:37 »
Aqui esta la imagen.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda con int AD, lenguaje C
« Respuesta #6 en: 18 de Febrero de 2010, 02:10:59 »
EL problema es que a veces tu número ocupa 3 dígitos, y cuando se reduce a sólo 2 dígitos no borra el de la derecha.
Para eso tienes la opción de fijar el tamaño de lo que imprimes, de manera que quede justificado a la derecha:

printf(lcd_putc,"%3u",i);

o también tienes la opción de dibujar un espacio detrás del número, lo que te lo justificará a la izquierda:

printf(lcd_putc,"%u ",i);

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Ayuda con int AD, lenguaje C
« Respuesta #7 en: 18 de Febrero de 2010, 09:32:17 »
Tal cual te lo explica Nocturno.
En cuanto al color plomo de la simulación, es debido a que el nivel de señal no puede ser considerado ni un 1 lógico (si fuera así se vería rojo) ni un 0 lógico (se vería azul) ya que teiene algún valor intermedio. En otras palabras, no le des importancia.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #8 en: 19 de Febrero de 2010, 01:21:01 »
Hola amigos.

Todo esta mucho mejor en el proteus ya esta todos bien. Les cuento que termine de construir mi propio entrenador de pic y estaba probando el programita que le mostre antes aun no logro arrancar el lcd pero debe ser por algun problema de hardware, ademas estoy probando los pines del pic y los leds de mi entrenador.
Encontre algo bien extaño, para probar los led hice este programita y resulta que no prende el pin RA4 ni en el proteus ni en mi tarjeta, los otros pines si prenden dejo el codigo.

#include <16f876.h>
#fuses   HS,NOWDT,NOPUT
#use     delay(clock=20000000)  // defino el crystal a utilizar
#use     fast_io(a)
 
void main()
{
      set_tris_a(0) ; //porta como salida
      output_a(0) ;   //reset al porta

 do{
   output_a(0x04); delay_ms(100); /* 00000100 prende RA2 */
   output_a(0x08); delay_ms(100); /* 00001000 prende RA3 */
   output_a(0x10); delay_ms(100); /* 00010000 prende RA4, este no prende */
   output_a(0x20); delay_ms(100); /* 00100000 prende RA5 */
 }
  while(true); 
   
}

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda con int AD, lenguaje C
« Respuesta #9 en: 19 de Febrero de 2010, 02:40:08 »
Mira la datasheet del micro y verás que ese pin es distinto al resto  :D

Bueno, mejor mira esto: El PORTA de los PIC's y una de sus particularidades : RA4

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #10 en: 20 de Febrero de 2010, 00:33:50 »
Hola nocturno.

Gracias por el dato, eso del RA4 sinceramente no sabia solo hay que ponerle una resistencia pull up y listo. Cambiando de tema cuando hacia mis programas en assembler y queria depurar recuerdo que usaba  la tecla F7 (step into) para hacerlo de linea en linea y tambien podia meterle estimulos , mi pregunta es en el CCS donde puede hacer ese tipo de pruebas.
Por otro lado quiero mostrar en el lcd datos de 0 a 50 pero recibo por el RA0 datos analogos de 0 a 255 no se me ocurre nada para hacer el algoritmo, hechame una mano gracias y saludos.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Ayuda con int AD, lenguaje C
« Respuesta #11 en: 20 de Febrero de 2010, 00:58:24 »
CCS no tiene simulador, pero puedes trabajar con CCS desde MPLAB y hacer los mismo o usar proteus. Luego para solucionar el tema de mostrar datos en el LCD con la regla de tres simple se soluciona  :mrgreen:


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #12 en: 21 de Febrero de 2010, 23:57:31 »
Hola Suky

Gracias  por tu respuesta, tienes razon me di cuenta de mi error luego, con una regla de tres funciona muy bien y para simularlo desde proteus hago lo sgte:
Source - Add/Remove source code files
Se abre una ventana Add/Remove source code files
busco mi programa en  : Source code filename (extencion .c)
selecciono el CCSC en: Code Generation Tool , aqui esta mi problema no encuentro esta opcion, uso el Proteus  Portable 7.1 SP2 , mi Proteus 7.2 se cierra a cada rato por eso no lo uso.
Que puede ser gracias y saludos.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Ayuda con int AD, lenguaje C
« Respuesta #13 en: 22 de Febrero de 2010, 10:13:12 »
Intenté responder anoche pero no sé si falló el sitio o mi conexión a internet.

Yo compilo desde el MPLAB, sea con Hitech o sea con CCS.
Simulo en Proteus y cuando cargo el programa en el PIC elijo el archivo .COF (que se genera al compilar). Cuando inicio el debug se carga automáticamente el archivo .C correspondiente y de esa manera ya podés simular paso a paso tranquilamente.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda con int AD, lenguaje C
« Respuesta #14 en: 23 de Febrero de 2010, 00:49:15 »
Hola AngelGris

Si no es mucho pedir  cuales son los pasos para simular ccs desde Mplab v8.00 con esta vesion hice algunos programitas,  en lenguaje C, bastante sencillos para dspic.