Timer0 en XC8 y PIC18F2520

Muy buenas!

Quiero leer el código de una señal infrarroja, y para ello necesito trabajar con el timer, así que me he dispuesto a crear un programa que solamente utilice el timer y luego ya iré adaptándolo al infrarrojos.
El tema es que no consigo que funcione el programa y por más que lo reviso no consigo ver el por qué. A ver si hay suerte y lo conseguimos sacar!:D

Código:
// CONFIG1H     // Oscillator Selection bits (XT oscillator)
#pragma config OSC = XT
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

Ahí están las definiciones pragma, y ahora el código:

Código:
#include <xc.h>
#include<plib/timers.h>

#define _XTAL_FREQ 40000000

    unsigned char config1;
    unsigned int timer_value;
    unsigned int tpr;

void main(void) {


    TRISBbits.RB3 = 0;
    PORTBbits.RB3 = 0;
    TRISBbits.RB4 = 0;
    PORTBbits.RB4 = 0;

    T0CONbits.T08BIT = 1;
    // 16-bit
    T0CONbits.T0CS = 0; // Internal clock
    
    T0CONbits.PSA = 0;
    T0CONbits.T0PS0 = 1;
    T0CONbits.T0PS1 = 1;
    T0CONbits.T0PS2 = 1;

    TMR0H = 0x00; //Cleaning timer value
    TMR0L = 0x00;
    
    INTCONbits.T0IF = 0; // Clear the flag
    INTCONbits.T0IE = 1; // Enable the interrupt
    INTCONbits.PEIE = 1; // Turn on peripheral interrupts  <-- This is needed by you
    INTCONbits.GIE = 1; // ... and global interrupts  <-- As is this
    T0CONbits.TMR0ON = 1; // and finally set the period.
}

void low_priority interrupt Low_Priority_Interrupt(void) {
    PORTBbits.RB4 == 0;
    if (INTCONbits.TMR0IE && INTCONbits.T0IF) {
        INTCONbits.T0IF = 0;

        TMR0H = 0x00;
        TMR0L =0x00;
        if(PORTBbits.RB3 == 0)
        {
            PORTBbits.RB3 == 1;
        }
        else if(PORTBbits.RB3 == 1)
        {
            PORTBbits.RB3 == 0;
        }
    }
}

He revisado varias veces el código y los flags creo que están correctos y no me olvido de ninguno, por lo que no se qué le sucede al programa.

Un saludo!.
 
Última edición por un moderador:
Buenas! He conseguido que funcione el programa!
Comparto el código por si le sirve de ayuda a alguien! (Las definiciones pragma son las mismas.)
Código:
#include <xc.h>
#include<plib/timers.h>

#define _XTAL_FREQ 40000000

    unsigned char config1;
    unsigned int timer_value;
    unsigned int tpr;
    int counter=0;

void main(void) {


    TRISBbits.RB3 = 0;
    PORTBbits.RB3 = 0;


       // 1/1 prescalar
       T1CONbits.T1CKPS1 = 1;
       T1CONbits.T1CKPS0 = 1;

       // Use Internal Clock
       T1CONbits.TMR1CS = 0;

       // Timer1 overflow interrupt
       PIE1bits.TMR1IE = 1;

       // Enable Timer 1
       T1CONbits.TMR1ON = 1;


       INTCONbits.PEIE = 1; // Enable Perpherial Interrupt
       INTCONbits.GIE = 1; // Enable Global Interrupt
       
       while(1)
       {

       }
}

void interrupt high_priority lowISR(void) {
    if (PIR1bits.TMR1IF == 1) {

        if(counter == 0)
        {
            PORTBbits.RB3 = 1;
            counter = 1;

        }
        else if(counter == 1)
        {
            PORTBbits.RB3 = 0;
            counter = 0;
        }
        TMR1 = 0X00;

        PIR1bits.TMR1IF = 0;
    }
    }
El problema se ha resuelto cuando en los if en vez de comparar el estado de un pin he comparado el valor de una variable.

Un saludo!
 
Última edición por un moderador:
hola , tengo un problema al usar el TMR0ON y el TMR1ON, necesito que el timer se resetee e inicie de nuevo en un punto determinado del código, al principio usé enable_interrupts y disable_interrupts pero me di cuenta que no reseteaba el timer y ésto hacia que se descontrolaran los ciclos útiles de las señales (debo generar las 4 señales para un inversor en puente ), cuando pongo en 0 o 1 (según lo necesite) los TMR0ON y TMR1ON al simular no sale absolutamente nada.
agradecería mucho si alguien me pudiera ayudar con eso
 
Hola. Tengo un problema al usar el TMR0ON y el TMR1ON, necesito que el timer se resetee e inicie de nuevo en un punto determinado del código.
Al principio usé enable_interrupts y disable_interrupts, pero me di cuenta que no reseteaba el timer y ésto hacía que se descontrolaran los ciclos útiles de las señales.
No sé a que te refieras con eso de resetear el Timer1. ¿Será tal vez, recargar el Timer1?
Por las funciones de interrupción que mencionas, al parecer estás usando PIC C Compiler de CCS, pero este tema trata sobre el compilador XC8.
Menciono esto, porque en PIC C de CCS no existen los bits que mencionas: TMR0ON y TMR1ON
¿Los estás definiendo o qué compilador estás usando?

En PIC C de CCS se usa; setup_timer_0(int8 mode) o setup_counters(int8 mode) y setup_timer_1(int16 mode)
Para deshabilitar el Timer0 se usa; setup_timer_0(T0_OFF) y para el Timer1 se usa; setup_timer_1(T1_DISABLED)
Y para cargar el timer0 se usa set_timer0(int16 value) o set_rtcc(int16 value), para el Timer1 se usa; set_timer1(int16 value)

Para los PIC16, el Timer0 es de 8 Bits y para los PIC18 puede ser de 8 o 16 Bits.
(Debo generar las 4 señales para un inversor en puente)
¿No será qué lo que necesitas es generar señales PWM?
Cuando pongo en 0 o 1 (según lo necesite) los TMR0ON y TMR1ON al simular no sale absolutamente nada.
Agradecería mucho si alguien me pudiera ayudar con eso.
Para que se te pueda colaborar de mejor forma, es necesario que adjuntes el código y esquema de lo que estás haciendo, porque resulta algo confuso lo que mencionas.
 
Sí, estoy utilizando el CCS se me olvido aclarar, mira este es el código.
El problema de usar pwm es que después de tener generadas las señales, necesito desfasarlas entre ellas.

Código:
#include <18f2550.h>
#device ICD=TRUE
#DEVICE HIGH_INTS=TRUE
#fuses HS,NOWDT
#use delay(clock=8M)
#use standard_io(B)
#use standard_io(A)
#bit TMR0ON=0xFD5.7        //defino el bit de encendido apagado de los timers
#bit TMR1ON=0xFCD.0

int contpuls1=9;           //contador de pulsaciones para desfase con la otra rama
int contpuls2=9;           //contador de pulsaciones para desfase con el otro modulo
int T1delm=0;
int T2delm=0;
int T1delr=0;
int T2delr=0;
int Delm=0;
int continterr2=0;
int continterr3=0;
int cruce=0;
int contpulcambio=0;
int tarea=1;

#int_TIMER1
void intTMR1 (void)
{
if(continterr2==1)
      {
          continterr2=0;
          Output_low(PIN_A2);
          TMR1ON=0;
      }
      else{
          continterr2++;
          Output_low(PIN_A0);
          TMR1ON=0;
      }
}
#int_TIMER0
void intTMR0 (void)
{
if(continterr3==1)
      {
          continterr3=0;
          Output_low(PIN_A3);
          TMR0ON=0;
      }
      else{
          continterr3++;
          Output_low(PIN_A1);
          TMR0ON=0;
      }
}
#int_EXT          
void intRB0(void)                //rutina de interrupcion del detector de cruce por cero
{
clear_interrupt(int_ext);
cruce++;
if(contpuls2!=9)
      {      
      if (contpuls2>9) Delm=T2delm;  
      else Delm=T1delm;
      }
else Delm=0;
}
#int_EXT1
void intRB1(void)                //rutina de interrupcion del boton que disminuye el desfase
clear_interrupt(int_ext1);
if(contpulcambio==1)
       {
           if (contpuls2>=1)
           {
               contpuls2--;            //disminuye el contador de pulsaciones del modo 2
               if(contpuls2!=9)
               {                   
                   if(contpuls2>9)
                   {
                       T2delm=3*(contpuls2-9);
                       tarea=2;
                   }
                   else {
                       T1delm=3*(contpuls2);
                       tarea=3;
                   }
               }
               else tarea=1;
           }
           else {
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
       else{
         if (contpuls1>=1)
         {
            contpuls1--;            //disminuye el contador de pulsaciones del modo 1
            if(contpuls1!=9)
            {                
                if(contpuls1>9)
                {
                    T2delr=3*(contpuls1-9);
                    tarea=2;
                }
                else {
                    T1delr=3*(contpuls1);
                    tarea=3;
                }
            }
            else tarea=1;
         }
         else{
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
}
#int_EXT2
void intRB2(void)                   //rutina de interrupcion del boton que aumenta el desfase
{
clear_interrupt(int_ext2);
 if(contpulcambio==1)
       {
           if (contpuls2<=19)
           {
               contpuls2++;            //aumenta el contador de pulsaciones del modo 2
               if(contpuls2!=9)
               {                   
                   if(contpuls2>9)
                   {
                       T2delm=3*(contpuls2-9);
                       tarea=2;
                   }
                   else {
                       T1delm=3*(contpuls2);
                       tarea=3;
                   }
               }
               else tarea=1;
           }
           else {
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
       else{
         if (contpuls1<=19)
         {
            contpuls1++;            //aumenta el contador de pulsaciones del modo 1
            if(contpuls1!=9)
            {                
                if(contpuls1>9)
                {
                    T2delr=3*(contpuls1-9);
                    tarea=2;
                }
                else {
                    T1delr=3*(contpuls1);
                    tarea=3;
                }
            }
            else tarea=1;
         }
         else{
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
}
#int_RB
void intRB4(void)             //rutina de interrupcion del boton que cambia ntre desfase con el modulo
{                             // o con la otra rama
clear_interrupt(int_rb);
 if (contpulcambio==1)
            {
                contpulcambio=0;
                enable_interrupts(int_EXT);
            }
            else{
                contpulcambio++;
                disable_interrupts(int_EXT); 
            }
}
void main()                //rutina principal
{
enable_interrupts(GLOBAL);
enable_interrupts(int_RB);
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
disable_interrupts(int_ext);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2|RTCC_8_BIT);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
TMR0ON=0;
TMR1ON=0;

while (1){
switch (tarea){
   case 1:  Delay_us(Delm);               //rutina de tarea, cuando las señales están en fase
            Output_high(PIN_A0);
            set_timer1(65511);
            TMR1ON=1;
            output_high (PIN_A1);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==0&&continterr3==0)
            {} 
            Output_high(PIN_A2);
            set_timer1(65511);
            TMR1ON=1;
            output_high (PIN_A3);
            set_timer0(231);
            TMR0ON=0;
            while (continterr2==1&&continterr3==1)
            {}    
            break;
   case 2:  Delay_us(Delm);                //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);           // entre 0º<a<=90º
            set_timer1(65511);
            TMR1ON=1;
            delay_us(T2delr);
            output_high (PIN_A1);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==0)
            {}            
            Output_high(PIN_A2);
            set_timer1(65511);
            TMR1ON=1;
            while (continterr3==0)
            {}            
            output_high (PIN_A3);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==1)
            {}            
            break;
   case 3:  Delay_us(Delm);               //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);          // entre -90º<=a<0º
            set_timer1(65511);
            TMR1ON=1;
            delay_us(T1delr);
            output_high (PIN_A3);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==0)
            {}            
            Output_high(PIN_A2);
            set_timer1(65511);
            TMR1ON=1;
            while (continterr3==0)
            {}            
            output_high (PIN_A1);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==1)
            {}    
            break;*/
}
}
}
Espero que así quede mas claro.



Ah, y mira esta es la simulación en proteus.
Las señales que arroja cuando uso es enable_interrupts es la que aparece ahi, pero al usar el TMR0ON no hace absolutamente nada.
 

Adjuntos

  • sseñales.PNG
    sseñales.PNG
    94.3 KB · Visitas: 6
  • simlucacion.PNG
    simlucacion.PNG
    51.7 KB · Visitas: 10
Última edición por un moderador:
Vamos a empezar por la palabra de configuración.
Tienes esta configuración:
#fuses HS,NOWDT
#use delay(clock=8M)

Y en el esquema que pones estás usando un cristal, entonces esa no es la configuración que debes usar.
Usando esa configuración, al no ser correcta, entrará en funcionamiento el oscilador interno y a 1MHz.
Usa esta para un oscilador a cristal de 8MHz.:
#fuses NOFCMEN,NOIESO,NOPBADEN,NOVREGEN,NOBROWNOUT
#use delay(crystal = 8MHz)


Sobre el código:
Te hace falta iniciar con un corchete en la rutina intRB1
Y eliminar el */ al final del último break;
El servicio de interrupción int_EXT, será conveniente que lo establezcas de alta prioridad.
Así:
int_EXT HIGH
Esto es porque tienes declarado usar alta prioridad y evitas que el compilador de advertencias.

Sobre la simulación:
Cuando simules, trata de no usar componentes activos y mejor utiliza señales digitales.
Esto es para evitar la sobrecarga del CPU y la simulación corra más fluida.
Evita colocar los componentes del oscilador o establece su propiedad como fuera de la simulación. (No son necesarios)

Por ahora corrige esos detalles y ve como funciona con esos cambios.

Suerte.
 
vale, ya cambie eso y de igual manera sigue saliendo lo mismo
el código quedó asi
Código:
#include <18f2550.h>
#device ICD=TRUE
#DEVICE HIGH_INTS=TRUE
#fuses NOFCMEN,NOIESO,NOPBADEN,NOVREGEN,NOBROWNOUT
#use delay(crystal = 8MHz)
#use standard_io(B)
#use standard_io(A)
#bit TMR0ON=0xFD5.7        //defino el bit de encendido apagado de los timers
#bit TMR1ON=0xFCD.0

int contpuls1=9;           //contador de pulsaciones para desfase con la otra rama
int contpuls2=9;           //contador de pulsaciones para desfase con el otro modulo
int T1delm=0;
int T2delm=0;
int T1delr=0;
int T2delr=0;
int Delm=0;
int continterr2=0;
int continterr3=0;
int cruce=0;
int contpulcambio=0;
int tarea=1;

#int_TIMER1
void intTMR1 (void)
{
if(continterr2==1)
      {
          continterr2=0;
          Output_low(PIN_A2);
          setup_timer_1(T1_DISABLED);
      }
      else{
          continterr2++;
          Output_low(PIN_A0);
          setup_timer_1(T1_DISABLED);
      }
}
#int_TIMER0
void intTMR0 (void)
{
if(continterr3==1)
      {
          continterr3=0;
          Output_low(PIN_A3);
          setup_timer_0(T0_OFF);
      }
      else{
          continterr3++;
          Output_low(PIN_A1);
          setup_timer_0(T0_OFF);
      }
}
#int_EXT HIGH         
void intRB0(void)                //rutina de interrupcion del detector de cruce por cero
{
clear_interrupt(int_ext);
cruce++;
if(contpuls2!=9)
      {      
      if (contpuls2>9) Delm=T2delm;  
      else Delm=T1delm;
      }
else Delm=0;
}
#int_EXT1
void intRB1(void)                //rutina de interrupcion del boton que disminuye el desfase
{clear_interrupt(int_EXT1);
if(contpulcambio==1)
       {
           if (contpuls2>=1)
           {
               contpuls2--;            //disminuye el contador de pulsaciones del modo 2
               if(contpuls2!=9)
               {                   
                   if(contpuls2>9)
                   {
                       T2delm=3*(contpuls2-9);
                       tarea=2;
                   }
                   else {
                       T1delm=3*(contpuls2);
                       tarea=3;
                   }
               }
               else tarea=1;
           }
           else {
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
       else{
         if (contpuls1>=1)
         {
            contpuls1--;            //disminuye el contador de pulsaciones del modo 1
            if(contpuls1!=9)
            {                
                if(contpuls1>9)
                {
                    T2delr=3*(contpuls1-9);
                    tarea=2;
                }
                else {
                    T1delr=3*(contpuls1);
                    tarea=3;
                }
            }
            else tarea=1;
         }
         else{
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
}
#int_EXT2
void intRB2(void)                   //rutina de interrupcion del boton que aumenta el desfase
{
clear_interrupt(int_ext2);
 if(contpulcambio==1)
       {
           if (contpuls2<=19)
           {
               contpuls2++;            //aumenta el contador de pulsaciones del modo 2
               if(contpuls2!=9)
               {                   
                   if(contpuls2>9)
                   {
                       T2delm=3*(contpuls2-9);
                       tarea=2;
                   }
                   else {
                       T1delm=3*(contpuls2);
                       tarea=3;
                   }
               }
               else tarea=1;
           }
           else {
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
       else{
         if (contpuls1<=19)
         {
            contpuls1++;            //aumenta el contador de pulsaciones del modo 1
            if(contpuls1!=9)
            {                
                if(contpuls1>9)
                {
                    T2delr=3*(contpuls1-9);
                    tarea=2;
                }
                else {
                    T1delr=3*(contpuls1);
                    tarea=3;
                }
            }
            else tarea=1;
         }
         else{
               output_high(PIN_A4);
               Delay_ms(50);
               output_low(PIN_A4);
                }
       }
}
#int_RB
void intRB4(void)             //rutina de interrupcion del boton que cambia ntre desfase con el modulo
{                             // o con la otra rama
clear_interrupt(int_rb);
 if (contpulcambio==1)
            {
                contpulcambio=0;
                enable_interrupts(int_EXT);
            }
            else{
                contpulcambio++;
                disable_interrupts(int_EXT); 
            }
}
void main()                //rutina principal
{
enable_interrupts(GLOBAL);
enable_interrupts(int_RB);
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
disable_interrupts(int_ext);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2|RTCC_8_BIT);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
setup_timer_1(T1_DISABLED);
setup_timer_0(T0_OFF);

while (1){
switch (tarea){
   case 1:  Delay_us(Delm);               //rutina de tarea, cuando las señales están en fase
            Output_high(PIN_A0);
            set_timer1(65511);
            TMR1ON=1;
            output_high (PIN_A1);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==0&&continterr3==0)
            {} 
            Output_high(PIN_A2);
            set_timer1(65511);
            TMR1ON=1;
            output_high (PIN_A3);
            set_timer0(231);
            TMR0ON=1;
            while (continterr2==1&&continterr3==1)
            {}    
            break;
   case 2:  Delay_us(Delm);                //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);           // entre 0º<a<=90º
            set_timer1(65511);
            enable_interrupts(INT_TIMER1);
            delay_us(T2delr);
            output_high (PIN_A1);
            set_timer0(231);
            enable_interrupts(INT_TIMER0);
            while (continterr2==0)
            {}            
            Output_high(PIN_A2);
            set_timer1(65511);
            enable_interrupts(INT_TIMER1);
            while (continterr3==0)
            {}            
            output_high (PIN_A3);
            set_timer0(231);
            enable_interrupts(INT_TIMER0);
            while (continterr2==1)
            {}            
            break;
   case 3:  Delay_us(Delm);               //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);          // entre -90º<=a<0º
            set_timer1(65511);
            enable_interrupts(INT_TIMER1);
            delay_us(T1delr);
            output_high (PIN_A3);
            set_timer0(231);
            enable_interrupts(INT_TIMER0);
            while (continterr2==0)
            {}            
            Output_high(PIN_A2);
            set_timer1(65511);
            enable_interrupts(INT_TIMER1);
            while (continterr3==0)
            {}            
            output_high (PIN_A1);
            set_timer0(231);
            enable_interrupts(INT_TIMER0);
            while (continterr2==1)
            {}    
            break;
}
}
}
 

Adjuntos

  • mod.jpg
    mod.jpg
    102.9 KB · Visitas: 8
Vale, ya cambie eso y de igual manera sigue saliendo lo mismo.
OK. No había visto que te hace falta habilitar la interrupción por desborde del Timer1 y del Timer0.
Habilita esas interrupciones y cambia el prescaler del Timer1 por 1:1

Prueba con esos agregados, al menos ya debes notar la generación de señales.
 
Ahora tengo un problema con la interrupción en RB4; solo necesito un botón en RB no una matriz, pero al pulsarlo, las señales se caen a 0 :cry:
Si entras en modo de depuración y poniendo un breakpoint en la rutina de interrupción por RB4<>RB7, verás que entra en un bucle infinito y ya no se sale de esa rutina.
No entiendo que pueda causar este problema, pero prueba deshabilitando la interrupción dentro de la misma rutina y vuélvela a habilitar dentro del bucle del programa principal.

Por ahora no se me ocurre una mejor manera de solucionarlo, pero prueba de esa forma.

Otra cosa que no logro entender, es; el por qué la interrupción del Timer1 no responde con el prescaler 1:2.
El valor que estableces para el Timer1 es de 65511, que con el prescaler 1:2 y a 8MHz, debe desbordar cada 25uS. Aprox.
Cambiando el prescaler a 1:1, lógicamente ahora desborda cada 12.5uS. Pero, "así es cómo funciona"

No entiendo mucho sobre lo que quieres hacer con el programa, pero para generar señales desfasadas, yo lo haría de esta forma.
Por ejemplo, 4 señales a 60Hz.
Código:
#include <18f2550.h>
#device  high_ints = true
#fuses   NOFCMEN,NOIESO,NOPBADEN,NOVREGEN,NOBROWNOUT
#use     delay(crystal = 8MHz)

#int_timer1
void Timer1_ISR (void)
{
   set_timer1(57203);
   output_toggle(pin_a0);    // Cambiar de polaridad RA0
   output_toggle(pin_a1);    // Cambiar de polaridad RA1
}

// Darle prioridad a esta interrupción para no perder sincronía con la del Timer1
#int_timer0 HIGH
void Timer0_ISR (void)
{
   set_timer0(57203);
   output_toggle(pin_a2);    // Cambiar de polaridad RA2
   output_toggle(pin_a3);    // cambiar de polaridad RA3
}

void main (void)
{
   enable_interrupts(int_timer1);
   enable_interrupts(int_timer0);
   enable_interrupts(global);
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
   set_timer1(57203);      // Para 60Hz.
   
   setup_timer_0(T0_INTERNAL | T0_DIV_2);
   set_timer0(57203);      // Para 60Hz.
   
   output_high(pin_a0);    // Iniciar RA0 en alto.
   output_low(pin_a1);     // Iniciar RA1 en bajo.
   output_high(pin_a2);    // Iniciar RA2 en alto.
   output_low(pin_a3);     // Iniciar RA3 en bajo.
   
   
   while(true);   // Bucle infinito o abrir para realizar rutinas del programa.
}
Es una forma sencilla de hacerlo, pero tal vez necesitas algo más complejo.
 
Por cierto, ¿cómo depuro mi programa en ccs?
Como en tu programa tenías declarado usar ICD (In Circuit Debugger), pensé que lo estabas usando.
Mira por aquí:How do I generate code compatible with ICD (or ICD2)?
Otra forma de entrar en modo de depuración, es con el mismo ISIS de Proteus.
Para eso, debes cargar al PIC el archivo *.cof que se genera al compilar y presionar el botón Pause.
Al hacer eso, aparecen las ventanas de variables y depuración, o las que hayas seleccionado en el menú Debug.
Verifica que el código que aparezca sea el que quieres depurar.
Busca la instrucción dentro de la rutina en donde quieres que se detenga el programa cuando se llegue ahí, y das doble click sobre ella para establecer un punto de ruptura, (Breakpoint) o también puedes usar los botones del depurador.

Mira también este enlace:Depuración de programas con Proteus y CCS
 
Última edición:
tengo un problema, al simular las selañes salen y se desfasan (no como quisiera, pero algo hacen) pero al quemarlo con un pickit2 clon y probarlo en fisico las salidas son niveles DC, no se que pasa. Asi va el código:
Código:
#include <18f2550.h>
#device ICD=TRUE
#DEVICE HIGH_INTS=TRUE
#fuses NOFCMEN,NOIESO,NOPBADEN,NOVREGEN,NOBROWNOUT
#use delay(crystal = 8MHz)
#use standard_io(B)
#use standard_io(A)
#bit TMR0ON=0xFD5.7        //defino el bit de encendido apagado de los timers
#bit TMR1ON=0xFCD.0
#bit TMR3ON=0xFB1.0

int contpuls1=10;           //contador de pulsaciones para desfase con la otra rama
int contpuls2=10;           //contador de pulsaciones para desfase con el otro modulo
int T1delm=0;
int T2delm=0;
int T1delr=0;
int T2delr=0;
int Delm=0;
int continterr2=0;
int continterr3=0;
int cruce=0;
int contpulcambio=0;
int tarea=1;

#int_TIMER1 HIGH
void intTMR1 (void)
{
if(continterr2==1)
      {
          continterr2=0;
          Output_low(PIN_A2);
          TMR1ON=0;
      }
      else{
          continterr2++;
          Output_low(PIN_A0);
          TMR1ON=0;
      }
}
#int_TIMER0 HIGH
void intTMR0 (void)
{
if(continterr3==1)
      {
          continterr3=0;
          Output_low(PIN_A3);
          TMR0ON=0;
      }
      else{
          continterr3++;
          Output_low(PIN_A1);
          TMR0ON=0;
      }
}
#int_TIMER3 HIGH
void intTMR3 (void)
{
if(continterr3==1)
      {
          continterr3=0;
          Output_low(PIN_A3);
          TMR3ON=0;
      }
      else{
          continterr3++;
          Output_low(PIN_A1);
          TMR3ON=0;
      }
}
#int_EXT HIGH         
void intRB0(void)                //rutina de interrupcion del detector de cruce por cero
{
clear_interrupt(int_ext);
cruce++;
if(cruce==2)
   {
   cruce=0;
   if(contpuls2!=10)
         {      
         if (contpuls2>10) Delm=T2delm;  
         else Delm=T1delm;
         }
   else Delm=0;
   }   
}
#int_EXT1
void intRB1(void)                //rutina de interrupcion del boton que disminuye el desfase
{
disable_interrupts(int_ext1);
if (contpulcambio==1)
   {
   contpuls2--;
   if (contpuls2>=1)
      {      
      if (contpuls2!=10)
         {
         if(contpuls2>10)
            {
            T2delm=20*(contpuls2-10);
            tarea=2;
            }
         else
            {
            T1delm=(20*(10-contpuls2));
            tarea=3;
            }
         }
         else tarea=1;
      }
      else
      {
      output_high(PIN_A4);
      Delay_ms(50);
      output_low(PIN_A4);
      }
   }
else
   {
   contpuls1--;
   if(contpuls1>=19)
      {
      if(contpuls1!=10)
         {
         if(contpuls1>10)
            {
            T2delr=20*(contpuls1-10);
            tarea=2;
            }
         else
            {
            T1delr=(20*(10-contpuls1));
            tarea=3;
            }
         }
      else tarea=1;
      }
   else
      {
      output_high(PIN_A4);
      Delay_ms(50);
      output_low(PIN_A4);
      }
   }
clear_interrupt(int_EXT1);
enable_interrupts(int_ext1);
}
#int_EXT2
void intRB2(void)                   //rutina de interrupcion del boton que aumenta el desfase
{
disable_interrupts(int_ext1);
if (contpulcambio==1)
   {
   contpuls2++;
   if (contpuls2<=19)
      {      
      if (contpuls2!=10)
         {
         if(contpuls2>10)
            {
            T2delm=40*(contpuls2-10);
            tarea=2;
            }
         else
            {
            T1delm=(40*(10-contpuls2));
            tarea=3;
            }
         }
         else tarea=1;
      }
      else
      {
      output_high(PIN_A4);
      Delay_ms(50);
      output_low(PIN_A4);
      }
   }
else
   {
   contpuls1++;
   if(contpuls1<=19)
      {
      if(contpuls1!=10)
         {
         if(contpuls1>10)
            {
            T2delr=40*(contpuls1-10);
            tarea=2;
            }
         else
            {
            T1delr=(40*(10-contpuls1));
            tarea=3;
            }
         }
      else tarea=1;
      }
   else
      {
      output_high(PIN_A4);
      Delay_ms(50);
      output_low(PIN_A4);
      }
   }
clear_interrupt(int_EXT2);
enable_interrupts(int_ext2);
}
#int_RB
void intRB4(void)             //rutina de interrupcion del boton que cambia ntre desfase con el modulo
{                             // o con la otra rama
disable_interrupts(int_RB);
 if (contpulcambio==1)
            {
            }
            else{ 
            }
clear_interrupt(int_rb);
}
void main()                //rutina principal
{
enable_interrupts(GLOBAL);
enable_interrupts(int_RB);
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
disable_interrupts(int_ext);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER3);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
setup_timer_3(T3_INTERNAL|T3_DIV_BY_2);
TMR1ON=0;
TMR0ON=0;
TMR3ON=0;
SET_TRIS_B(0x17);
SET_TRIS_A(0x00);

while (TRUE){
enable_interrupts(int_RB);
switch (tarea){
   case 1:  Delay_us(Delm);               //rutina de tarea, cuando las señales están en fase
            Output_high(PIN_A0);
            set_timer1(65010);
            TMR1ON=1;
            output_high (PIN_A1);
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==0||continterr3==0)
            {} 
            Output_high(PIN_A2);
            set_timer1(65010);
            TMR1ON=1;
            output_high (PIN_A3);
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==1||continterr3==1)
            {}    
            break;
   case 2:  Delay_us(Delm);              //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);          // entre 0º<a=<90º
            set_timer1(65010);
            TMR1ON=1;
            delay_us(T2delr);
            output_high (PIN_A1);
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==0)
            {} 
            Output_high(PIN_A2);
            set_timer1(65010);
            TMR1ON=1;
            while (continterr3==0)
            {}
            output_high (PIN_A3);
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==1)
            {}    
            break;
   case 3:  Delay_us(Delm);              //rutina de tarea, cuando las señales se desfasan
            Output_high(PIN_A0);          // entre -90º<a=<0º
            set_timer1(65010);
            TMR1ON=1;
            delay_us(T1delr);
            output_high (PIN_A3);
            continterr3=1;
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==0)
            {} 
            Output_high(PIN_A2);
            set_timer1(65010);
            TMR1ON=1;
            while (continterr3==1)
            {}
            output_high (PIN_A1);
            set_timer3(65000);
            //TMR0ON=1;
            TMR3ON=1;
            while (continterr2==1)
            {}    
            break;
}
}
}
 
tengo un problema, al simular las selañes salen y se desfasan (no como quisiera, pero algo hacen) pero al quemarlo con un pickit2 clon y probarlo en fisico las salidas son niveles DC, no se que pasa.
Probé el programa físicamente y si existe generación de señales. (900Hz. Aprox.)
Pero se caen cuando se produce la interrupción por RB2. (Cuando RB2 = 1)
Así que, tienes que verificar lo que sucede dentro de esa rutina para encontrar la causa.
 
Atrás
Arriba