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

[Help] No want jump to RB_interrupts when start program

 
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

[Help] No want jump to RB_interrupts when start program
PostPosted: Sun May 19, 2013 7:21 pm     Reply with quote

Hi all.
I'm having a trouble with RB_interrupts.
My program auto jump to RB_interrupt_service when my program starts.
I don't want this because it make my program is failure.
Please show me a way to fix this problem.

In my project, used:
+ Pic18LF4680
+ CCS C version 4.140
Code:

#include <18LF4680.h>
#fuses HS,PUT,NOPROTECT,NOLVP,NOWDT,NOBROWNOUT
#device *=16 //HIGH_INTS=TRUE
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors) // HARD UART
#define DS1307_SDA  PIN_C4
#define DS1307_SCL  PIN_C3
//!#use i2c(master, sda=DS1307_SDA, scl=DS1307_SCL)
//!#priority rda
#use fast_io (B)
#use fast_io (D)
#use fast_io (A)
#use fast_io (E)
#int_timer0

void ngat_timer0()
{
   set_timer0 (61);
   ++i;
   ++j;

   if (i == 100) // 100 * 10ms = 0.5s
   {
      i = 0;
      output_toggle (PIN_a0);
     
      if (input (PIN_B5) == 0)
      {
         putc ('$');
         putc ('S');
         putc ('A');
         putc ('#');
         //output_low (PIN_e1);
      }

      else if (input (PIN_B5) == 1)
      {
         putc ('$');
         putc ('S');
         putc ('O');
         putc ('#');
         //output_high (PIN_e1);
      }
   }

   //-------------------------------------------------------------------------------
   if (j == 500) // 5s se kiem tra trang thai ket noi voi PC 1 lan
   {
      j = 0;
     
      if (check_link_pc = 0)
      {
         //check_save_eeprom = 1;
      }
   }
}
//-------------------------------------------------------------------
#int_rb // detect ON/OFF BIEN TAN

void ngat_rb()
{
   output_low (PIN_E1);
   disable_interrupts (int_rb);
   delay_ms (1000);

   if (input (PIN_B5) == 0)
   {
      putc ('$');
      putc ('S');
      putc ('A');
      putc ('#');
      //delay_ms (50);
      putc ('$');
      putc ('S');
      putc ('A');
      putc ('#');
      output_low (PIN_E0) ;
      check_sa = 1;
      goto out_int1;
   }

   else
   {
      putc ('$');
      putc ('S');
      putc ('O');
      putc ('#');
      //delay_ms (100);
      putc ('$');
      putc ('S');
      putc ('O');
      putc ('#');
     
      if (check_sa == 1)
      {
         check_sa = 0;
         output_low (PIN_E0) ;
         reset_cpu () ;
         //output_high (PIN_A1);
         //check_sa = 0;
      }

      goto out_int1;
   }

   out_int1:
   set_timer0 (61);
   enable_interrupts (int_timer0);
   enable_interrupts (int_rb);
}
void main(void)
{
   //delay_ms (3000);
   set_tris_a (0); // control A0 - A3: cs1, rst, cs2, cs3
   set_tris_b (0xff); // ngat keypad
   set_tris_c (0x80); //
   set_tris_d (0);
   set_tris_e (0); // control
   
   clear_interrupt (int_rb) ;
   clear_interrupt (int_ext);
   
   output_a (0x00);
   output_e (0xff);
   port_b_pullups (TRUE);
   
   
   
   //------------------------------------------------
   // INIT INTERRUPTS EDGE --- int EXT 0
   //------------------------------------------------
   ext_int_edge (0, H_TO_L) ;
   clear_interrupt (int_ext);
   enable_interrupts (int_ext);
   
   set_timer0 (61);
   setup_timer_0 (RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256); // setup timer0: 10ms
   enable_interrupts (int_timer0);
   enable_interrupts (int_rb); // neu khai bao lenh nay ma phan cung ko ket noi voi ngat onchange portB - > code ko chay
   enable_interrupts (int_rda);
   enable_interrupts (global);
   
   //output_high (PIN_E0);         
   //------------------------
   // INIT DS1307
   //------------------------
   //!   init_ds1307 (); // initial DS1307
   //!   sec = read_ds1307 (0) ;
   //!   write_ds1307 (0, sec&0x7F); // enable oscillator (bit 7 = 0)
   //!   delay_ms (1);
   //!   settime_ds1307 ();
   //!   delay_ms (100);
   
//!   putc('$');
//!   putc('1');
//!   putc('R');
//!   putc('S');
//!   putc('T');
//!   putc('E');
//!   putc('D');
//!   putc('#');
   
   delay_ms(500);
   

   while (1)
   {
      //----------------------------------------------------------
      // KIEM TRA GOI LAI GIA TRI UPDATE COUNTER KHI NHAN $1SEND#
      //----------------------------------------------------------
      if (check_send_count_data == 1)
      {
         send_count_data ();
         check_send_count_data = 0;
      }

     
     
   }
}




Thanks & Regards.
_________________
Begin Begin Begin !!!
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sun May 19, 2013 8:22 pm     Reply with quote

all those putc() calls are a MAJOR problem !!!

and should NEVER be used inside an interrupt function.
the execution time will sooner or later cause other trouble

the rule of interrupt handlers is GET out fast - do slow stuff
like send characters in MAIN or elsewhere.

use a flag character to record the IO state
and send your bytes in MAIN
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Sun May 19, 2013 8:32 pm     Reply with quote

asmboy wrote:
all those putc() calls are a MAJOR problem !!!

and should NEVER be used inside an interrupt function.
the execution time will sooner or later cause other trouble

the rule of interrupt handlers is GET out fast - do slow stuff
like send characters in MAIN or elsewhere.

use a flag character to record the IO state
and send your bytes in MAIN


thank you, asmboy
My problem is program auto jump to rb_interrupts service function when often PIC startup, but I don't want this, I want the rb_interrupts service function run when detected level change on RB7-RB4, not run when PIC is startup.
Pls show me fix it
thanks& regards
_________________
Begin Begin Begin !!!
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun May 19, 2013 11:45 pm     Reply with quote

You can clear PortB change interrupt flags by reading PortB before enabling the interrupt.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon May 20, 2013 12:28 am     Reply with quote

Yes.

The key thing to understand is what INT_RB 'is'.
It is triggered whenever the internal 'latch' disagrees with what is seen on the pins.
Clearing the interrupt won't work, until the latch matches.
Now the latch wakes up in a state that may not agree with what it on the pins.

So sequence to ensure the interrupt is cleared is:

1) Read the port. This sets the latch to match the current pins.
2) Clear the interrupt.
3) Now enable the interrupt.

As a further comment, there is no point in disabling and enabling the interrupt in the handler.

The handler really is an example of 'bad' interrupt handling, as asmboy has said. If you want to do a job when the interrupt triggers, then read the pin, set a flag, and exit. In the main, when the flag is set, trigger the handling event. General 'rule of thumb', is to do as little as possible actually inside the interrupt handler.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 20, 2013 12:45 am     Reply with quote

Use this code to setup the interrupt-on-change interrupts:
Code:

void main(void)
{
int8 temp;

port_b_pullups(TRUE);
delay_us(10);      // Allow time for weak pullups to rise up
temp |= input_b();  // Read PortB to clear change condition
clear_interrupt (INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
.
.
.

The reason for ORing the 'temp' variable with PortB is because the
18F4680 data sheet says the change condition can be cleared by:
Quote:

a) Any read or write of PORTB (except with the MOVFF (ANY),
PORTB instruction). This will end the mismatch condition.

In the .LST file code below, you can see that just reading PortB generates
the MOVFF instruction, which Microchip says to avoid. By changing it to
OR 'temp' with PortB, it generates the MOVF instruction which is OK:
Code:
.................... temp = input_b();
0022A:  MOVFF  PORTB,temp
.................... 
.................... temp |= input_b(); 
0022E:  MOVF   PORTB,W
00230:  IORWF  temp,F
.................... 
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Mon May 20, 2013 1:07 am     Reply with quote

Ttelmah wrote:
Yes.

The key thing to understand is what INT_RB 'is'.
It is triggered whenever the internal 'latch' disagrees with what is seen on the pins.
Clearing the interrupt won't work, until the latch matches.
Now the latch wakes up in a state that may not agree with what it on the pins.

So sequence to ensure the interrupt is cleared is:

1) Read the port. This sets the latch to match the current pins.
2) Clear the interrupt.
3) Now enable the interrupt.

As a further comment, there is no point in disabling and enabling the interrupt in the handler.

The handler really is an example of 'bad' interrupt handling, as asmboy has said. If you want to do a job when the interrupt triggers, then read the pin, set a flag, and exit. In the main, when the flag is set, trigger the handling event. General 'rule of thumb', is to do as little as possible actually inside the interrupt handler.

Best Wishes


thank you , Ttelmah
I fixed this problem by adding command read portb before enable RB interrupts
Code:
unsigned int8 temp =input_b();
clear_interrupt(int_rb);
enable_interrupts(int_rb);


and I added flag to send string into main function.

Quote:
As a further comment, there is no point in disabling and enabling the interrupt in the handler.

this mean i don't need to dissable and after enable interrupts because in interrupt service function , another interrupt is auto dissable?
I'm begin with a Pic again, so that some questions is not right,Smile
Thanks &Regards.
_________________
Begin Begin Begin !!!
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Mon May 20, 2013 1:12 am     Reply with quote

PCM programmer wrote:
Use this code to setup the interrupt-on-change interrupts:
Code:

void main(void)
{
int8 temp;

port_b_pullups(TRUE);
delay_us(10);      // Allow time for weak pullups to rise up
temp |= input_b();  // Read PortB to clear change condition
clear_interrupt (INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
.
.
.

The reason for ORing the 'temp' variable with PortB is because the
18F4680 data sheet says the change condition can be cleared by:
Quote:

a) Any read or write of PORTB (except with the MOVFF (ANY),
PORTB instruction). This will end the mismatch condition.

In the .LST file code below, you can see that just reading PortB generates
the MOVFF instruction, which Microchip says to avoid. By changing it to
OR 'temp' with PortB, it generates the MOVF instruction which is OK:
Code:
.................... temp = input_b();
0022A:  MOVFF  PORTB,temp
.................... 
.................... temp |= input_b(); 
0022E:  MOVF   PORTB,W
00230:  IORWF  temp,F
.................... 


thank you, PCM programmer.
I have fixed similar as your way, thank you again, PCM programmer Smile
_________________
Begin Begin Begin !!!
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