Autor Tema: Timer0_PIC18F4550_No_se_que_pasa  (Leído 20270 veces)

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

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Timer0_PIC18F4550_No_se_que_pasa
« en: 04 de Diciembre de 2013, 22:58:37 »
Buenas noches la verdad no se que pasa. quiero generar una señal cuadrada de 5Khz por un pin del puerto B utilizando el timer0 realizo todo lo indicado en la hoja de datos pero no sale :(
estoy utilizando el pic18f4550 con 8Mhz de reloj (utilizando el interno)

Mi codigo es el siguiente.

Código: [Seleccionar]
#include <p18f4550.h>
#include <delays.h>

//////////////////Configuaracion de bits//////////////////////////

#pragma config PLLDIV = 4
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 1   /////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config FOSC = INTOSC_EC  //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF


void main (){

    TRISBbits.RB1=0; //Definimos el pin 5 del PuertoB como salida.
    //Configuracion del timer0
    T0CONbits.T08BIT=0; //Configurado a 16bits el Timer0
    T0CONbits.T0CS=0;  //Internal Fos/4 (8Mhz/4)
    T0CONbits.PSA=1;  //No prescaler.
    //Cargando los registros TMR0H
    TMR0H=0XFF;
    TMR0L=0X38;
    INTCONbits.TMR0IF=0;
    T0CONbits.TMR0ON=1; //Iniciamos el timer0

    while(1){

        if(INTCONbits.TMR0IF)
        {
           INTCONbits.TMR0IF=0;
           TMR0H=0XFF;
           TMR0L=0X38;
           LATBbits.LATB1=!LATBbits.LATB1;
          
          
         }
     }


}

Alguien me puede decir en que estoy fallando.. muchas gracias.. Anexo imagen del osciloscopio con la señal que me genera con el codigo de arriba

« Última modificación: 04 de Diciembre de 2013, 23:26:42 por alvaro2043 »

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #1 en: 05 de Diciembre de 2013, 03:59:54 »
Hola alvaro2043 debes configurar el registro TRISB como salida, por defecto esta como entrada, y tambien con ADCON1 las entradas y salidas analogicas que por defecto son analogicas.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #2 en: 05 de Diciembre de 2013, 09:39:24 »
Hola alvaro2043 debes configurar el registro TRISB como salida, por defecto esta como entrada, y tambien con ADCON1 las entradas y salidas analogicas que por defecto son analogicas.

Saludos!

He corregido lo que me ha dicho... Seleccionar los pines como digitales con el ADCON1.. Pero no he tenido buenos resultados la señal generada es de 604Hz y quiero generar una de 5Khz.. estoy hacieno mal los calculos???

Para este ejemplo quiero generar una señal cuadrada de 5khz..  osea T=1/5khz = 200us-- un Alto que dura 100us y bajo de 100us... 100us/0.5us = 200 conteo.  65536-200=65336 = FF38   eso quiere decir que TM0H=FF y TM0L=38


Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #3 en: 05 de Diciembre de 2013, 11:55:45 »
  Según el datasheet que estoy mirando, la frecuencia seteada para el oscilador interno luego de un PowerOnReset es de 1MHz, con lo cual tu frecuencia de salida debería ser aproximadamente 625Hz. Debes configurar el oscilador interno modificando el registro OSCCON.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #4 en: 06 de Diciembre de 2013, 18:20:24 »
Si AngelGris.. tiene toda la razon.. no habia configurador el OSCILADOR A 8MHZ fue un descuido.. gracias ya esta todo solucionado


Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #5 en: 07 de Diciembre de 2013, 11:09:27 »
oK.. después de leer algunos libros ve que para generar este tipo de señales es mejor utilizar interrupciones, por lo tanto me puse en la tarea de realizar esta misma señal pero por medio de interrupciones pero esta vez utilizando una velocidad de 48Mhz.. a partir de un oscilador de cristal de 8Mhz.. Una duda que me genera es que la señal cuadrada no sale exacta, debería ser de 5khz y sale de 4.685khz utilizo el timer0 a 16bits sin prescaler y interrupcion por desbordamiento..
////////////////Calculos:

Ancho_de_pulso = TMR0*TOSC*4*TMR0PRE   .....

Ancho de pulso= 100us   ya que es una onda cuadrada de 5khz

T0SC= 1/48Mhz

TMR0PRE=1

TMR0=1200.

Eso quiere decir que para obtener esa frecuencia debo de cargar los registro TMR0H y TMR0L con 65536-1200=64336 que es lo mismo FB50  TMR0H=FB y TMR0L=50

Pero el valor esperado no es el que aparece en el osciloscopio. Lo fácil seria cuadrar a prueba y error el valor de los dos registro  TMR0H y TMR0L que es lo haría si no encuentro otra forma.. Me gustaría saber si alguien sabe la explicación del porque se genera esto.  Algo que se me viene a la cabeza es que el problema se deba algun retador por Latencia en sistema o cuando se genera la atención de la ISR. ¿Esto ocurre con todos los timer?

Anexo codigo

Código: [Seleccionar]
//Configuaracion de bits//////////////////////////

#pragma config PLLDIV = 2  //Cristal de 8Mhz lo dividimos entre 2 para tener los 4Mhz
#pragma config CPUDIV = OSC1_PLL2  //Los 96Mhz de PLL lo dividimos entre 2 para tener los 48Mhz con lo que vamos a trabajar
#pragma config USBDIV = 2  /////Tomar el reloj para USB desde el PLL- 48Mhz
#pragma config FOSC = HSPLL_HS  //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF

///Include////
#include <p18f4550.h>
#include <delays.h>

//Variables globales
int estado=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(void);
void Change_Estado(void);

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

#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
     _asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code

////////////////////////////////////////////
#pragma interrupt Interrupt_ISR_TMR0
void  Interrupt_ISR_TMR0 (void)
{
    if(INTCONbits.TMR0IF ==1 ){  //Si el timer0 se desbordo 0xFFFF a 0x0000
       INTCONbits.TMR0IF =0;     //Borramos la bandera
        Change_Estado();         //Llamamos la funcion que se realiza cuando esto ocurre.
        TMR0H=0XFB;
        TMR0L=0X50;
    }

}

void main(){

    OSCCONbits.SCS1=0;      //Configurando como Oscilador primario
    OSCCONbits.SCS0=0;

    TRISBbits.RB1=0;        //Configurando como salida el PinRB1 del puerto B
    LATBbits.LATB1=0;       //Estableciendo a un nivel bajo el PinRB1

    ADCON1=0x0F;            //Configurando todos los puerto como Digitales.

    T0CONbits.TMR0ON=0;     //Timer 0 off
    T0CONbits.T08BIT=0;     //Configurado a 16bits
    T0CONbits.T0CS=0;       //Internal
    T0CONbits.T0SE=0;
    T0CONbits.PSA=1;        //Prescaler no asignado

    TMR0H=0XFB;
    TMR0L=0X50;

    RCONbits.IPEN=1;        //Enable priority levels on Interrupts
    INTCONbits.TMR0IF=0;    //Clear TF0
    INTCONbits.GIE_GIEH=1;  //Enable Global interrupt
    INTCONbits.TMR0IE=1;    //Enable TMR0 overflow

    INTCON2bits.TMR0IP=1;   //High priority
           
    T0CONbits.TMR0ON=1;     //on Timer 0

    while(1){}


}

void Change_Estado(void){

    if(estado==0){
         LATBbits.LATB1=1;
         estado=!estado;
    }   else if (estado==1){
        LATBbits.LATB1=0;
        estado=!estado;
    }

   
}

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #6 en: 07 de Diciembre de 2013, 11:57:57 »
El cálculo está muy bien y en general yo te diría que parece estar funcionando bien.

  Ten en cuenta que dentro de tu vector de interrupciones hay "goto" (que en código asm son dos ciclos más de instrucción) también tienes las evaluaciones de los flags y la llamada a la función "Change_Estado()" y todo lo que se incluye en dicha función hasta que cambia de estado el pin. Además de ello, es casi seguro que el compilador agregue código en la interrupción (en realidad no sé si ocurre con C18, pero sí con XC8).

  También ten en cuenta que luego de chequeado el flag (para ver si la interrupción es por el timer0) debes primeramente precargar nuevamente el timer, para no perder más tiempo.

  Todo ese código agregado generará más retardo. Observa esto...


 4.685KHz = 1/213.447uS --> es decir que tu tiempo total es 213.447uS cuando debería ser 200uS según los cálculos que realizaste.
Si dividimos el tiempo a la mitad nos da una diferencia de 106.724uS contra 100uS. Teniendo en cuenta que el ciclo de trabajo a 48MHz es de 83.333nS, la diferencia en cantidad de ciclos entre lo calculado y lo real es
100uS/83.333nS = 1200 contra 106.724uS/83.333nS = 1280, es decir que hay una diferencia aproximada de 80 ciclos de instrucción.

  Tal vez ésa sea la diferencia contando tu agregado mas lo que pueda estar agregando el compilador.

 Puedes intentar optimizar más tu código de interrupción para ver si disminuye dicha diferencia y luego quedará retocar a mano el valor necesario de la precarga del timer.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #7 en: 07 de Diciembre de 2013, 14:47:31 »
Hola alvaro,

una pregunta: por qué intentas generar la onda cuadrada de 5kHz con el Timer0, cuando el 18F4550 tiene un par de módulos específicos para generarla mediante PWM y sin requerir absolutamente de casi nada del uso del CPU?

Saludos.
"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 alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #8 en: 07 de Diciembre de 2013, 21:28:44 »
AngelGris muchas gracias por tu explicación mas claro no puede ser me ha sacado de muchas dudas. Cuando habla de optimizar el codigo a que te refieres esa parte no me quedo claro.. Supongo que se debe eliminar la funcion void Change_Estado(void); y dejar todo sobre la interrupcion sin necesidad de hacer llamados de Funciones.. No se es la unica idea que se me viene en mente.

Hola BrunoF.. Bueno el por que esto generando señales cuadradas de 5khz si el 18f4550 cuenta con 2 modulos de PWM y uno de ECCP.. Tengo en mente controlar un puente H inversor con un tipo de modulación que se llama phase-shift  http://www.emeraldinsight.com/content_images/fig/1740250405013.png en el cual debo de generar 4 señales PWM..
Quiero arrancar desde lo mínimo que es generando señales sencillas, debido a que soy  novato con los PIC..

Gracias.. por su ayudas. a medida que vaya avanzando en esto lo ire publicando.. El paso siguiente es variar el ancho de pulso y la frecuencia por medio de dos potenciometro o 2 pulsadores, cual me recomieda que sea mejor (Pulsadores o Potenciometro)

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #9 en: 12 de Diciembre de 2013, 19:21:50 »
Bueno sigo con otras preguntas que me surgen con respecto a la frecuencia maxima que puedo obtener con una interrupcion, estaba probando y se me dio por cargar los registros
TMR0H y TMR0L con FFFE eso quiere decir que apenas se van a realizar 2 tick.. ya que el Timer se desborda cuando llega a FFFF (Configurado a 16bits) en teoria la frecuencia debieria de ser de:

2*(1/(48Mhz/4))=166.66ns este es el ancho del pulso osea que la frecuencia seria de (1/(2*166.66ns))=3000Khz pues ese es el calculo que saco apartir de los calculos que hice para obtener los 5khz...  y la frecuencia que obtengo en mi osciloscopio es de 312Khz aprox... Que es lo que esta pasadan???' alguien me puede decir?

Nota: Solo son inquietudes que se me generan, no utilizo prescale.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #10 en: 12 de Diciembre de 2013, 20:40:14 »
Bueno sigo con otras preguntas que me surgen con respecto a la frecuencia maxima que puedo obtener con una interrupcion, estaba probando y se me dio por cargar los registros
TMR0H y TMR0L con FFFE eso quiere decir que apenas se van a realizar 2 tick.. ya que el Timer se desborda cuando llega a FFFF (Configurado a 16bits) en teoria la frecuencia debieria de ser de:

2*(1/(48Mhz/4))=166.66ns este es el ancho del pulso osea que la frecuencia seria de (1/(2*166.66ns))=3000Khz pues ese es el calculo que saco apartir de los calculos que hice para obtener los 5khz...  y la frecuencia que obtengo en mi osciloscopio es de 312Khz aprox... Que es lo que esta pasadan???' alguien me puede decir?

Nota: Solo son inquietudes que se me generan, no utilizo prescale.

  El problema de lo que quieres intentar es que precargar el timer consume ciclos de reloj, lo mismo que volver de la interrupción. Suponiendo que puedas precargar, al retornar de la interrupción ya deberías ingresar nuevamente y así sucesivamente. Suponiendo que esté pasando éso, estás contando aproximadamente 20 ciclos.

  20 * 83.3333n * 2 = 3.333us --> 300KHz aproximadamente. O si contarás 19 daría una frecuencia de 315.79 KHz.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #11 en: 12 de Diciembre de 2013, 22:47:02 »
Eso quiere decir que no es posible obtener una frecuencia mayor a 312Khz en C, debido a que se usan 20 ciclos de reloj (en este caso). Osea que en .ASM se puede llegar a una frecuencia superior o no?. Me nace esa inquietud porq se gasta menos ciclo de reloj en Assembler.

Perdón por hacer esas preguntas pero son conceptos que de pronto no tengo claro y que no he encontrado en ningún libro o si están no lo he entendió jejeje

Otra preguntica, con un solo timer y su interrupcion es posible generar las 4 señales que publique en la parte superior http://www.emeraldinsight.com/content_images/fig/1740250405013.png o necesitaria de otro timer? la frecuencia que tengo pensado manejar para esas señales es de 25 a 40Khz

Nota: Optimice el código como me lo recomendaron y llegue a una frecuencia de 4.96Khz.
« Última modificación: 12 de Diciembre de 2013, 22:49:53 por alvaro2043 »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #12 en: 12 de Diciembre de 2013, 22:58:15 »
Eso quiere decir que no es posible obtener una frecuencia mayor a 312Khz en C, debido a que se usan 20 ciclos de reloj (en este caso).

Eso depende de muchos factores, optimizaciones del compilador en cuestión, si le metes mano tu y haces la ISR manualmente, cantidad de interrupciones, si utilizas vector de alta/baja prioridad, si guardas/restauras mas o menos registros al ingresar al vector de interrupción,etc.

Osea que en .ASM se puede llegar a una frecuencia superior o no?. Me nace esa inquietud porq se gasta menos ciclo de reloj en Assembler.

Seguramente sea más sencillo exprimir un poco más al uC en ASM, pero todo tiene su precio...

Otra preguntica, con un solo timer y su interrupcion es posible generar las 4 señales que publique en la parte superior http://www.emeraldinsight.com/content_images/fig/1740250405013.png o necesitaria de otro timer? la frecuencia que tengo pensado manejar para esas señales es de 25 a 40Khz

Cuál grupo? El de la izquierda o el de la derecha? El de la izquierda es mucho más sencillo de lograr que el de la derecha. Se puede tornar sumamente complicado hacer un phase-shift angle con un uC de estos. Hay microcontroladores, incluso de microchip, que traen módulo de phase-shift para simplificar la tarea. Acaso estás intentando hacer una fuente de corriente constante?

Saludos.
"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 alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #13 en: 12 de Diciembre de 2013, 23:29:14 »
Si tengo en mente hacer una fuente de corriente constante para ser aplicada a un calentador por inducción...

cuento con 8 modulos de este tipo y quiero ponerlo a trabajar en ese proyecto que tengo en mente..

http://www.ineltron.de/english/mitsubishi-data/IGBT/CM200DU-12F.pdf

[/quote]

Cuál grupo? El de la izquierda o el de la derecha? El de la izquierda es mucho más sencillo de lograr que el de la derecha. Se puede tornar sumamente complicado hacer un phase-shift angle con un uC de estos. Hay microcontroladores, incluso de microchip, que traen módulo de phase-shift para simplificar la tarea. Acaso estás intentando hacer una fuente de corriente constante?

[/quote]

Que Uc me puede recomendar para esa aplicacion?

« Última modificación: 12 de Diciembre de 2013, 23:31:55 por alvaro2043 »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #14 en: 12 de Diciembre de 2013, 23:54:08 »
Si tengo en mente hacer una fuente de corriente constante para ser aplicada a un calentador por inducción...

cuento con 8 modulos de este tipo y quiero ponerlo a trabajar en ese proyecto que tengo en mente..

http://www.ineltron.de/english/mitsubishi-data/IGBT/CM200DU-12F.pdf

Ok, ya me parecía debido a la necesidad del phase shifting y las frecuencias de PWM que mencionaste.

Que Uc me puede recomendar para esa aplicacion?

Modelo exácto no sabría decirte, tendría que revolver un poco porque hace un tiempo que no toco el tema. Sé que muchos dsPIC33F y PIC24H lo traen.

Acá tenés un PDF de Microchip donde lo menciona para dichas familias:

http://ww1.microchip.com/downloads/en/DeviceDoc/70323D.pdf

Saludos.
"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.


 

anything