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

18f46k22 interrupt no work
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
daniel82



Joined: 05 Jan 2011
Posts: 11

View user's profile Send private message

18f46k22 interrupt no work
PostPosted: Wed Jan 05, 2011 3:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 4:26 am     Reply with quote

Is that compiler problem? anyone can help me?? Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 2:21 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 7:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 7:55 pm     Reply with quote

Another test i using interrupt timer it doesn't work also Crying or Very sad

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

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 7:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 06, 2011 10:21 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 07, 2011 11:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 09, 2011 7:27 pm     Reply with quote

Yes it work, thank you very much! Laughing
daniel82



Joined: 05 Jan 2011
Posts: 11

View user's profile Send private message

PostPosted: Sun Jan 09, 2011 9:25 pm     Reply with quote

Another question Sad

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

View user's profile Send private message

PostPosted: Sun Jan 09, 2011 10:04 pm     Reply with quote

Add the "make_all_pins_digital()" function and call it at the start of your
program, as shown in the link below:
http://www.ccsinfo.com/forum/viewtopic.php?t=43961&start=6
daniel82



Joined: 05 Jan 2011
Posts: 11

View user's profile Send private message

PostPosted: Mon Jan 10, 2011 2:16 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 10, 2011 1:33 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 10, 2011 8:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jan 11, 2011 11:26 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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