CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

I need help with two interrupts

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nick_18



Joined: 22 May 2010
Posts: 2

View user's profile Send private message

I need help with two interrupts
PostPosted: Sat May 22, 2010 1:40 am     Reply with quote

hi I'm a newby programing in CCS and I have a problem, but first sorry for my bad english and I hope you understand.
Ok. I use the timer0 to control a countdown timer (00 to 99) that show in two 7 segment. I use the timer2 to set a pwm at 64khz. The problem is when both interrupts are enabled (the pwm and the countdown timer), the seven segment display begin flashing and the pic crash, pic stops responding and for example I can not use the buttons for setting the time.
Thanks for your help.

Here is the code and Proteus simulation.
Code:


#include<16F876A.h>
#fuses XT,NOPUT,NOWDT,NOLVP,NOPROTECT
#use delay(clock=8000000)
#byte TRISA=0x85
#byte TRISB=0x86
#byte TRISC=0x87
#byte PORTA=0x05
#byte PORTB=0x06
#define max_duty 124

signed int  d1,d2;
int16 duty_cicle;
long overflow;

                                                  // array with numbers 0 to 9
int show[]={0b00111111,0b00000110,0b01011011,0b01001111,
            0b01100110,0b01101101,0b01111101,0b00000111,   
            0b01111111,0b01100111};


void config(void){
      TRISA=0x00;
      TRISB=0x00;
      TRISC=0x00;
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16|RTCC_8_BIT);
      setup_timer_2(T2_DIV_BY_1,30,1);
      set_timer0(214);
     
}

void reset(void){
disable_interrupts(GLOBAL);
disable_interrupts(INT_RTCC);
disable_interrupts(INT_TIMER1);
}

#INT_RTCC
void RTCC(){
        //countdown
  overflow++;
 
  if(overflow>10000){ overflow=0; D2--;}
  if(D2<0){D2=9;D1--;}
  if(d1==0 && d2==0){break; reset();}
 
  set_timer0(214);
}

#int_timer2
void timer2_isr(void)     //PWM
{
static int8 increment = TRUE;

if(increment)
  {                                           
   duty_cicle++;

   if(duty_cicle == max_duty){
      increment = FALSE;
                                             
   }
  }
else
  {
   duty_cicle--;
     
   if(duty_cicle == 0)
      increment = TRUE;
     
   }   
set_pwm1_duty(duty_cicle);

}



void main()
{
disable_interrupts(global);
disable_interrupts(INT_RTCC);
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
config();

for(;;){


if(input(pin_a5)){ if(d1!=0 || d2!=0){     //pin_a5 button to begin the count time and pwm
      delay_ms(60);
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_RTCC);
      enable_interrupts(INT_timer2);
      setup_ccp1(CCP_PWM);
      }}
                 
if(input(PIN_A3)){                         //Increase time
      delay_ms(60);                 
      D2++;
        if(D2>=10){ D2=0; D1++;}
         if(D1>9){D1=0;D2=0;}
      }
     
if(input(PIN_A4)){if(d1!=0 || d2!=0){      //decrease time
      delay_ms(60);
      D2--;
      if(D2<0){ D2=9; D1--;}
      if(D1<0){D1=0;D2=0;}
      }}               
                 
               output_high(pin_a1);    // show time in display
               PORTB=show[D1];
               output_low(pin_a0);
               delay_ms(10);
               output_high(pin_a0);
               PORTB=show[D2];
               output_low(pin_a1);
               delay_ms(10);     
 }
 
}

The Proteus simulation is here

http://rapidshare.com/files/390237258/test.rar
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sat May 22, 2010 2:53 pm     Reply with quote

For timer2, if all you want is just pure pwm that doesn't change in any sort of time crticial way, you don't need to enable the interrupt. Just set the timer to run and your period values and the PWM will operate.

The only "interrupt" you need to really service is timer0.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Sat May 22, 2010 3:01 pm     Reply with quote

First a small problem. XT fuse selected. Max frequency recommended for this fuse, 4MHz....
Then, a comment. You select RTCC as 8bit, but the 876, _only_ has an 8bit RTCC. This option does nothing on this chip.

Your big problem is _time_.
The RTCC, is effectively counting in '8 instruction' ticks. You set it to 214. It'll then try to trigger every 336 instructions. Your Timer2 interrupt though, is set to reset at just 31 counts, and is counting in instructions. So, just 31 instructions between triggers. It takes typically 60 instructions to get into, and out of an interrupt. Add the code in the interrupt itself (perhaps another dozen instructions), and this interrupt will continuously trigger...
You need to slow down this interrupt to have any hope at all of the code working. The last value in the timer2 setup, is the number of PWM cycles between interrupt triggers, and is there just for this reason.
Realistically, drop the PWM to perhaps 20KHz, and interrup every fourth cycle, and you will have a 'chance'...

Best Wishes
nick_18



Joined: 22 May 2010
Posts: 2

View user's profile Send private message

PostPosted: Sat May 22, 2010 5:13 pm     Reply with quote

Thank you very much for you help.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group