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 CCS Technical Support

SOLVED:Help in INTERRUPT required for PIC16F873A

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



Joined: 02 Aug 2013
Posts: 2

View user's profile Send private message

SOLVED:Help in INTERRUPT required for PIC16F873A
PostPosted: Fri Aug 02, 2013 11:50 pm     Reply with quote

I am having problem with interrupts in 16f873a, I have 3 interrupts required for Bulb Dimmer project.
Timer0- Used for pulse modulation.
INT_RB-Port on change interrupt to detect zero crossing detect.
Serial INT_RDA- To receive serial data.

My problem is when I enable port on change interrupt serial data is not being received i.e. my serial interrupt doesn't work.

Here is my code.
Please help urgent.
Code:

#use rs232(xmit=PIN_C6,rcv=PIN_C7,enable=PIN_B0,baud=9600)

#define MINIMUM_FIRING_ENGLE   170
#define MAXIMUM_FIRING_ENGLE   220

//#BYTE PORTB = 0x05
//#BYTE PORTC = 0x07
#define CH1_ON    0x03
#define CH1_OFF   0x04
#define CH2_ON    0x05
#define CH2_OFF   0x06
#define CH3_ON    0x07
#define CH3_OFF   0x08
#define CH1_UP    0x09
#define CH1_DOWN  0x0a
#byte PortB = getenv("SFR:PortB")

void initialize_ports(void);
void initialize_variables(void);
void read_pot_position(void);
void shift_buff(void);
void shift_adc_buff(void);
void change_position(void);
unsigned int8 fire_on_delay;
unsigned int8 firing_angle;
unsigned int1 TRAIC_GATE;
unsigned int8 data;
 int8 count;
 unsigned int1 ch1_dim=0;//unsigned int8 temp_port_a;
//------------------------------------------------------------------------------
#int_RDA
void RDA_isr(void)

   data = getc();
//   enable_interrupts(INT_RB);
}
//------------------------------------------------------------------------------

#int_RB
void  RB_isr(void)       // Zero Cross Detect _ to Pin RB5         
{
   int8 current;
   static int last=0;
   TRAIC_GATE=1;
   disable_interrupts(INT_RB);
   set_timer0(firing_angle);
   enable_interrupts(INT_TIMER0);       //Enable timer0 interrupt
   set_tris_b(0xF0);
   current=input_b();
   last=current;
   enable_interrupts(INT_RB);
}
//------------------------------------------------------------------------------
#int_TIMER0
void  TIMER0_isr(void)
{
   disable_interrupts(INT_TIMER0);               //disable timer0 interrupt
   if(TRAIC_GATE)
   {
      output_low(PIN_A2);
      TRAIC_GATE=0;
      set_timer0(fire_on_delay);
      enable_interrupts(INT_TIMER0);
   }
   else if(!TRAIC_GATE)
   {
      output_high(PIN_A2);
      TRAIC_GATE=1;
   }
}
//------------------------------------------------------------------------------
void main()
{

   port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
//   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   TRAIC_GATE=0;
   count=145;          //MINIMUM_FIRING_ENGLE;
   initialize_ports();
   initialize_variables();
   enable_interrupts(INT_RB);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);   
   while(TRUE)
   {
       switch(data)
       {
         case CH1_ON:
//                  output_high(PIN_A0);
//                  output_low(PIN_A2);
                  count=220;
//                  fire_valu_calc();
                  ch1_dim=1;                 
            break;
         case CH1_OFF:
//                  output_low(PIN_A0);
                  output_high(PIN_A2);
//                  ch1_on=0;
                  ch1_dim=0;
            break;
         case CH2_ON:
                  output_high(PIN_A0);
            break;
         case CH2_OFF:
                  output_low(PIN_A0);
            break;
         case CH3_ON:
                  output_high(PIN_A1);
         
            break;
         case CH3_OFF:
                  output_low(PIN_A1);
            break;
         default:
            break;
       }
    if(!input(PIN_C2))
    {
      delay_ms(50);
      if(! input(PIN_C2))
      {
         if(count < 220)
         {
            count++;
         }
         else
         {
            count =220;
         }
      }
    }
    if(! input(PIN_C3))
    {
      delay_ms(50);
      if(! input(PIN_C3))
      {
         if(count > 145)
         {
            count--;
         }
         else
         {
            count =145;
         }
      }
    }
    initialize_variables();
   }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void initialize_ports(void)
   {
   output_low(PIN_A0);
   output_low(PIN_A1);
   output_high(PIN_A2);
//   output_float(PIN_A3);
//   output_float(PIN_A4);
//   output_float(PIN_A5);

//   output_high(PIN_C0);
//   output_float(PIN_C1);
//   output_high(PIN_C2);
//   output_high(PIN_C3);
//   output_float(PIN_C4);
//   output_high(PIN_B5);
   }
//------------------------------------------------------------------------------
void initialize_variables(void)
{
     firing_angle = count;
     fire_on_delay= 400-firing_angle;
}
//------------------------------------------------------------------------------
[/b]

Last edited by Harish on Tue Aug 06, 2013 10:11 am; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Aug 03, 2013 5:26 am     Reply with quote

just a few comments...things you can think over...no particular order...

1) ...
fire_on_delay= 400-firing_angle
...
what's the biggest number an unsigned int8 can have in it?

2) you could 'clean up' the program by assigning all variables as 'global'.you've got lots of RAM for this small program, making it simpler to follow.

3) add comment 'headers' before prototype, variable assignments, etc.,again, just to tidy things up and be organized.The neater a program looks, the faster you'll see mistakes.

4) ISRs must be short and fast.First operation within the INT_RB should be to read the portB.There's no need to disable interupts within an ISR, compiler handles it for you.

5)same hold true for set_tris....let the compiler do it ,automatically.

6) always add 'errors' to the #use rs232(..options..).it keeps the UART from 'locking up'.

7) you've chosen B0 to be the enable pin,presumably for an RS-485 network ? Not required for RS-232.

8) Triac is spelled TRIAC not TRAIC.Again, something to 'tidy up' your program,it can be confusing to another programmer.

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 12:31 am     Reply with quote

One possibility Change the ISR to:

Code:

#int_RB
void  RB_isr(void)       // Zero Cross Detect _ to Pin RB5         
{
   int8 current;
   static int8 current;
   current=input(PIN_B5);
   if (last!=current)
   {
      //Here B6 has changed
      TRIAC_GATE=1;
      set_timer0(firing_angle);
      enable_interrupts(INT_TIMER0);       //Enable timer0 interrupt
      last=current;
   }
}


The comments about INT_RB already made apply.
Then, there is an erratum on some PIC 16's, where a movf from the input port, won't reset the latch (this is what a byte wide input does). I couldn't find it listed for this one, but switching to testing just the one pin, avoids this.
Final one though is that if noise is picked up on the other pins of portB, this could trigger the interrupt at the wrong time. Given the noise likely from a triac circuit, this may be causing your problems....

Best Wishes
Harish



Joined: 02 Aug 2013
Posts: 2

View user's profile Send private message

PostPosted: Mon Aug 05, 2013 12:25 pm     Reply with quote

Ttelmah wrote:
One possibility Change the ISR to:

Code:

#int_RB
void  RB_isr(void)       // Zero Cross Detect _ to Pin RB5         
{
   int8 current;
   static int8 current;
   current=input(PIN_B5);
   if (last!=current)
   {
      //Here B6 has changed
      TRIAC_GATE=1;
      set_timer0(firing_angle);
      enable_interrupts(INT_TIMER0);       //Enable timer0 interrupt
      last=current;
   }
}


The comments about INT_RB already made apply.
Then, there is an erratum on some PIC 16's, where a movf from the input port, won't reset the latch (this is what a byte wide input does). I couldn't find it listed for this one, but switching to testing just the one pin, avoids this.
Final one though is that if noise is picked up on the other pins of portB, this could trigger the interrupt at the wrong time. Given the noise likely from a triac circuit, this may be causing your problems....

Best Wishes


Thank you Ttelmah you save the day for me your code applied and it worked thank you again
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Tue Aug 06, 2013 9:28 am     Reply with quote

Thanks for posting back - you might like to flag the thread as 'solved'.
It makes it much more useful for other people looking in the future. Smile
It is annoying when the thread just 'dies' without knowing what did/didn't work.

Best Wishes
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