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

"INT_EXT" problem.

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



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

"INT_EXT" problem.
PostPosted: Fri Sep 30, 2011 2:10 pm     Reply with quote

Hi all !!
I have strange problem ! I want to use 1 or 2 INT_EXT for serial interrupts and gate the data from card reader. When I powered my schematics my CPU (PIC18F2525) blocking and do nothing! The Pic start working normally when "catch" ISR INT_EXT and INT_EXT1 if I defined 2 int_ext isr.
My compiler ver. is 4.104, my configuration for PIC 18F2525 it's:
Code:

      #include <18F2525.h>
      #device HIGH_INTS=TRUE
      #build (nosleep)
      #fuses HS,PROTECT,NODEBUG,PUT,NOWDT,NOBROWNOUT,NOLVP,NOCPB,MCLR
      //#fuses NOFCMEN,NOWRTB,NOIESO,NOPBADEN,NOXINST,
      #use delay(clock=11059200)
      #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,errors,STREAM=rs_485)
      #use rs232(baud=9600,rcv=PIN_B0,STREAM=GP_20_1,errors)
      #use rs232(baud=9600,rcv=PIN_B1,STREAM=GP_20_2,errors)

//.................................................

   #int_ext HIGH
   void EXT_GP20_1isr()               
   {
      buffer_GP20_1[index_gp20_1] = fgetc(GP_20_1);
      if(++index_gp20_1 == buffer_size_GP20)
      {
         index_gp20_1 = 0;
      }
      set_timer0(52500);
      clear_interrupt(int_TIMER0);       
      enable_interrupts(int_TIMER0);;
   }
   
   
#int_ext1
   void EXT_GP20_2isr()                   
   {
      buffer_GP20_2[index_gp20_2] = fgetc(GP_20_2);
      if(++index_gp20_2 == buffer_size_GP20)
      {
         index_gp20_2 = 0;
      }
      set_timer0(52500);
      clear_interrupt(int_TIMER2);       
      enable_interrupts(int_TIMER2);
   }

  #int_rda                                              //receive data from rs485;
   void rs485_isr ()
   {
      x = fgetc(rs_485);
      if(!packet)                                           
      {
         buffer_485_rx[index_485_rx] = x;
         if(++index_485_rx == buffer_size_485_rx)
         { 
             index_485_rx =0;
         }
         temp_index=index_485_rx;
         set_timer1(62500);
         clear_interrupt(int_TIMER1);       
         enable_interrupts(int_TIMER1);   
      }
   }
  // ...........................................................
   void main ()
   {
      delay_ms (1000);
      packet=0;
      index_485_rx=0;
      index_gp20_1=0;
      index_gp20_2=0;
      tony_fl = 0;
      card_rdy1=FALSE;
      card_rdy2=FALSE;
     
      fprintf(rs_485,"Projec running..->\n\r");
      lcd_init ();
      lcd_putc("\fLCD_test..");
     
      SETUP_ADC(ADC_OFF);
      SETUP_CCP1(CCP_OFF);
      SETUP_CCP2(CCP_OFF);
      setup_vref(FALSE);
      setup_comparator(NC_NC_NC_NC);
      setup_timer_0(T0_INTERNAL|T0_DIV_1);   //T0_DIV_8
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
      setup_timer_2(T2_DIV_BY_16, 0xc0, 10);
      //setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
     
      enable_interrupts(global);       
      enable_interrupts(int_rda);
      enable_interrupts(INT_EXT_H2L);
      enable_interrupts(INT_EXT1_H2L);
      port_b_pullups (TRUE);
//.........................................
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 4:59 pm     Reply with quote

You need to show a complete and compilable test program that fails.
Also, explain what you mean by "blocking and do nothing". Do you
mean that the fprintf() and lcd_putc() lines don't display anything ?

If so, first make a very small program with only fprintf() and lcd_putc()
(and lcd_init) and prove that you can display text. If so, then debug
the full test program by commenting out lines or sections of the program
until you discover which part is causing the failure to print.
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Sat Oct 01, 2011 2:38 am     Reply with quote

Several little comments though:

1) Get rid of the errors keyword on the GP_20_1, and GP_20_2 streams. These are doing nothing for you.
2) Understand, that if you perform an fgetc, on a software UART, the code will sit in the handler for 9.5/9600th second. So if you are receiving a byte on EXT1, and have started receiving, then receive an interrupt on ext, the code will jump to handle the data on B0, and return basically a mSec later. The receive code on EXT, will then _continue_, with the data now being garbage.

With the CCS software UART, you can _only_ receive on one software stream at a time. As written your code _will_ get garbage if data arrives on a second source at the same time, even if using interrupts

3) You don't show your timer interrupt handler, so no comments can be made about what effect this may also have on receiving data.
4) Enable the pullups, and clear the interrupts _before_ enabling them. Otherwise if the pins were low when you setup the interrupts, you will get a spurious receive at the start.

If you genuinely need to handle RS232 receive on three streams at the same time, you will have to change your approach. Use a timer interrupt at 19200 * per second or more, and poll the two serial lines in this, then when a start bit is seen, use a state machine to build the byte on subsequent interrupt calls, or have two 9600* per second interrupts available, and on the falling edge in int0/int1, delay for few uSec, then start one of these, and shift in the bits with state machines in these. The CCS software UART implementation, won't do it.

Best Wishes
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Sun Oct 02, 2011 3:29 pm     Reply with quote

Hi PCM, Ttelmah ! thanks for your reply! I will paste small test program that demonstrate my problem.
Code:
     
     
     
      #include <18F2525.h>
      #device HIGH_INTS=TRUE
      #build (nosleep)
      #fuses HS,PROTECT,NODEBUG,NOPUT,NOWDT,NOBROWNOUT,NOLVP,NOCPB,MCLR
      #use delay(clock=11059200)
      #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,errors,STREAM=rs_485)
      #use rs232(baud=9600,rcv=PIN_B0,STREAM=GP_20_1)
      #use rs232(baud=9600,rcv=PIN_B1,STREAM=GP_20_2)
 
      #define buffer_size_GP20       14
      #define buffer_size_485_tx     16
      #define buffer_size_485_rx     64
     
 // Global variable     
      //int1  packet;
      //int   index_485_rx,temp_index;
      //int   x;
      int   index_gp20_1;
      int   index_gp20_2;
      int1  card_rdy1,card_rdy2;
     
      int   buffer_GP20_1    [buffer_size_GP20];
      int   buffer_GP20_2    [buffer_size_GP20];
     
     
#int_ext HIGH
   void EXT_GP20_1isr()                      // ext_Gp20 interrupt receiver func;
   {
      buffer_GP20_1[index_gp20_1] = fgetc(GP_20_1);
      if(++index_gp20_1 == buffer_size_GP20)
      {
         index_gp20_1 = 0;
      }
      set_timer0(52500);
      clear_interrupt(int_TIMER0);       
      enable_interrupts(int_TIMER0);;
   }
   
   
#int_ext1
   void EXT_GP20_2isr()                     
   {
      buffer_GP20_2[index_gp20_2] = fgetc(GP_20_2);
      if(++index_gp20_2 == buffer_size_GP20)
      {
         index_gp20_2 = 0;
      }
      set_timer3(52500);
      clear_interrupt(int_TIMER3);       
      enable_interrupts(int_TIMER3);
   }
   
 
   #int_timer0 
   void timer_0_isr ()
   { 
      card_rdy1=TRUE;
      index_gp20_1 = 0;
      disable_interrupts(int_TIMER0);     
   }
 
  #int_timer3
   void timer_2_isr ()
   {
      card_rdy2=TRUE;
      index_gp20_2 = 0;
      disable_interrupts(int_TIMER3);     
   }
 

 void main (void)
      {
      delay_ms (1000);
      fprintf(rs_485,"Projec running...\n\r");
     
      SETUP_ADC(ADC_OFF);
      SETUP_CCP1(CCP_OFF);
      SETUP_CCP2(CCP_OFF);
      setup_vref(FALSE);
      setup_comparator(NC_NC_NC_NC);
      setup_timer_0(T0_INTERNAL|T0_DIV_1);   //T0_DIV_8
      setup_timer_3(T3_INTERNAL|T3_DIV_BY_1);
     
      enable_interrupts(global);       
      enable_interrupts(INT_EXT_H2L);
      enable_interrupts(INT_EXT1_H2L);
      clear_interrupt(INT_EXT);
      clear_interrupt(INT_EXT1);
       
      while (TRUE){
         fprintf(rs_485,"TEST UART ...\n\r");
         delay_ms(1000);
      }     
   }


PS. Ttelmah I know for garbage data if INT_EXT and INT_EXT1 occur on the same time, but I'm using LCD display in my project and show error message on lcd if data is garbage.

My general problem is why cpu don't reach: " while (TRUE){
fprintf(rs_485,"TEST UART ...\n\r");
delay_ms(1000);
} " ??
PIC reach "while (true)...." when get ext_isr if one or two ext_isr's for my case.
This event happen when reset or power up PIC.

Thanks for your attention !
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 02, 2011 6:47 pm     Reply with quote

Ttelmah told you to do this, but you didn't do it or you did the wrong thing:
Quote:

4) Enable the pullups, and clear the interrupts _before_ enabling them. Otherwise if the pins were low when you setup the interrupts, you will get a spurious receive at the start.


He means do it like this:
Code:

port_b_pullups(TRUE);

enable_interrupts(INT_EXT_H2L);
enable_interrupts(INT_EXT1_H2L);
clear_interrupt(INT_EXT);
clear_interrupt(INT_EXT1);

enable_interrupts(global);     


Also, I have found in the past that it can take some time for the Port B
pull-ups to completely pull-up. So add a short delay after that line,
like this:
Code:

port_b_pullups(TRUE);
delay_us(10);

enable_interrupts(INT_EXT_H2L);
enable_interrupts(INT_EXT1_H2L);
clear_interrupt(INT_EXT);
clear_interrupt(INT_EXT1);

enable_interrupts(global);
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Sun Oct 02, 2011 11:02 pm     Reply with quote

Hi PCM! I've external 4k7 pull up resistor on B0 and B1 pins.
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Mon Oct 03, 2011 12:58 pm     Reply with quote

I don't know, but pic get start work normaly if add keyword "INVERT" in :
Code:
#use rs232(baud=9600,rcv=PIN_B0,INVERT,STREAM=GP_20_1)
#use rs232(baud=9600,rcv=PIN_B1,INVERT,STREAM=GP_20_2)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 03, 2011 2:54 pm     Reply with quote

Quote:
pic get start work normaly if add keyword "INVERT

If it works with the INVERT parameter, it probably means:

1. You don't have a MAX232 chip or any inverter chip connected between
the PIC and card reader.

2. Your card reader sends out CMOS voltage level, inverted serial
port signals.

Are those two things true ?

Describe the connections between your card reader and the PIC.
Post a link to the data sheet for your card reader.
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Mon Oct 03, 2011 3:24 pm     Reply with quote

Hi PCM!
Yes my cardreader send rs232 compatible signal with 0-5v level (p-p) , and I'm inverting signal with sn74HC04. The form signal from card reader is OK,because I've a Scope and saw signal, and if disconnecting PIN_B0,PIN_B1 from schematics and connect only external pull up resistors THE Problem is same!!
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Tue Oct 04, 2011 2:44 pm     Reply with quote

The problem was solved with this configuration for interrupts:
Code:
         
      enable_interrupts(int_rda);
      enable_interrupts(INT_EXT_H2L);
      enable_interrupts(INT_EXT1_H2L);
      clear_interrupt(int_rda);
      clear_interrupt(INT_EXT);
      clear_interrupt(INT_EXT1);
      enable_interrupts(global);

And an external 4k7 resistors on PIN_B0 and PIN_B1.
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