# Error en frecuencimetro escrito con ccs simulado con proteus



## dani_pic (Ago 13, 2008)

¡Hola a todos!

Posteo esto a ver si alguien me puede echar una mano en lo siguiente:

Estoy programando un frecuencimetro (forma parte de un afinador) para leer unas señales cuadradas y la idea que vengo desarrollando es esta:

- La señal cuadrada (de entre 40 y 100 Hz) entra por el RB1 y mediante la interrupcion externa INT1 a cada flanco de subida de la señal voy incrementando un contador. Cada 6 flancos (contador=6) miro el contenido del timer 1 que es el que utilizo para contar y de ahí saco la frecuencia. Después ese valor (freq) lo quiero mostrar por pantalla LCD.

Al compilarlo el CCS no me da ningun error pero, cuando simulo con proteus veo que el fallo está en la parte del codigo que he escrito para usar el LCD.

Deciros tambien q el puerto A me lo reservo para futuros pulsadores y para usar unos leds y que me comunico con el LCD mediante el puerto C.

Os adjunto el código que compilo,

¡Muchas gracias!


----------



## lmct (Ago 13, 2008)

Hola, no se si es tu caso, pero por si acaso te lo comento, la libreria lcd.c, no esta preparada para manejar el puerto c, para ello tiene que abrir dicha libreria y cambiar la direccion del puerto que por defecto es el "d" por el puerto "c"

#if defined(__PCH__)
#if defined use_portb_lcd
   #byte lcd = 0xF81                   // This puts the entire structure
#else
//   #byte lcd = 0xF83         This puts the entire structure direccion puerto d anulada
   #byte lcd = 0xF82   // para gestionar el puerto c 
#endif
#else
#if defined use_portb_lcd
   #byte lcd = 6                  // on to port B (at address 6)
#else
//   #byte lcd = 8                 on to port D (at address 8) anulada
   #byte lcd = 7             // para el puerto c 
#endif
#endif

aqui el codigo que tiene que modificar he anulado las lineas correspondientes al puerto d y he añadido las del puerto c

por lo demas tiene que funcionar... no esta demasiado bien estructurado pero deberia funcionar.


----------



## lmct (Ago 13, 2008)

perdona me he dejado de poner el codigo corregido que esta mal
la funcion debe ser asi

void escribir_pantalla(){

   // NO HACE FALTA YA ESTA INICIALIZADO EN MAIN lcd_init();
   lcd_gotoxy(1,1);

  // ASI NO FUNCIONA ESTO ES PARA EL PUERTO SERIE   printf("%3Lu",freq);
      printf(lcd_putc,"%3Lu",freq);  // esto es lo correcto hay que añadir el comando lcd_putc
   enable_interrupts(INT_EXT1);
}

Saludos


----------



## dani_pic (Ago 14, 2008)

Gracias por la respuesta, lmct, he cambiado lo que me dijiste y ahora cuando simulo con proteus me sale el siguiente mensaje de alerta:

"PC=0x442. The SCSx bits have been set. This feature is not modelled - the model continues to clock itself as before"

Veo que el mensaje hace referencia a la linea de mi programa en la que paso los parametros del oscilador:


```
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
```


Tambien sale otro mensaje referente a la lcd que dice:

"Controller received command whilst busy"


Realmente ahora mismo no se que debo modificar para que se solucione, cualquier ayuda que me deis será de agradecer chicos.

¡Un saludo!


----------



## lmct (Ago 14, 2008)

Hola, que tal.
Bueno yo el proteus no lo manejo. Ha lo mejor no estoy en lo cierto, pero 
Setup_oscillator no forma parte del lenguaje CCS, en el archivo de cabezera ya hay algo como esto #use delay(clock=4000000), que es lo que define el clock. Pero a lo mejor setup oscillator forma parte del proteus no lo se.
Tambien he observado que el el main no tienes el bucle cerrado, posiblemente el problema del display sea este pon esto para probar

void main()
{


  // SET_TRIS_E(0x0);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();

   setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);

   ini_timer();

   enable_interrupts(INT_EXT1);
   enable_interrupts(GLOBAL);
 //añadido esto

 while (true) 
  {
    // esto evita que se repitan las instrucciones de arriba, que ya han sido
   // inicializadas y da continuidad al programa
    }

}

Saludos


----------



## ElVale (Ago 18, 2008)

Haz que freq sea float y no long


----------



## dani_pic (Ago 18, 2008)

Muy buenas,

Pues bueno, la cosa sigue sin ir, de momento el error que me da proteus sigue siendo el mismo referente al LCD:

Controller received data whlts busy  

 

Está claro que la estoy liando en el codigo del CCS pero no tengo ni idea donde.

Por cierto, lmct, en la version de CCS que manejo 4.038, usando el project wizard, te pregunta a que frecuancia trabajara el micro (en mi caso 4Mhz, utilizando el oscilador interno del 18f2520), así que no se si seguirá siendo necesario definirlo yo a mano

¡Saludos!

EDIT:
tambien he cambiado freq por un float ^^


----------



## lmct (Ago 20, 2008)

Hola, bien pues vamos a probar esto a ver que pasa puede que el problema este en el formato de la variable. si esto funciona por lo menos sabras que el display esta bien. Pon esto justo encima del main. El problema puede estar en el tipo del formato de datos creo que faltan numeros.

printf(lcd_putc, "\f Frecuencimetro V1.1");
delay_ms(5000);

tambien puedes probar a cambiar el formato he puesto mas digitos a ver si es que la variable es mas grande de 3 digitos y no la puede mostrar. He colocada 6 digitos, antes borro la pantalla, pon la variable en long
printf("/f%06Lu",freq);

Saludos


----------



## dani_pic (Ago 25, 2008)

Perdona por no responder antes, he estado aislado sin internet durante estos dias 
Mañana tendré mi ordenador a mano con el proyecto y probaré lo que me has dicho a ver si funciona.

Os contaré que tal ha ido.


----------



## dani_pic (Ago 27, 2008)

Nada chicos, que no funciona:

"Controller received command whilst busy" 


 Os adjunto el proyecto en proteus tambien para que le echeis un vistazo a ver donde puede estar el fallo...  

Que desesperación... sin esto no voy a terminar el proyecto nunca 
 

¡un saludo!


----------



## OZONO (Mar 4, 2011)

Chicos, probablemente estén usando una interrupción que les envia mensajes al LCD, se soluciona haciendo un retardo de 20ms antes de enviar el mensaje


----------



## MerLiNz (Mar 7, 2011)

Te ha pasado exactamente lo mismo que a mi cuando intente usar un LCD por primera vez, evita usar los puertos RC0, RC1 y RC2, estos se usan para otras cosas (tendrias que mirarte el datasheet), supongo que se podrian declarar como I/O pero te es mas sencillo usar otro puerto como el RB o bien usar RC4, 5 ,6, 7 para los bits del LCD y para RS, E, RW usar RB por ejemplo.

Si te fijas cuando simulas se te pone en gris estos puertos, es por eso porque estan haciendo otro uso.


----------



## jjpl2001 (Jul 26, 2011)

No compadre!! estan lanzando flechas!! el problema no lo tiene proteus ni el programa del amigo... es un problema con el CCS... algo que cambiaron que no logro dar con la fallita!! yo tengo varias versiones del CCS cuando instalo la version 4.106 me compila perfecto PERO cuando actualizo a cualquier version despues de la 4.109 me aparece el error "controller LCD received data whilst busy" es algito con el clear flag o con algun delay que no encuentro.. voy a probar instalando 4.106 y guardando aparte la libreria lcd.c y despues acualizo y sobreescribo la vieja libreria e ver que talco!



> Controller received data whlts busy


Listo men, instale la version 4.106 y guarde la libreria lcd.c luego instale la 4.120 y reemplase la nueva lcd.c con la del 4.106 y ya no me da el error de Controller received data whlts busy


----------



## MerLiNz (Jul 27, 2011)

Ese error es que se ha intentado una operacion en el LCD mientras este estaba ocupado con alguna operacion, es decir le falta algun delay.

Si unicamente quieres simular en el proteus le subes la frecuencia a la LCD y se arregla, para la realidad ya debes poner el delay que le corresponde.


----------



## jjpl2001 (Jul 27, 2011)

> Ese error es que se ha intentado una operacion en el LCD mientras este estaba ocupado con alguna operacion, es decir le falta algun delay.
> 
> Si unicamente quieres simular en el proteus le subes la frecuencia a la LCD y se arregla, para la realidad ya debes poner el delay que le corresponde.



Algo asi pero no totalmente.

A partir de la version 4.107 cambiaron unas 3 lineas de codigo en la libreria LCD.c esto anda bien en el mundo real pero por alguna razon se queda pegado en proteus... es como una pelea entre marido y mujer con el proteus y el CCS. Son precisamente unos delay que añaden no que quitan y creeo que por error pusieron estan leyendo en vez de la pata RW estan leyendo otra! son como 4 lineas.

Si abres un LCD.c de una version anterior como la 4.106 y abres una del 4.110 en adelante te daras cuentas de esas 3 o 4 lineas diferentes y que tienen un errorcillo. ya lo probe saludos!


----------



## MerLiNz (Jul 27, 2011)

Si lo que estan equivocado son los pines unicamente se esperara un comportamiento erroneo del LCD, pero si el error que te pone el proteus es ese significa eso, que has enviado datos mientras este estaba procesando otros comandos/datos.
Es posible que el cambio que veas sea que el codigo que te funcione utiliza la lectura del flag busy y mientras este activado no se escribe.
Sin embargo con delays funciona correctamente sin tener que leer el flag busy, unicamente debes calcular el tiempo entre comando y comando, si te lees un datasheet de una lcd veras que no todos los comandos tardan el mismo tiempo en hacerse efectivos, pues siguiendo esto ya sabrias que delay aplicarle.
Aun asi si solo se utiliza con motivos educacionales, le subes al LCD la frecuencia (mediante 2 clicks en el LCD en el proteus) y se arregla.

Yo me he hecho mi propia libreria glcd, y lo pruebo mediante el proteus, por eso te lo comento, porque me ha pasado y es unicamente eso.

El proteus emula lo que tu le escribas, no es porque haya incompatibilidad, es porque el codigo no esta correcto, el unico problema de emulacion que me ha dado el proteus ha sido cuando he probado a ponerle el modo extendido, nunca me ha funcionado bien, con C18 si, pero con mikroC no.


----------



## henry mora (Sep 30, 2011)

Este es un error de tiempos ps para simularlo en proteus ps es necesario tener en cuenta varias cosas bueno ara q no haya congestion de datos en la lcd en la simulacion y para q visualice lo q queremos ver es importante tener en cuenta q hayamos inicializado la lcd con la funcion lcd_int(), supongamos q el mensaje q queremos utlilizar es hola mundosimplemente le damos un retardo de tiempo mayor a 20ms "ud delay", tambien tienen q fijarse bien en la conexion pic lcd por defecto en el 16f877a se utiliza el puerto d aunq esto tamnien se puede mmodificar, pero si basicamente esa es la forma como se quita el error o bueno esa es la forma q pude quitar el error


----------



## donfructuoso (May 22, 2012)

Solucion al error "Controller received data whilst busy" en la simulacion con Proteus en lenguaje C del CCS y PIC 18F4550.

Según mi experiencia modificando la funcion "void lcd_send_byte( BYTE address, BYTE n )" que vien en lcd.c se puede simular sin errores el LCD en Proteus

La función modificada quedaría así:

void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;  //Original
      delay_ms(10);    //Añado un retardo para que funcione la simulación en Proteus
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}

Creo que el problema se debe a que se "pisan" los comandos o los datos en el envío y/o recepción. Añadiendo la línea "delay_ms(10);    //Añado un retardo para que funcione la simulación en Proteus" se soluciona.

En ejecución real del programa en el PIC (según mi experiencia) se visualiza correctamente siempre que conectemos correctamente los puertos.

El programa en c bajo el que se simula correctamente el LCD es el siguiente:


#include <18f4550.h>
#fuses hs,nowdt,noprotect,nolvp
#use delay(clock=20000000)
#use standard_io(B)
#define use_portB_lcd TRUE
#include <lcd.c>


/*


El sistema funciona correctamente

*/

void main()
{

      int x;
      lcd_init();

      while (1)
      {

            printf(lcd_putc, "\f Uno");
            delay_ms(100);

            printf(lcd_putc, "\f Dos");
            delay_ms(500);

            printf(lcd_putc, "\f Tres");  
            delay_ms(1000);

            printf(lcd_putc, "\f Cuatro");   
            delay_ms(2000);

            printf(lcd_putc, "\f Cinco");     
            delay_ms(3000);           


            x = 0;


      }
}


----------



## unic (Ene 25, 2017)

buenas, tuve el mismo problema y lo solucione cambiando en el LCD de 250Kz a 4MHz correspondientes a mi oscilador de 4MHz. Saludos


----------

