|
|
View previous topic :: View next topic |
Author |
Message |
Besugo
Joined: 12 Mar 2011 Posts: 20
|
PIC18F27J13 External Interrupts |
Posted: Sat Mar 12, 2011 1:13 pm |
|
|
Hi!
I've been trying to execute an external interrupt on a PIC18F27J13 using ccs v4.110 but i run out of options.
I've tried everything I could imagine, here's my code:
Code: |
#include "Header Files/18F27J13.h"
#include "Header Files/setup.h"
#include <math.h>
#include <string.h>
#define BUFFER_SIZE 24
#define BYTE2 int16
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
int ack_pending = 0;
#include "Header Files/KNX.h"
#int_rda
void serial_isr() {
output_high(pin_A0);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_4 );
int t;
buffer[next_in]=fgetc(COM1);
t = next_in;
next_in = (next_in+1) %BUFFER_SIZE;
if(next_in==BUFFER_SIZE)
{
next_in = t; // Buffer full !!
}
set_timer1(64861);
}
#int_timer1
void timeout1()
{
disable_interrupts(int_rda);
setup_timer_1(T1_DISABLED);
set_timer1(64861);
check_buffer(buffer[0]);
output_low(pin_A0);
next_in = 0;
enable_interrupts(int_rda);
}
#INT_EXT
void remote_ir()
{
send_packet();
output_a(0xff);
}
void main() {
enable_interrupts(int_rda);
enable_interrupts(int_timer1);
enable_interrupts(INT_EXT);
//port_b_pullups(true);
//ext_int_edge( H_TO_L );
//setup_uart(UART_WAKEUP_ON_RDA, COM1);
enable_interrupts(periph);
enable_interrupts(global);
set_individual_address(0x01,0x01,0x03);
set_group_address(0x01,0x03);
while(1)
{
sleep(1);
}
}
|
I've even tried setting the INTCON register manually but with no sucess. This happens witn any external interrupt (INT1,2 etc) but not with INT_RB, that one seems to work, but the problem is that i need to set te edge H_TO_L.
I would appreciate your help.
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sun Mar 13, 2011 3:16 am |
|
|
_What_ happens?....
You say 'this happens', but don't tell us what the problem is.....
Now some comments though:
You don't show your #USE RS232 line. You are stopping receive at times. This _must_ have ERRORS, or if data arrives while the UART is stopped, the UART will be hung.
You wake the chip up on interrupts. You are aware of the limitations of this?. For instance, the first serial character received when you wake up, _will_ be garbage. This is because the UART clock is stopped when you sleep, so though the chip wakes on the falling edge of the start bit, the character timing _will_ be destroyed. Normally to have serial wake a chip, you need to have the code 'remain awake' for some time, once woken, and then send a dummy 'wake' character before the actual data, so the chip does not sleep during the message.
Several 'pointless' things:
1) Why disable int_rda when you arrive in the timer interrupt. _all_ interrupts are disabled when you are in the interrupt handler...
2) You don't show us your 'check_buffer', or 'send_packet' code, but do you really mean to be sending the first of these the character that is in the first buffer location?.
3) You enable the timer1 interrupt in the main, without having selected a clock source, divider etc..
4) Avoid non binary buffer sizes, with '%'. Either use a binary buffer size (16, 32 etc..), or change to simply testing against the size limit. Your code is then screwed, when you check for 'buffer full', by testing if 'next_in', can equal buffer size. It can't. The value from '%', is the remainder after division by the second value. If the value is 40, the result from '%', can only be 0 to 23. You seem to have half the code for a linear buffer, and half the code for a ring buffer, with the result being neither...
Best Wishes |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 5:06 am |
|
|
Hi.
Thanks for the reply and suggestions, they we're very helpful.
I have all the timer settings and rs232 settings in another files, but all of that it's working with no problems at all, my only problem it's with external interrupts. When I do an external interrupt on port RB0 for example, nothing happens, the interrupt it's not generated.
Thanks for your time. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sun Mar 13, 2011 5:53 am |
|
|
Problem here is that code that works perfectly in an 'outside' environment, _may_ give problems when used inside an interrupt...
You need to simplify, and prove whether things are actually doing basic things. So, something like:
Code: |
Code:
#include "Header Files/18F27J13.h"
#include "Header Files/setup.h"
#INT_EXT
void remote_ir(void) {
output_toggle(PIN_A0);
}
void main(void) {
enable_interrupts(INT_EXT);
ext_int_edge( H_TO_L );
enable_interrupts(global);
while(1) {
sleep(SLEEP_IDLE);
}
}
|
Then put a signal on the EXT interrupt, and see if A0 toggles.
You will also get an idea of the time taken to re-awaken, and get into an interrupt, by the delay between your incoming signal, and the line toggling.
Only once you have this basic level working, 'move on'.
It is like the guy who turns up at a garage, and says 'my car wanders all over the road'. Any sensible garage, would at the very least 'look' to see that the wheels are all pointing in the right direction, and probably put it on a ramp, and verify that the steering arms are connected, that the wheels don't move when pushed, _before_ testing it round the local streets. The same 'basic testing', is needed to debug problems.
best Wishes |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 8:04 am |
|
|
I've done exactly that but it still doesn't work. It doesn't go into #INT_EXT, and i've tried without sleep funtions, and with just something simples as enabling the int_ext interrupt, the global, and a simple toggle on pin A0. Nothing works.
Same thing happens if I define INT1, INT2, etc in other pins.
Thanks in advance. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Mar 13, 2011 8:27 am |
|
|
Please show the contents of the custom include files.
What TTelmah posted should work so something else is wrong. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 9:05 am |
|
|
Ok, here it goes:
I've simplified things and done this:
main.c:
Code: |
#include "18F27J13.h"
#fuses HS,NODEBUG,NOXINST,NOPROTECT,NOWDT,NOCLOCKOUT,
#use delay(internal=8MHz)
#use rs232(baud=9600, parity=N, bits=8, ERRORS, UART1, STREAM = COM1 )
#use rs232(baud=9600, xmit=PIN_C5,rcv=PIN_C4, parity=N, bits=8, ERRORS, UART2, STREAM = COM2 )
#int_ext
void interrupt()
{
output_toggle(pin_A0);
}
void main()
{
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
port_b_pullups(true);
enable_interrupts(global);
while(1)
{
}
}
|
Still nothing...
Thanks for your help. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sun Mar 13, 2011 9:42 am |
|
|
Ttelmah wrote: |
You wake the chip up on interrupts. You are aware of the limitations of this?. For instance, the first serial character received when you wake up, _will_ be garbage. This is because the UART clock is stopped when you sleep, so though the chip wakes on the falling edge of the start bit, the character timing _will_ be destroyed. Normally to have serial wake a chip, you need to have the code 'remain awake' for some time, once woken, and then send a dummy 'wake' character before the actual data, so the chip does not sleep during the message.
|
Right -- I wrote a routine in the past that woke up the chip from sleepy mode and the first char was a throw-away. The system would then come up out of sleep and print something like, "system awake.... hit '?' for help..." _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 9:45 am |
|
|
Yes sure, i'm aware of the limitations of wake from sleep, but i can't do a simple external interrupt for some reason, even if i don't put the PIC to sleep.
Thank to everyone for your help. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Mar 13, 2011 10:12 am |
|
|
OK to make sure the basic chip is functioning:
Code: |
#include "18F27J13.h"
#fuses HS,NODEBUG,NOXINST,NOPROTECT,NOWDT,NOCLOCKOUT,
#use delay(internal=8MHz)
//#use rs232(baud=9600, parity=N, bits=8, ERRORS, UART1, STREAM = COM1 )
//#use rs232(baud=9600, xmit=PIN_C5,rcv=PIN_C4, parity=N, bits=8, ERRORS, UART2, STREAM = COM2 )
#int_ext
void interrupt()
{
output_toggle(pin_A0);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
port_b_pullups(true);
enable_interrupts(global);
while(1)
{
output_toggle(pin_A1);
delay_ms(500);
}
|
Does A1 blink with this code?
Edit: I forgot to add setup_adc_ports(NO_ANALOGS) _________________ Google and Forum Search are some of your best tools!!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sun Mar 13, 2011 10:39 am |
|
|
and to change the clock fuse to INTRC. Though the 'clock' line should select this, having HS selected as well could well result in the chip not running....
Best Wishes |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 10:48 am |
|
|
The chip is running, it blinks.
:( |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Mar 13, 2011 12:42 pm |
|
|
That is actually good. At least we have something to build on.
I assume the interrupt still does not work? I that's the case we may need to
look at the code enabling the interrupts, it may be wrong. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Mar 13, 2011 12:48 pm |
|
|
OK Try this:
Code: |
include "18F27J13.h"
#fuses HS,NODEBUG,NOXINST,NOPROTECT,NOWDT,NOCLOCKOUT,
#use delay(internal=8MHz)
//#use rs232(baud=9600, parity=N, bits=8, ERRORS, UART1, STREAM = COM1 )
//#use rs232(baud=9600, xmit=PIN_C5,rcv=PIN_C4, parity=N, bits=8, ERRORS, UART2, STREAM = COM2 )
#int_ext
void interrupt()
{
output_toggle(pin_A0);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
port_b_pullups(true);
enable_interrupts(global);
while(1)
{
output_toggle(pin_A1);
delay_ms(500);
}
|
_________________ Google and Forum Search are some of your best tools!!!!
Last edited by dyeatman on Sun Mar 13, 2011 12:49 pm; edited 1 time in total |
|
|
Besugo
Joined: 12 Mar 2011 Posts: 20
|
|
Posted: Sun Mar 13, 2011 12:48 pm |
|
|
I posted the code above, I enable the interrupts in main. Is that what you were talking about? |
|
|
|
|
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
|