Autor Tema: problema con delay_ms(1000); no da la espera de 1 seg.  (Leído 8794 veces)

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

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
problema con delay_ms(1000); no da la espera de 1 seg.
« en: 28 de Abril de 2014, 01:59:42 »
Hola, quisiera que me ayudaran a resolver un problema que tengo, resulta que tengo un problema con la funcion  delay_ms(1000);, el problema radica en que en lugar de esperarse 1 segundo se espera 4, realice un programa sencillo para averiguar si tenia algún problema de configuración, como información adicional he probado con un oscilador de 4 Mhz y uno de 20 Mhz, configurando su respectivo #use delay(clock=4000000), físicamente tengo el oscilador con capacitores de 22pF, a continuación les dejo mi código de ejemplo, espero me puedan ayudar, gracias

Código: [Seleccionar]
/////////////////////////////////////////////////////////////////
// programa para prender un led y apagarlo cada segundo        //
//                                                             //
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
///// Created by Uriel                             //////////////
/////                                              //////////////
/////////////////////////////////////////////////////////////////
#include <18F4550.h>


#Fuses HS, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL1, CPUDIV1, VREGEN

#use delay(clock=4000000)

void main()
{
   

   DO{
         // enciende led conectado a RB1
      output_high(PIN_A1);
      delay_ms(250);
      output_low(PIN_B5);   // enciende led conectado a RB1
      delay_ms(10);
      if(input(PIN_B4)==0){
         output_low(PIN_B1);
      }else{
         output_high(PIN_B1);
      }
      output_low(PIN_A1);
      delay_ms(250);
   }
   while (TRUE);
}

/////////////////////////////////////////////////////////////////



con el código anterior logro el retardo de 1 segundo, pero debería de ser solo de 250 mili-segundos, por cierto a excepción del tiempo todo funciona bien, un led parpadea y el otro enciende dependiendo de un botón que tengo conectado.

Desconectado EdoNork

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 616
    • ElektroQuark
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #1 en: 28 de Abril de 2014, 05:48:33 »
¿Cómo es la función delay_ms() que utilizas?
Mi blog sobre electrónica y cosillas afines: www.elektroquark.com
EQVideo en Youtube
El foro de KiCad en castellano.
Mi librería para KiCad ¡AQUÍ!

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #2 en: 28 de Abril de 2014, 08:21:27 »
Una aclaración, usas el B4 como entrada y el B1, B5 y A5 como salida? 
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado zivit

  • PIC10
  • *
  • Mensajes: 22
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #3 en: 28 de Abril de 2014, 09:16:16 »
Hola,

si te lees el Datasheet del Pic, podrás encontrar que internamente el micro no trabaja a la frecuencia real del oscilador, sino que trabaja a Fclk = Fosc/4 eso significa que realmente tienes un clock de 1Mhz cuando trabajas con el Osc de 4MHz.

Entonces donde defines la frecuencia del CLK debes poner 1000000; #use delay(clock=1000000). Así ahora el tiempo que buscas se ajustara al del retardo.

Espero que te sirva.

Un Saludo.

Zivit.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #4 en: 28 de Abril de 2014, 09:35:23 »
Fuses HS le dice al compilador que es un cristal mayor a 4 Mhz, en tu caso deberas poner Fuses XT.

Por otro lado, debes declararle la velocidad de trabajo interno tambien, aqui tienes una nota de CCS al respecto:
https://www.ccsinfo.com/newsdesk_info.php?newsPath=ALL&newsdesk_id=164
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5552
    • Picmania by Redraven
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #5 en: 28 de Abril de 2014, 09:52:30 »
¿Qué versión de CCS C usas? porque dependiendo de la versión puede ser que tengas que variar el contenido del #use delay()

Yo, por ejemplo, en un proyecto que estoy haciendo con un 18F46K22 y el CCS C V.5.023 haciendo uso del oscilador interno tuve que poner

Código: CSS
  1. #use delay(clock=16000000,internal=16000000)

Y en otro proyecto con la misma versión del CCS C pero con un 18F2550 pero con Cristal Externo de 20 Mhz tuve que utilizar esto para que me contase en condiciones

Código: CSS
  1. #use delay(clock=20000000,Crystal=20000000)

En caso contrario no me iban bien los Timers o el cálculo de los baudios de la USART.  :shock:

« Última modificación: 28 de Abril de 2014, 09:57:45 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #6 en: 28 de Abril de 2014, 13:48:16 »
Primero que nada gracias a todos por responder tan rapido, ahora, revisando cada comentario:

Fuses HS le dice al compilador que es un cristal mayor a 4 Mhz, en tu caso deberas poner Fuses XT.

Por otro lado, debes declararle la velocidad de trabajo interno tambien, aqui tienes una nota de CCS al respecto:
https://www.ccsinfo.com/newsdesk_info.php?newsPath=ALL&newsdesk_id=164

lo del HS lo deje ya que en realidad pretendo usar un cristal de 20Mhz pero probé con uno de 4Mhz ya que mi cristal de 20 Mhz en lugar de tener impreso 20 000 000 dice 200 000 000 y me hizo pensar que me vendieron mal el oscilador, ahora con respecto a la nota veo que debería usar algo así para el de 20 Mhz
#use delay(crystal=20MHz)
aunque mi duda es si al usar esta instrucción no me afectara para usar los módulos de radiofrecuencia??????, ya que mi aplicación final es un sistema que se comunica a mas pic por RF pero pues debido al problema con los delay realice este programa básico.


Hola,

si te lees el Datasheet del Pic, podrás encontrar que internamente el micro no trabaja a la frecuencia real del oscilador, sino que trabaja a Fclk = Fosc/4 eso significa que realmente tienes un clock de 1Mhz cuando trabajas con el Osc de 4MHz.

Entonces donde defines la frecuencia del CLK debes poner 1000000; #use delay(clock=1000000). Así ahora el tiempo que buscas se ajustara al del retardo.

Espero que te sirva.

Un Saludo.

Zivit.

hola, supongo que con la modificación que sugiere MGLSOFT se resuelve el problema de que el micro trabaja a  Fclk = Fosc/4 cierto?, o tendría aun asi que dividirlo entre 4??? y si es así, no me afecta con lo que comento de los módulos de RF??

Una aclaración, usas el B4 como entrada y el B1, B5 y A5 como salida? 


sip, uso el B4 de entrada y el B1, B5 y A5 como salida y como comentaba antes eso funciona sin problemas.



¿Cómo es la función delay_ms() que utilizas?


La función delay_ms() es la que ya trae el compilador en sus librerías, ahora mismo no la tengo a la mano pero en la noche que llegue la busco y la publico



¿Qué versión de CCS C usas? porque dependiendo de la versión puede ser que tengas que variar el contenido del #use delay()

Yo, por ejemplo, en un proyecto que estoy haciendo con un 18F46K22 y el CCS C V.5.023 haciendo uso del oscilador interno tuve que poner

Código: CSS
  1. #use delay(clock=16000000,internal=16000000)

Y en otro proyecto con la misma versión del CCS C pero con un 18F2550 pero con Cristal Externo de 20 Mhz tuve que utilizar esto para que me contase en condiciones

Código: CSS
  1. #use delay(clock=20000000,Crystal=20000000)

En caso contrario no me iban bien los Timers o el cálculo de los baudios de la USART.  :shock:




En este momento no recuerdo que version es, pero lo reviso y lo publico


Gracias a todos y espero que puedan ayudarme con las dudas que aun tengo, en la noche probare las modificaciones que me sugieren y les comento que pasó

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #7 en: 29 de Abril de 2014, 00:47:55 »
Hola, tengo el compilador PCWHD versión 4.114

modifique el delay asi
#use delay(clock=20MHz, crystal)

y los delay_ms(250); duran 5 segundos, mi oscilador es de 20 Mhz y los fuse están así
#Fuses HS, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL1, CPUDIV1, VREGEN

hice la prueba de usar el oscilador interno poniendo esto
#use delay(clock=4MHz, internal)

y el delay de 1 segundo dura exactamente eso, que podrá ser, físicamente tengo conectado a los pines 13 y 14 el oscilador de 20Mhz (OSC1 y OSC2) posteriormente tengo capacitores de 22 pF a tierra

por cierto hay algo extraño, si lo programo por ejemplo a 4Mhz con reloj externo y le conecto el oscilador de 20 Mhz no veo ninguna diferencia en tiempo con el de 4 Mhz,  y en otro experimento que hice le quite el oscilador  los capacitores y sigue funcionando exactamente igual, porque???????
« Última modificación: 29 de Abril de 2014, 01:11:47 por urielm80 »

Desconectado solapower

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 209
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #8 en: 29 de Abril de 2014, 05:06:04 »
Estás verificando el funcionamiento en un circuito montado realmente o en un simulador ?
Si utilizas Proteus pudiera ser que no tuvieras bien configurado el oscilador en las propiedades del micro,
me induce a pensar en ello el hecho que comentas de que quitándole el cristal también te funciona.
Saludos

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #9 en: 29 de Abril de 2014, 13:08:29 »
Estás verificando el funcionamiento en un circuito montado realmente o en un simulador ?
Si utilizas Proteus pudiera ser que no tuvieras bien configurado el oscilador en las propiedades del micro,
me induce a pensar en ello el hecho que comentas de que quitándole el cristal también te funciona.
Saludos

lo estoy probando realmente, lo tengo en una protoboard, lo que hice fue desconectarlo de la pc, quitar oscilador y capacitores y volverlo a conectar al usb y para mi sorpresa seguia funcionando exactamente igual aun cuando lo programe con la configuracion de oscilador externo de 20 MHz y luego de 4 MHz

Desconectado zivit

  • PIC10
  • *
  • Mensajes: 22
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #10 en: 29 de Abril de 2014, 21:01:18 »
El pic tiene una salida del clock interno, en la pata CLKO, prueba a configurarla para que saque el clock, pincha con un osciloscopio y mira que frecuencia te da. Así comprobaras si realmente funciona bien el oscilador. Luego respecto a la función delay(ms), si quieres te la puedes hacer tu mismo, si sabes la frecuencia del reloj, sabes cuanto dura una instrucción, simplemente tienes que hacer una espera de tantas instrucciones (calculas con la formulita). Luego la compruebas con un simulador y calibras el numero de instrucciones para que te clave los ms que le indiques.

También lo puedes calibrar en un timer. Al fin y al cabo un delay provoca la retención del hilo del programa y te puede traer complicaciones si usas WDT ademas de desperdiciar recursos.

No se que tanto afecta a los módulos RF, supongo que te tendrás que comunicar por USART o por otro método con estos, entonces influiría el clock sobre el baudrate, tendrías que saber exactamente a que frecuencia va el CLK.

Mi consejo es que todas las librerías que te puedas ahorrar, ahorratelas picando código a mano, así luego cuando sigas el programa en depuración sabes exactamente que querías hacer, que esta haciendo y si se ajusta a lo que quieres.

Un saludo.

Zivit

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #11 en: 30 de Abril de 2014, 01:11:33 »
El pic tiene una salida del clock interno, en la pata CLKO, prueba a configurarla para que saque el clock, pincha con un osciloscopio y mira que frecuencia te da. Así comprobaras si realmente funciona bien el oscilador. Luego respecto a la función delay(ms), si quieres te la puedes hacer tu mismo, si sabes la frecuencia del reloj, sabes cuanto dura una instrucción, simplemente tienes que hacer una espera de tantas instrucciones (calculas con la formulita). Luego la compruebas con un simulador y calibras el numero de instrucciones para que te clave los ms que le indiques.

También lo puedes calibrar en un timer. Al fin y al cabo un delay provoca la retención del hilo del programa y te puede traer complicaciones si usas WDT ademas de desperdiciar recursos.

No se que tanto afecta a los módulos RF, supongo que te tendrás que comunicar por USART o por otro método con estos, entonces influiría el clock sobre el baudrate, tendrías que saber exactamente a que frecuencia va el CLK.

Mi consejo es que todas las librerías que te puedas ahorrar, ahorratelas picando código a mano, así luego cuando sigas el programa en depuración sabes exactamente que querías hacer, que esta haciendo y si se ajusta a lo que quieres.

Un saludo.

Zivit

gracias por tu respuesta, creo que tienes razon sobre el delay, aunqeu ahora mismo lo que mas me preocua es la comunicacion, tendre que comprarme lso modulitos para probar y ver que tanto me afecta el hecho de que funcione igual con  sin oscilador.

Si alguien tiene alguna explicacion sobre porque me funciona el programa aun sin ocilador y con la configuración de crystal les agradeceria que me lo explicaran

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #12 en: 02 de Mayo de 2014, 15:13:52 »
Funciona igualmente aún sin oscilador porque evidentemente está habilitado el FUSE IESO, que al no detectar cristal externo o detectar un error en el mísmo, cambia al oscilador interno automáticamente.

Saludosl
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #13 en: 02 de Mayo de 2014, 17:11:10 »
Funciona igualmente aún sin oscilador porque evidentemente está habilitado el FUSE IESO, que al no detectar cristal externo o detectar un error en el mísmo, cambia al oscilador interno automáticamente.

Saludosl

Hola BrunoF, gracias por tu respuesta, no sabia de la existencia de ese registro, ya revise el datasheet y pude comprobar su utilidad, aunque no logre encontrar si esta activado por default, en todo caso, como podría hacer para desactivarlo, simplemente con poner FUSE IESO =off ??? o de que manera??

gracias

Desconectado urielm80

  • PIC10
  • *
  • Mensajes: 30
Re: problema con delay_ms(1000); no da la espera de 1 seg.
« Respuesta #14 en: 02 de Mayo de 2014, 17:40:43 »
ya encontre como deshabilitarlo 
Código: [Seleccionar]
#FUSES NOIESO

en la noche probare hacer esto haber si se resuelve la interrogante de que funciona sin oscilador, mm pero aun sigo sin entender porque mis delay no duran lo que deberian, BrunoF sabras por que sucede esto????