AnsweredAssumed Answered

Multiple Interrupts

Question asked by Mohammad Shekarforoush on Jan 24, 2011
Latest reply on Jan 26, 2011 by Mohammad Shekarforoush

Hello,

 

I have enabled the input capture interrupts on rising edge and its working fine.

I now want to add a second interrupt (Timer Overflow Interrupt). The initialization below works fine.

I'm having problems when I enable the timer over flow interrupt on the TSCR2 register by changing its value to TSCR2 = 0x82. I've tried stepping through the code and after a few steps, True time simulator looses connection with board and my PORTB LED's stop working.

If I change TSCR2 back to TSCR2 = 0x02; everything works fine again.

 

 

void input_capture_initialize(void)
{
  TSCR1=0x90; /* enable timer and fast clear, rather than writing to bit0 of TFLG1 */
  TSCR2=0x02; /* prescale to 4  6000000 pps, longest pulse width measured using*/              
  TIOS|=0xFE;  /* select input capture (all channels) */
  TCTL3=0x00; /* capture disabled on channels 4 to 7 */
  TCTL4=0x01; /*PORTT0 capture on rising edge, channels 1 to 3 disabled */
  TIE=0x01;   /* enable timer interrupt on C0 */
  TFLG2=0x80;
}

 I think i'm not initializing something properly and the problem is somewhere in the initialization of the above registers.

 

However, here is the complete code (I don't expect anyone to go through it)

 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

volatile unsigned int rising, frequency_int, set_point;
volatile unsigned int flag;
float actual_period, frequency, period, average, Speed_RPM=0, frequency_actual;
unsigned int old_TC0, x, count, Speed_RPM2=0, i=0;
volatile int error;

void Set_Clock(void);
void PWM0_ini(unsigned char prescale_factor, unsigned char period, unsigned char init_duty);

#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module.
Placement will be in NON_BANKED area. */

/* Interrupt on a rising edge of waveform connected to PT0 */
interrupt void toc0_isr(void)

    if (flag ==0)
    {
        old_TC0 = TC0;
        flag = 1;
    }
    else
    {
        x = TC0;
        period = x - old_TC0;
        old_TC0 = TC0;
        average += period;
        count ++;
        if (count == 20)
        {
            count = 0;
            period = (average/20);
            average = 0;
            actual_period = period/6000000;
            frequency = 1/actual_period;
            frequency_int = (unsigned int)frequency/100;
            frequency_actual = (unsigned int)frequency;
            //PORTB = Speed_RPM2;
            error = set_point - frequency_int;
       }
    }
  
}
#pragma CODE_SEG DEFAULT

void input_capture_initialize(void); /* prototype to initialize input capture */

void main(void)
{                       
    DDRB = 0xFF;    //PORTB as output since LEDs are connected to it
    DDRJ = 0xFF;    //PTJ as output to control Dragon12+ LEDs
    DDRT = 0xFE;    /* PT0 is input, all the rest are unchanged */
    DDRH = 0x00;    //PORTH as input
    flag = 0;
    Set_Clock();
    PWM0_ini(0x03,255,0);
    flag = 0;
    input_capture_initialize();
    EnableInterrupts; /* clear I bit of CCR */
    while(1)
    {
        set_point = PTH;
        if (error > 8) error = 8;
        if (error < -8) error = -8;
        PWMDTY0 = 15*(error+8);
        Speed_RPM = frequency_actual*0.6666666;
        if (Speed_RPM < 300) Speed_RPM = 0;
        Speed_RPM2 = (unsigned int)Speed_RPM/10;
        //PORTB = Speed_RPM2;    
    
    }
    

}
    
    
void input_capture_initialize(void)
{
  TSCR1=0x90; /* enable timer and fast clear, rather than writing to bit0 of TFLG1 */
  TSCR2=0x82; /* prescale to 4  6000000 pps, longest pulse width measured using*/              
  TIOS|=0xFE;  /* select input capture (all channels) */
  TCTL3=0x00; /* capture disabled on channels 4 to 7 */
  TCTL4=0x01; /*PORTT0 capture on rising edge, channels 1 to 3 disabled */
  TIE=0x01;   /* enable timer interrupt on C0 */
  TFLG2=0x80;
}


void Set_Clock(void)
{
    CLKSEL &= 0x7F;
    PLLCTL |= 0x40;
    SYNR  = 0x05;
    REFDV = 0x01;
    while(!(0x08 & CRGFLG));
    CLKSEL |= 0x80;
}

void PWM0_ini(unsigned char prescale_factor, unsigned char period, unsigned char init_duty)
{
    PWMPRCLK = prescale_factor; /* choose 8-bit PWM, set clock A prescaler to prescale_factor */
                                /* choose clock A as clock source, PWM channel 0 output high
                                    at the beginning of the period */
    PWMPOL = 0x01;
    PWMCAE = 0x00; /* The next statements selects left-aligned */
    PWMCTL = 0x80; /* halt PWM clock in wait mode */
    PWMPER0 = period; /* set period of PWM0 to 0.1 ms */
                      /* period in sec = 1/(bus clock / prescale_factor) * PWMPER0 */
                      /* (PWMPER0-PWMDTY0)/PWMPER0*100% */
    PWMDTY0 = init_duty; /* set duty cycle to (period-init_duty) /period *100% */
    PWME |= 0x01; /* enable PWM0 channel */
}

#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module.
Placement will be in NON_BANKED area. */
interrupt void TimerOverflow_ISR(void)
{
    TFLG2=0x80; /* clear Timer Interrupt Flag bit by a write*/
    i++;
    if (i<500)
    PORTB = 0xFF;
    if(i>500)
    PORTB = 0x00;
    if (i == 1000)
    i=0;
  
  
  
}
#pragma CODE_SEG DEFAULT

 

 

Thanks

Outcomes