|
|
View previous topic :: View next topic |
Author |
Message |
daniel82
Joined: 05 Jan 2011 Posts: 11
|
18f46k22 interrupt no work |
Posted: Wed Jan 05, 2011 3:09 am |
|
|
Hi,
I'm 1st time using K series, may I know why interrupt no working on this chip but others chip working fine.
Please help!
Compiler ver 4.109.
Code: |
#include <18f46k22.h>
#fuses H4,NOWDT,NOPROTECT,NOLVP,INTRC
#use delay(clock=8Mhz)
#include <string.h>
#include <stdlib.h>
#INT_EXT2
void Ext2_interrupt()
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
delay_ms(1000);
}
void main()
{
ENABLE_INTERRUPTS(INT_EXT2);
EXT_INT_EDGE(2, H_TO_L);
ENABLE_INTERRUPTS(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
delay_ms(1000);
while(1)
{
}
}
}
|
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Thu Jan 06, 2011 4:26 am |
|
|
Is that compiler problem? anyone can help me?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 06, 2011 2:21 pm |
|
|
In your version of the compiler, CCS does not configure PortB as digital
by default. It is analog. That's why it doesn't work for INT_EXT2.
You can fix it by adding the line shown in bold below:
Quote: |
void main()
{
setup_adc_ports(NO_ANALOGS); |
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Thu Jan 06, 2011 7:44 pm |
|
|
Thanks for your reply, I added the command but still can't trigger the interrupt. What else I can do? I confirm no problem with my circuit.
Code: |
#include <18f46k22.h>
#fuses H4,NOWDT,NOPROTECT,NOLVP,INTRC
#use delay(clock=8Mhz)
#include <string.h>
#include <stdlib.h>
#INT_EXT2
void Ext2_interrupt()
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
delay_ms(1000);
}
void main()
{
SETUP_ADC_PORTS(NO_ANALOGS);
ENABLE_INTERRUPTS(INT_EXT2);
EXT_INT_EDGE(2, H_TO_L);
ENABLE_INTERRUPTS(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
delay_ms(1000);
while(1)
{
}
}
}
|
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Thu Jan 06, 2011 7:55 pm |
|
|
Another test i using interrupt timer it doesn't work also
Code: |
#include <18f46k22.h>
#fuses H4,NOPROTECT,NOLVP,INTRC
#use delay(clock=8Mhz)
/////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
INT CTR=0;
#INT_EXT2
void Ext_interrupt() //Read Sector1 Block0 data, password=8x12
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
delay_ms(1000);
}
#INT_TIMER1
void timer1_isr()
{
CTR++;
}
void main()
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
setup_adc_ports(NO_ANALOGS);
ENABLE_INTERRUPTS(INT_EXT2);
EXT_INT_EDGE(2, H_TO_L);
ENABLE_INTERRUPTS(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
delay_ms(1000);
while(1)
{
if (CTR>5)
{
output_high(PIN_D0);
delay_ms(200);
output_low(PIN_D0);
delay_ms(200);
}
else
{
CTR=0;
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 06, 2011 7:59 pm |
|
|
Does your external circuit look like this ? It needs to look similar to this:
Code: |
+5v
|
<
> 4.7K
< ___ Switch
To | _|_|_
PIC -----------------o o------
pin |
--- GND
-
|
You need a switch that connects to ground, and you need a pull-up
resistor as shown above.
Also, are you testing this on a real hardware board, or in Proteus ? |
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Thu Jan 06, 2011 10:21 pm |
|
|
Yes the design same as yours, the only diff is I used 10kohm. I do measure the PIC pin, when push button pressed, voltage from 5v to 0v.
Another test I try on PICkit 44-pin demo board, it connected INT0 (RB0) with switch, so I change the coding to
Code: |
#INT_EXT
void Ext_interrupt()
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
delay_ms(1000);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
ENABLE_INTERRUPTS(INT_EXT);
EXT_INT_EDGE(H_TO_L);
ENABLE_INTERRUPTS(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
delay_ms(1000);
while(1)
{
}
}
|
Same result I get, on the power PIN_D0 LED will on and off, after that I press button interrupt didn't trigger. I tested with PIN_D5 connection is good no problem.
I write another code test using internal timer1 it can not work also.
Code: |
#include <18f46k22.h>
#fuses H4,NOPROTECT,NOLVP,INTRC
#use delay(clock=8Mhz)
/////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
INT CTR=0;
#INT_EXT
void Ext_interrupt()
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
delay_ms(1000);
}
#INT_TIMER1
void timer1_isr()
{
CTR++;
}
void main()
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
setup_adc_ports(NO_ANALOGS);
ENABLE_INTERRUPTS(INT_EXT);
EXT_INT_EDGE(0, H_TO_L);
ENABLE_INTERRUPTS(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
delay_ms(1000);
while(1)
{
if (CTR>5)
{
output_high(PIN_D0);
delay_ms(200);
output_low(PIN_D0);
delay_ms(200);
}
else
{
CTR=0;
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 07, 2011 11:44 am |
|
|
I think I made a mistake. The setup_adc_ports() function does not work
correctly in vs. 4.109. You can fix the PortB problem as described below:
Try the program shown below. Note that it forces Port B to be a digital
port upon power-up by using the NOPBADEN fuse. Also note that the
'H4' fuse is not needed. Just use INTRC_IO for the 8 MHz internal oscillator.
Quote: |
#include <18F46K22.H>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP, NOPBADEN
#use delay(clock=8000000)
#INT_EXT
void ext_isr(void)
{
output_high(PIN_D5);
delay_ms(1000);
output_low(PIN_D5);
}
//=======================
void main()
{
ext_int_edge(L_TO_H);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
while(1);
} |
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Sun Jan 09, 2011 7:27 pm |
|
|
Yes it work, thank you very much! |
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Sun Jan 09, 2011 9:25 pm |
|
|
Another question
Now the problem from UART, the program run until blink the LED_C1 only, I can't get the msg "Send". What's wrong is that? I had read others ppl issue here same like me, but they haven't solve yet.
Code: |
#include <18f46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP, NOPBADEN
#use delay(clock=32MHz)
#use RS232 (baud=19200, xmit=PIN_D6, rcv=PIN_D7, STREAM=COM1)
void main()
{
ext_int_edge(L_TO_H);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
output_high(PIN_C1);
delay_ms(500);
output_low(PIN_C1);
fprintf(COM1,"\n\rSend");
output_high(PIN_C0);
delay_ms(500);
output_low(PIN_C0);
while(1);
{
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Mon Jan 10, 2011 2:16 am |
|
|
I have tested several time, still can't work, after the interrupt triggering, LED_D1 blink twice, but I didn't receive the msg "testing...".
Code: |
#include <18f46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=32MHz)
#use RS232(baud=19200, xmit=PIN_D6, rcv=PIN_D7, STREAM = COM1)
/////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
void make_all_pins_digital(void)
{
#byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;
}
INT CTR=0;
#INT_EXT
void Ext_interrupt()
{
output_high(PIN_D1);
delay_ms(1000);
output_low(PIN_D1);
printf(COM1, "testing...");
output_high(PIN_D1);
delay_ms(500);
output_low(PIN_D1);
delay_ms(500);
}
#INT_RDA
void rx_isr()
{
output_high(PIN_D2);
delay_ms(500);
output_low(PIN_D2);
delay_ms(500);
}
void main()
{
make_all_pins_digital();
ext_int_edge(0, H_TO_L);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
while(1);
{
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 10, 2011 1:33 pm |
|
|
You have to get the character inside the isr, to clear the int_rda interrupt.
You have call getc() or fgetc(). Example:
Quote: |
#INT_RDA
void rx_isr()
{
char c;
c = fgetc(COM1);
} |
#int_rda is only generated if you use the hardware UART, which is on
pins C6 and C7. Edit your #use rs232() statement as shown below to
add them. Also, if you put large delays inside the #int_rda routine (which
is not normally done), you must have the ERRORS directive in the #use
rs232() statement. In fact you should always put ERRORS in there, as
shown below:
Quote: |
#use RS232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, STREAM = COM1, ERRORS)
|
|
|
|
daniel82
Joined: 05 Jan 2011 Posts: 11
|
|
Posted: Mon Jan 10, 2011 8:32 pm |
|
|
i follow your instruction tested it work for:
Code: | #use RS232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, STREAM = COM1, ERRORS)
|
but i reserve PIN_C6 and PIN_C7 for RS485.
so i edit PIN_C6 to PIN_D6 and PIN_C7 to PIN_D7. but it cant work.
Code: | #include <18f46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP,NOPBADEN
#use delay(clock=32MHz)
#use RS232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, STREAM = COM1,ERRORS)
/////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
void make_all_pins_digital(void)
{
#byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;
}
#INT_EXT
void Ext_interrupt()
{
fprintf(COM1, "testing...");
output_high(PIN_D1);
delay_ms(500);
output_low(PIN_D1);
delay_ms(500);
}
#INT_RDA2
void rx_isr()
{
char c;
c = fgetc(COM1);
}
void main()
{
make_all_pins_digital();
ext_int_edge(0, H_TO_L);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
output_high(PIN_D0);
delay_ms(1000);
output_low(PIN_D0);
while(1);
{
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 11, 2011 11:26 am |
|
|
Version 4.109 has a lot of bugs with the 18F46K22 and 18F45K22.
I tested using the 2nd UART with vs. 4.116 and it works.
In the test program shown below, I get the following output:
Quote: |
Hi there
asdfasdfasdf
|
I just typed "asdf" a few times on the keyboard and it echoes the
characters correctly, so it's working.
Remember, this is with vs. 4.116. You are using vs. 4.109.
Code: |
#include <18F45K22.h>
#fuses INTRC_IO,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, ERRORS, stream=COM2)
#int_rda2
void rda2_isr(void)
{
char c;
c = fgetc(COM2);
fputc(c, COM2);
}
//======================================
void main(void)
{
fprintf(COM2, "Hi there\n\r");
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
while(1);
} |
Is there anyway you can upgrade to vs. 4.116 ? I think all your RS232
problems with the 18F46K22 would go away.
If you can't upgrade, I can look at the problem in vs. 4.109 and try to
come up with a solution. But it would be easier if you upgraded. |
|
|
|
|
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
|