|
|
View previous topic :: View next topic |
Author |
Message |
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
[Help] No want jump to RB_interrupts when start program |
Posted: Sun May 19, 2013 7:21 pm |
|
|
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
|
|
Posted: Sun May 19, 2013 8:22 pm |
|
|
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
|
|
Posted: Sun May 19, 2013 8:32 pm |
|
|
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
|
|
Posted: Sun May 19, 2013 11:45 pm |
|
|
You can clear PortB change interrupt flags by reading PortB before enabling the interrupt. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon May 20, 2013 12:28 am |
|
|
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
|
|
Posted: Mon May 20, 2013 12:45 am |
|
|
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
|
|
Posted: Mon May 20, 2013 1:07 am |
|
|
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,
Thanks &Regards. _________________ Begin Begin Begin !!! |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Mon May 20, 2013 1:12 am |
|
|
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 _________________ Begin Begin Begin !!! |
|
|
|
|
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
|