Autor Tema: Timer0_PIC18F4550_No_se_que_pasa  (Leído 20296 veces)

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

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #15 en: 14 de Diciembre de 2013, 16:15:25 »
No se que estoy cometiendo mal... Deseo hacer 30 interrupciones del Timer0 trabajando con un prescaler de 16 y oscilador de 48Mhz, no me aparece nada.. aqui pongo el codigo a ver si me puede dar una manito.

Es un codigo similar al que esta en la pagina de Redpic..pero en la pagina esta en CCS

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

const char num_int=30;
unsigned int contador=0;
//Banderas
char flag1=0,flag2=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(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 se produce la interrupcion
        INTCONbits.TMR0IF==0;  //Borramos la bandera
        if(contador>num_int){  //Si es mayor a num_int
            if(flag1==0){      //Bandera que hace un cambio cada 30 interrupciones
                flag1=1;
            } else{
                flag1=0;
                 }
             contador=0;
        }       
          contador++;
     //}

    TMR0H=0X00;
    TMR0L=0X00;
  }

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=0;        //Prescaler  asignado

    T0CONbits.T0PS2=0;      //Prescaler de 16
    T0CONbits.T0PS1=1;
    T0CONbits.T0PS0=1;
    //TMR0H=0X00;
    //TMR0L=0X00;

    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

    do{

        if(flag1=flag2){}

        else{
            LATBbits.LATB1=!LATBbits.LATB1;
            flag2=flag1;
    }
}
    while(1);
}

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #16 en: 14 de Diciembre de 2013, 16:27:30 »
if(flag1==flag2)
"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 #17 en: 14 de Diciembre de 2013, 16:31:02 »
if(flag1==flag2)

BrunoF gracias por ese detalle, pero ya lo acabo de hacer y nada de resultados :( que mas puede ser...

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #18 en: 14 de Diciembre de 2013, 17:13:22 »
ejejej ya encontré el error cuando estoy borrando la bandera de desbordamiento esto haciendo.
Código: [Seleccionar]
INTCONbits.TMR0IF==0; el error era ese y el de flag1==flag2

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #19 en: 14 de Diciembre de 2013, 19:57:07 »
ejejej ya encontré el error cuando estoy borrando la bandera de desbordamiento esto haciendo.
Código: [Seleccionar]
INTCONbits.TMR0IF==0; el error era ese y el de flag1==flag2


Mirá vos. Se te habían intercambiado... :D
"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 #20 en: 14 de Diciembre de 2013, 21:51:14 »
Bueno acabo de mejorar el código, el primer código me guié por uno que tenia Redpic en su pagina, yo quería ver como podía minimizar un poco el código y lo que hice fue lo siguiente:

1- Que cada vez que el contador llegue al maximo se active una bandera indicando "Un desbordamiento" y ese valor lo tomo para realizar los cambios de estado a la salida.
Código: [Seleccionar]
const int num_int=15;
unsigned int contador=0;

//Banderas
char flag1=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(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(contador==num_int){
        contador=0;
        flag1=1;
      }
    ++contador;
    INTCONbits.TMR0IF=0;  //Borramos la bandera
   
    TMR0H=0X00;
    TMR0L=0X00;
    }

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=0;        //Prescaler  asignado

    T0CONbits.T0PS2=0;      //Prescaler de 16
    T0CONbits.T0PS1=1;
    T0CONbits.T0PS0=1;
 

    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){

        if(flag1){
            flag1=0;
            LATBbits.LATB1=!LATBbits.LATB1;


        }

    }
}


El resultado deber ser un desbordamiento cada 1.308s (87.20ms * 15) (87.20ms por que estoy con un prescaler de 16).  ¿Que para que lo necesito?  La verdad no se, pero estoy practicando para coger destreza en esto, me imagino que ha alguien le debe de servir.



BrunoF estos son los módulos que le había dicho, estos son los que quiero poner a trabajar.




Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #21 en: 14 de Diciembre de 2013, 22:06:11 »
La precarga del Timer dentro de la ISR:

    TMR0H=0X00;
    TMR0L=0X00;

provoca una demora adicional, si no necesitás ajustar el tiempo, dejalo correr libre al Timer. Ni bien se desborda vuelva cero, se levanta el flag de interr, y aún mientras la interr está ocurriendo, el Timer ya está volviendo a contar la próxima vuelta.

Lindos módulos, ojalá puedas ponerlos a trabajar pronto.
"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 #22 en: 14 de Diciembre de 2013, 22:19:49 »
si.. son bien bonitos jejejeje estoy ansioso por ponerlos a trabajar, por ahora decidí trabajar sin phase shift... solo voy a generar 2 señales pwm complementarias... (Se que el 18F4550 cuenta con el modulo ECCP pero quiero aprender primero hacerlo por software)  :) :)

Desconectado alvaro2043

  • PIC10
  • *
  • Mensajes: 41
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #23 en: 15 de Diciembre de 2013, 17:55:22 »
una preguntilla... como puedo leer el valor del timer0. en ccs se hace con leer_timer=get_timer0();

Como lo puedo hacer en c18 sin utilizar la libreria <timer.h> leer_timer=readtimer0();

Según lo que he leído, para escribir en el Timer0 primero se carga el TMR0H y despues el TMR0L, eso es lo que vengo haciendo. Ahora para leer los valores del timer se hace el proceso contrario.. Primero se lee TMR0L y despues TMR0H.. He encontrado un ejemplo pero no entiendo la parte del 256U

Nota: No entiendo el 256U que función cumple..

 valTimer0=TMR0L;
 valTimer0|=TMR0H*256U;

« Última modificación: 15 de Diciembre de 2013, 18:48:22 por alvaro2043 »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #24 en: 15 de Diciembre de 2013, 19:09:41 »
una preguntilla... como puedo leer el valor del timer0. en ccs se hace con leer_timer=get_timer0();

Como lo puedo hacer en c18 sin utilizar la libreria <timer.h> leer_timer=readtimer0();

Según lo que he leído, para escribir en el Timer0 primero se carga el TMR0H y despues el TMR0L, eso es lo que vengo haciendo. Ahora para leer los valores del timer se hace el proceso contrario.. Primero se lee TMR0L y despues TMR0H.. He encontrado un ejemplo pero no entiendo la parte del 256U

Nota: No entiendo el 256U que función cumple..

 valTimer0=TMR0L;
 valTimer0|=TMR0H*256U;



  Multiplicar por 256 es como rotar 8 veces a la izquierda y se hace para que ocupe el byte alto en una variable de 16 bits. Por ello hace una or con el valor almacenado anteriormente.

Código: C
  1. unsigned int valor; // variable de 16 bits
  2. valor = TMR0L;      // el valor sera 0b00000000TMR0L, es decir byte alto en 0 y byte bajo el valor de TMR0L
  3. vlor |= TMR0H *256; // el valor sera 0bTMR0HTMR0L, por lo tanto valor almacenara los 16 bits del timer

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 #25 en: 17 de Diciembre de 2013, 14:28:11 »
Gracias AngelGris por la explicacion de verdad siempre me sacas de dudas  :)

BrunoF me puse en la tarea de leer el documento que me envió sobre la opción de utilizar dsPIC33f.. Para la aplicación que quiero implementar, se ve que con un dsPIC es mas trabajable obtener el tipo de control que estoy buscando ya que cuenta con modulos Phase-shift tengo en mente (a largo plazo ya para el 2014 jeejjeje ) trabajar con el dsPIC33fj32GS606, he mirado sus caracteristica y es ideal para trabajar con convertidores de potencia la cual es mi linea.. Una cosita puede alguien decirme cuales son los pasos para iniciar a utilziar estos dsPIC... ¿Que necesito? mi Pickit2 sirve para grabar en estos dsPic? el C18 sirve para programar?? Donde puedo ver un ejemplo como encender y apagar un led..

Nota: Mas adelante les consultare sobre el programa que llevo en el 18F4550 :)  lo del dspic es para hacerme una idea del 2014 que me espera jejeje

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #26 en: 17 de Diciembre de 2013, 14:44:58 »
  Si no recuerdo mal, el sof del pickit2 trae un readme en el cual se listan los dispositivos soportados.
Supongo que para un dsPIC33 será necesario el compilador XC32... Seguramente en el sitio de microchip te dará esa información... los compiladores actuales son XC8, XC16 y XC32 y me pareció haber visto que el compilador XC32 también permite programación orientada a objetos (C++)
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 #27 en: 17 de Diciembre de 2013, 14:48:59 »
El C30 no me sirve? estoy confundido

C18-------------------------> para los PIC18

C30-----------------------> Para elo PIC24-y dspic

XC8---------------------->?

XC16-------------------->?

XC32---------------------?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Timer0_PIC18F4550_No_se_que_pasa
« Respuesta #28 en: 17 de Diciembre de 2013, 15:22:32 »
El C30 no me sirve? estoy confundido

C18-------------------------> para los PIC18

C30-----------------------> Para elo PIC24-y dspic

XC8---------------------->?

XC16-------------------->?

XC32---------------------?

  Si no me equivoco la línea C18 y C30 no van a tener continuidad.... por ello ahora está la línea XC8, XC16 y XC32

Fijate en la opción "Design support" --> "Compilers"
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 #29 en: 17 de Diciembre de 2013, 17:20:18 »
jejej Vuelvo y repito gracias a AngelGris, BrunoF, Nocturno y todas las personas que ven y aportan ideas para solucionar algun problema me ha servido de mucha ayuda en todo este proceso de aprendizaje  :P :P :P lo de los dsPIC los dejare para el próximo año cuando me llegue el que pedí  :) Por ahora seguimos sacando jugo al timer0 y las interrupciones.. A continuación muestro unas imágenes y códigos que he hecho para hacer un PWM por software. Voy a tratar de explicar lo que hice antes de mostrar las imágenes.

Primero que todo la frecuencia de mi PWM es de 25Khz en teoría. trabajando con Timer0 - 48Mhz de crystal y prescaler de 2 y variar el ciclo de trabajo entre 50% 30% y 20% (por ahora) el máximo ciclo para esta aplicación va ser de 50% ya que es para controlar un puente H.

Que es lo que he hecho?

Rta: Aparte de leer y leer y mirar ejemplos jejeje he hecho una interrupción cada "40us" esto lo he tomado como mi periodo de la señal (1/40us)=25KHZ

Ahora para tener los 40us deberia de cargar mi TIMER0 con 65296 de tal forma que solo se cuenten 240tick teniendo en cuenta que un tick = (1/(48Mhz/4))*2 =0.166us (donde 2 es el prescaler) por lo tanto 240*0.1666uS = 40us.. que es lo deseado.. Ese resultado es en TEORIA con la ayuda del osciloscopio calibre el valor de carga del TMR0 = FF1F que es lo mismo 65311 eso es en la realidad, que con respecto a lo calculado teoricamente tenemos 15 tick de mas.. Esto fue explicado en un comentario mas arriba por AngelGris. Bueno después de esa explicación viene lo otro que hice. Ya teniendo esa interrupción cada 40us  voy variando el tiempo en que permace en high la salida.. Espero no ser tan canson con este tema, pero apenas estamos en el proceso de aprendizaje jeje . Y se que mucha gente se preguntara del porq no he utilziado los modulos PWM, la razon es una sola quiero experimentar.

Voy a generar un Switch-Case para aumentar el ciclo de trabajo o disminuir apartir de un pulsador. Por ahora solo lo estoy haciendo desde Soft.

Anexo Imagen y código si me pueden ayudar para minimizar y optimizar codigo escucho ideas.. Gracias.

La señal roja es el tiempo de interrupción y la Amarilla es el PWM





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

#define PWM1    LATBbits.LATB1
//Variables globales

//const int periodo = 240;  //240 tick en donde un tick=0.166uS  (240x0.166us)=39.84us aprox 25.10Khz
const int duty_50 = 120;
const int duty_30 = 72;
const int duty_20 = 48;

unsigned int flag_t =0;  //Bandera que me indica cuando se genera una interrupcion
unsigned int flag_d =0;  //Bandera para el ciclo de trabajo
unsigned int contador=0;

unsigned int valTimer0;

/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(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){
        INTCONbits.TMR0IF=0;   //Borramos bandera
            ++contador;       //Cada vez que se presente una interrupcion aumentamos la variable contador
            LATBbits.LATB2=!LATBbits.LATB2;
            if(contador==1){
                flag_t=1;
                contador=0;
            }
        TMR0H=0XFF;   //El timer 0 arranca desde 65311. 65536-65311=235tick*0.166uS=39.01us
        TMR0L=0X1F;
    }
  
    }


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

    TRISBbits.RB2=0;
    LATBbits.LATB2=0;

    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=0;        //Prescaler  asignado

    T0CONbits.T0PS2=0;      //Prescaler de 2
    T0CONbits.T0PS1=0;
    T0CONbits.T0PS0=0;

    

    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){

        //Pulso del pwm
        if(flag_t==1){  //Si se desbordo el timer activamos una bandera
            flag_t=0;   //Limpiamos la bandera
            PWM1=1;     //Activamos el pin del PWM
            flag_d=1;
        }

        //cuadrar ciclo de trabajo
        if(flag_d==1){
            valTimer0=TMR0L;    //Leemos el valor del timer0 y lo almacenamos en la variable valtimer0
            valTimer0|=TMR0H<<8;
                if(valTimer0>duty_50){
                    flag_d=0;
                    PWM1=0;

            }
        

        }

    }
}