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

Can't clear mismatch condition (int_rb)

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



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

Can't clear mismatch condition (int_rb)
PostPosted: Tue Sep 24, 2013 1:36 am     Reply with quote

Hi all:)
I'm have a trouble when used PortB- on change interrupts in PIC18f46K22.
In my program, the interupts on change on Pin_B5 can't clear, so that, when start, it jump to int_isr and execute.
I used Pic18f46K22, CCS C ver 5.011.
Code:

#include <18F46K22.h>
#fuses HSH, PUT, NOPROTECT, NOLVP , NOWDT, PLLEN, NOPBADEN
#use delay(clock=40000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, errors) // HARD UART

unsigned int1 check_int_rb0=0, check_int_rb1=0, check_int_rb2=0;
unsigned int1 check_sa_so=0;
unsigned int8 temp=0;

#int_ext
void ngat_rb0(void)
{
   while(input(pin_B0==0)) delay_ms(10);
   check_int_rb0=1;
}

#int_ext1
void ngat_rb1(void)
{

   while(input(pin_B1==0)) delay_ms(10);
   check_int_rb1=1;
}

#int_ext2
void ngat_rb2(void)
{

   while(input(pin_B2==0)) delay_ms(10);
   check_int_rb2=1;
}

#int_rb
void ngat_rb(void)
{
   temp = input_b();
   delay_ms(10);
   if( input(PIN_B5)==0 || input(PIN_B5)==1 )
   {
      delay_ms(100);
      check_sa_so=1;
   } 
}

#int_rda
void ngat_rda( void)
{
   char c;
   c=getc();
   switch(c)
   {
      case '1': output_a(0x00); break;
      case '2': output_a(0xff); break;
      default:  break;
   }
}
//--------------------------------------------------------------------------------------------------------

void main(void)
{   
   delay_ms (1000);
   set_tris_a (0x00);   // input RA5: ESC button,,,,,, control A0 - A3: cs1, rst, cs2, cs3
                        // INOUT RA4: KBD DATA
   set_tris_b (0xFF);   // ngat keypad
   set_tris_c (0x80);   // input RC5: ENT button, RC0: TRK, RC7: RX
   set_tris_d (0);
   set_tris_e (0);      // control
       
   output_a(0xff);
   output_high(PIN_C1);
   output_low(PIN_C0);
   
   port_b_pullups (0x20);
   delay_us(100);
   temp |= input( PIN_B5);   
   clear_interrupt( int_rb);
   
   ext_int_edge (0, H_TO_L) ;
   clear_interrupt (int_ext);
   enable_interrupts (int_ext);
   
   ext_int_edge (1, H_TO_L) ;
   clear_interrupt (int_ext1);
   enable_interrupts (int_ext1);

   ext_int_edge (2, H_TO_L) ;
   clear_interrupt (int_ext2);
   enable_interrupts (int_ext2);   
   
   //enable_interrupts (int_rb5);
   enable_interrupts (int_rb);
   enable_interrupts( int_rda);
   enable_interrupts( global);
   
   clear_interrupt( int_rb);
   
   printf("\n\r test ");
   
   while(1)
   {
     
     
      if (check_int_rb0==1)
      {
         check_int_rb0=0;
         printf("\n\r Int_RB0_pressed ");
         output_toggle(PIN_A0);
      }
     
      if( check_int_rb1==1)
      {
         check_int_rb1=0;
         printf("\n\r Int_RB1_pressed ");
         output_toggle(PIN_A1);
      }
     
      if( check_int_rb2==1)
      {
         check_int_rb2=0;
         printf("\n\r Int_RB2_pressed ");
         output_high(PIN_A0);
         output_high(PIN_A1);
      }
     
      if(check_sa_so==1)
      {
         printf("\n\r Int_RB_pressed ");
         check_sa_so=0;
         if(input(PIN_B5)==0 )
         {
            output_low(PIN_A0);
            output_low(PIN_A1);
         }
         
         else
         {
            output_high(PIN_A0);
            output_high(PIN_A1);
         }     
      }
   } 

Pls show me way to fix it, thanks all Smile
_________________
Begin Begin Begin !!!
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Sep 24, 2013 8:15 pm     Reply with quote

your code is a mess

the delay loops in the ISR are slow death warmed over

and you need to read the whole B port as a byte, i believe to clear the INT
when the ISR branch is taken.

You should rethink the problem and use the ISR info ONLY
to feed a state machine, called from main.

just my 2 cents


Very Happy Very Happy
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Sep 25, 2013 8:34 pm     Reply with quote

Thanks u.
I will tried with read input PortB but it don't change, and the delay is too not change.
Have a another problems in my code ?:|
_________________
Begin Begin Begin !!!
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Sep 26, 2013 7:32 am     Reply with quote

the loop function inside each handler looks like a recipe for disaster.

using a delay_ms() call in an interrupt handler is horrible programming practice.

the 1st rule of interrupts is :
GET IN, && get OUT - FAST !!!

U R in violation of that in a non-deterministic way

ask yourself- if it Was working as intended, how would you know ??
What code execution can occur if a button is pressed and not released - or gets STUCK down ??

also
w/o knowledge of your circuitry, is hard to tell where your problem might lie.
but certainly the code in your ISR's is TROUBLE .

are the inputs to the port B pins - PUSHBUTTONS ??
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Sep 26, 2013 8:00 pm     Reply with quote

Code:

#int_rda
void ngat_rda( void)
{   
   switch(getc()){
      case '1': output_a(0x00); break;
      case '2': output_a(0xff); break;
    }
}
//there will always be at least one char to read  BUT there is the
// outside possibility
 // that another prior interrupt in process may allow 2 chars 2 arrive
//what about the POSSIBLE one left in the hardware buffer?
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 12:40 am     Reply with quote

It'll just interrupt again.

Will only happen if either a very high baud rate is being used, or something has delayed getting to the ISR. There is a whole character time between the interrupt happening, and reaching the point where a second character is available.

Since the interrupt can't be cleared, if there is another character, the routine will just be called a second time.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 27, 2013 4:21 am     Reply with quote

Just a few notes:
1) Keep your posted program as short as possible!
Your program contains a lot of code that's not related to your problem. We like short programs of about 10-20 lines. Do so and you will get more and better answers. Now many people see a large program and don't want to read it all.

2) You are setting the TRIS registers. This is something the compiler will do for you so these lines can be left out. Only in special situations you have to set the TRIS registers yourself but then also write the line '#use FAST_IO'.

3) In PIC processors the I/O pins are shared between multiple modules. Microchip made the strange decision to have the special devices be the default value. So, for making a digital I/O port you often have to disable the special device first. Check the data sheet for your processor (Table 10-4). What device do you see listed there on the RB5 pin?

4) As other people already told you, it is bad design to have a delay_ms() call inside your interrupt routines. Just imagine what happens when the 10ms delay is executed and serial data is arriving. At 4800 baud, it takes about 0.2ms for one character to arrive. In 10ms you can miss 50 characters!

5)
Code:
 if( input(PIN_B5)==0 || input(PIN_B5)==1 )
What are you trying to do here?
The input is always 1 or 0, so the if-statement will always be true. Doesn't make sense.


Please make changes to your program.
Post the new program. Maximum 20 lines!
Tell us what is working and what is not working.
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