TODOPIC

Microcontroladores PIC => Primeros pasos - Iniciación a los microcontroladores => Mensaje iniciado por: kurono02 en 11 de Enero de 2021, 18:31:51

Título: CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: kurono02 en 11 de Enero de 2021, 18:31:51
Buenas tardes,

 Primero los datos generales: Estoy usando Proteus 8.9 para la simulación del circuito y tengo un project board para montarlo en físico. Para compilar estoy usando Pic C compiler 4.104 y estoy usando el PIC16F1827.

 Mi intención es generar un delay sencillo para 1 seg. Estaba probando con la función delay_ms() pero no me da el tiempo correcto. He leído el datasheet y el help del compilador y parece que no he configurado mi función para que quede bien.

Lo que deseo es que los números en mi display vayan cambiando a razón de 1 seg a la vez, pero si uso delay_ms() pasan demasiado rápido. Lo interensante es que con esta última combinación, en la simulación pasan los números pero en físico no.

¿Qué preguntas tienen para poder ayudarme? Gracias de antemano.

#include <16f1827.h>
#FUSES  NOWDT,NOCPD, NOWRT, NOPROTECT, STVREN, NOMCLR, PUT, WDT, INTRC_IO
#USE delay(CLOCK=8M, INTERNAL)

 BYTE CONST DISPLAY[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x67}; // La secuencia del 0-9
 #BYTE PORTB = 0X0D // La dirección del puerto B
 
 //Preparacion de las variables para mapear los registros del timer 0
 #BYTE OPTION = 0x95 // La direccion del OPTION_REG
 #bit  T0IF = 0X0B.2 // Bit del flag de la interrupcion de timer 0
 
 
 void generador_delay()
 {
   INT OVERFLOW=0;
   set_timer0(0);      // Inicializar el timer
   while (OVERFLOW != 31) //Cuando se desborde 31 veces habrá pasado 1 seg
   {
      IF(T0IF)
         {
   
   ++OVERFLOW; //Incrementa el contador de overflows
   T0IF = 0;   // Limpiame el flag para que pueda seguir leyendo
   
         }
   }
 
 }
 



 
void main()
{
   // Declaracion de variables
   int CONTADOR;

   // Habilitando interrupciones
   ENABLE_INTERRUPTS(INT_TIMER0);           //Activa interrupcion del timer 0
   ENABLE_INTERRUPTS(GLOBAL);             //Activa TODAS las interrupciones
   
   
   // Configurando el Timer 0
   OPTION = 0B00000111;
   // (opcional)SETUP_TIMER_0(0B00000111);  Configurar el registro OPTION_REG
   T0IF = 0;  // Limpiar el flag del INTCON de la interrupcion
   
   SET_TRIS_B(0B00000000); //Se establecen los pines de PORTB como salidas
   while(true)
   {
     
     for (CONTADOR = 0; CONTADOR<10; CONTADOR++)
     {
         PORTB = DISPLAY[CONTADOR]; //Muestra el valor actual del elemento del arreglo al que apunta el index llamado CONTADOR
         generador_delay(); // Espera 1 seg antes de mostrar el siguiente valor
         
     }
   
   
   }

   // TODO: USER CODE!!

}
Título: Re:CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: remi04 en 11 de Enero de 2021, 19:27:38
Si quieres obtener 8 Mhz a partir del oscilador interno tienes que configurar el registro OSCCON ya que tal y como lo tienes declarado solo desde el fuse lo normal es que te este dando 16 Mhz. Y como le estas declarando a #use delay() que el oscilador va a 8 Mhz cuando en verdad te está yendo a 16 pues las funciones delay_ms y derivadas te van el doble de rápido de lo esperado.

   Es muy importante tener muy claro a que velocidad va tu cpu, por que si no controlas eso no vas a poder hacer nada ni con los Timer por que no se va a cumplir ningún cálculo que hagas.

  Una forma rápida de comprobarlo es que pongas CLOCK=16000000  en la directiva #use_delay().  Seguramente ahora ya si se te cumplen los tiempos “siempre teniendo en cuenta el error por las ejecuciones de instrucciones en las reentradas para generar el tiempo”.

  Un saludo.

  Saludos.

 
Título: Re:CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: kurono02 en 11 de Enero de 2021, 20:51:11
Hola ,

Probé eso y sigue igual. Para configurar el OSSCON estoy usando setup_oscillator(OSC_8MHZ);

¿Me podrían mostrar algún ejemplo de como generar este dichoso delay?
Título: Re:CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: remi04 en 12 de Enero de 2021, 07:07:08
Entiendo que lo estas probando con un simulador. Normalmente ellos no tienen en cuenta los #fuses.

  Tu configuración:
Código: C
  1. setup_oscillator(OSC_8MHZ);


  No sería suficiente por que en el simulador no se qué es lo que te va a interpretar en el valor FOSC 2:0, seguramente 00.

  En la vida real seguramente si que te funcionaría.

  Para probar con el simulador pon en tu main, al principio esto:
Código: C
  1. setup_oscillator(OSC_8MHZ | OSC_INTRC);

  Un saludo.

Título: Re:CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: KILLERJC en 12 de Enero de 2021, 09:47:30
Y en Proteus hacer doble click en el microcntrolador, y elegir correctamente la frecuencia. Ya que es la única frecuencia que tiene en cuenta el mismo.
Título: Re:CREAR DELAY DE 1 SEG CON TIMER 0 EN LENGUAJE C
Publicado por: kurono02 en 13 de Enero de 2021, 12:32:23
Buenos días distinguidos,

La configuración en Proteus siempre fue la correcta.