|
|
View previous topic :: View next topic |
Author |
Message |
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
Can't clear mismatch condition (int_rb) |
Posted: Tue Sep 24, 2013 1:36 am |
|
|
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 _________________ Begin Begin Begin !!! |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Sep 24, 2013 8:15 pm |
|
|
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
|
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Wed Sep 25, 2013 8:34 pm |
|
|
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
|
|
Posted: Thu Sep 26, 2013 7:32 am |
|
|
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
|
|
Posted: Thu Sep 26, 2013 8:00 pm |
|
|
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
|
|
Posted: Fri Sep 27, 2013 12:40 am |
|
|
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
|
|
Posted: Fri Sep 27, 2013 4:21 am |
|
|
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. |
|
|
|
|
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
|