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 support@ccsinfo.com

Need help with interrupts

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cypher



Joined: 05 Oct 2007
Posts: 31

View user's profile Send private message

Need help with interrupts
PostPosted: Fri Oct 19, 2007 11:14 am     Reply with quote

Hi,
I'm trying to write a simple program with interrupts. Bascially, the interrupt is on PORTB.0 on the rising edge. Here's what I have so far:
Code:

#include <18F8722.h>
#device ADC=10
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#use standard_io(D)
#use standard_io(E)

#define CLK_IN       PIN_D0
#define DAT_IN       PIN_D1
#define CS_PULSE   PIN_D2
#define   DAT_OUT      PIN_D5

#int_ext      //Use External Interrupt on PORTB.0
void interrupt_routine();

void shiftout(int byte5, int byte4, int byte3, int byte2, int byte1);

int switch1 = 0b10000000;
int switch2 = 0b10000000;
int switch3 = 0b10000000;
int switch4 = 0b10000000;
int control_w = 0b00001010;
int count   =   0;

void interrupt_routine(void)    //Interrupt subroutine
{

   clear_interrupt(int_ext);   //Clears the interrupt flag
   output_bit(DAT_IN,1);      //Toggles the LED on PIN_D1 if an interrupt is detected
   delay_ms(100);
   output_bit(DAT_IN,0);
   delay_ms(100);

}

void main()
{

//Setup ADC
output_d(0);
output_e(0);
set_tris_d(0x20);
set_tris_e(0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(ALL_ANALOG);

output_bit(CS_PULSE,0);

printf("Working");

set_tris_b(0x0F);
ext_int_edge(L_TO_H);
enable_interrupts(int_ext);

shiftout(switch4,switch3,switch2,switch1,control_w);

output_bit(CS_PULSE,1);
delay_us(100);

output_bit(CS_PULSE,0);
delay_us(100);

disable_interrupts(int_ext);
}


void shiftout(int byte5, int byte4, int byte3, int byte2, int byte1)
{

int a;

set_tris_d(0x20);


for(a = 0; a < 8; a++)
   {
      output_bit(CLK_IN,1);
      delay_ms(1);
      output_bit(CLK_IN,0);
      delay_ms(1);
      output_bit(CLK_IN,1);
      delay_ms(1);
      output_bit(CLK_IN,0);
      delay_ms(1);
   }

return;

}


Basically, I'm generating a clock on CLK_IN and connecting that to PORTB.0 and hoping to see the LED on PIN_D1 toggle everytime it detects an interrupt. However this does not seem to work. Does anyone know what i'm missing?
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 11:43 am     Reply with quote

Before you do anything else, you need a loop in your MAIN. Right now you're just going to sleep after your first trip through.
Guest








PostPosted: Fri Oct 19, 2007 11:45 am     Reply with quote

You enabled your interrupt then disable it again about 6 lines down and your code comes to and end.

try this

Code:
void main()
{

//Setup ADC
output_d(0);
output_e(0);
set_tris_d(0x20);
set_tris_e(0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(ALL_ANALOG);

output_bit(CS_PULSE,0);

printf("Working");

set_tris_b(0x0F);
ext_int_edge(L_TO_H);
enable_interrupts(int_ext);

shiftout(switch4,switch3,switch2,switch1,control_w);

output_bit(CS_PULSE,1);
delay_us(100);

output_bit(CS_PULSE,0);
delay_us(100);

while (1)
{
   //sit here and wait for interrupt to occur
   output_bit(CS_PULSE,1);
   delay_us(100);

   output_bit(CS_PULSE,0);
   delay_us(100);


}

disable_interrupts(int_ext);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 12:14 pm     Reply with quote

Your interrupt routine is not being compiled. You can see this if you
look at the .LST file. You must put the #int_ext directive right before
the isr, to tell the compiler that it is an isr. Do it like this:
Quote:

#int_ext
void interrupt_routine(void) //Interrupt subroutine
{

clear_interrupt(int_ext); //Clears the interrupt flag
output_bit(DAT_IN,1); //Toggles LED on PIN_D1 int is detected
delay_ms(100);
output_bit(DAT_IN,0);
delay_ms(100);

}


The 2nd thing is, you don't need function prototypes if the function
is placed above main(), so that the compiler has already seen it
before it's called in later code.
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 1:42 pm     Reply with quote

Also..

You have 200 msec of delay IN the isr. During this time, no other processing can take place. Don't use delays in an isr. Find some other way to do this in your main loop.

Ken
cypher



Joined: 05 Oct 2007
Posts: 31

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 3:44 pm     Reply with quote

Thanks for all your replies.
I made all the suggested changes and it still does not seem to work. I have a feeling it has something got to do with the INTCON register.

I think it should be cleared at the start of the program. How do you set INTCON = 0 in C. I cannot find the syntax for setting internal registers.

And is there any other way I can confrim an interrupt has been detected since toggling an LED or printf does not seem to work.
Guest








PostPosted: Fri Oct 19, 2007 4:59 pm     Reply with quote

This is what it looks like now. However I do not understand why its important to keep looping in the main function since the interrupt should occur when I go to the shiftout function and generate a clock.
Code:

#include <18F8722.h>
#device high_ints = TRUE
#device ADC=10
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT,NOPUT
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#use standard_io(D)
#use standard_io(E)


#int_ext      //Use External Interrupt on PORTB.0
void interrupt_routine(void);
#int_ext fast

#define CLK_IN       PIN_D0
#define DAT_IN       PIN_D1
#define CS_PULSE   PIN_D2
#define   DAT_OUT      PIN_D5


void shiftout(int byte5, int byte4, int byte3, int byte2, int byte1);

int switch1 = 0b10000000;
int switch2 = 0b10000000;
int switch3 = 0b10000000;
int switch4 = 0b10000000;
int control_w = 0b00001010;
int state   =   0;

void main()
{

//Setup ADC
output_d(0);
output_e(0);
set_tris_d(0x20);
set_tris_e(0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(ALL_ANALOG);

output_bit(CS_PULSE,0);

printf("Working");

set_tris_b(0x0F);
ext_int_edge(L_TO_H);
enable_interrupts(int_ext);

shiftout(switch4,switch3,switch2,switch1,control_w);


output_bit(CS_PULSE,1);
delay_us(100);


output_bit(CS_PULSE,0);
delay_us(100);

while (1)
{
   //sit here and wait for interrupt to occur
   output_bit(CS_PULSE,1);
   delay_ms(100);

   output_bit(CS_PULSE,0);
   delay_ms(100);

}

disable_interrupts(int_ext);

}

void shiftout(int byte5, int byte4, int byte3, int byte2, int byte1)
{

int a;

set_tris_d(0x20);


for(a = 0; a < 8; a++)
   {
      output_bit(CLK_IN,1);
      delay_ms(100);
      output_bit(CLK_IN,0);
      delay_ms(100);
      output_bit(CLK_IN,1);
      delay_ms(100);
      output_bit(CLK_IN,0);
      delay_ms(100);
   
   }

return;

}

#int_ext
void interrupt_routine(void)    //Interrupt subroutine
{

   clear_interrupt(int_ext);   //Clears the interrupt flag
   output_bit(DAT_IN,1);      //Lights an LED when interrupt occurs
   

}   
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 5:16 pm     Reply with quote

Quote:
#device high_ints = TRUE

You don't need to enable this feature right now. Delete it.


Quote:
#int_ext //Use External Interrupt on PORTB.0
void interrupt_routine(void);
#int_ext fast

The line in bold is just floating around in space. It shouldn't be there.
Interrupt directives only go in front of the Function Prototype, as above,
and in front of the actual isr routine. Delete the line in bold.


Quote:
set_tris_b(0x0F);
ext_int_edge(L_TO_H);
enable_interrupts(int_ext);
enable_interrupts(GLOBAL);

You need to enable Global interrupts, as shown in bold.

Quote:
while (1)
{
//sit here and wait for interrupt to occur
output_bit(CS_PULSE,1);
delay_ms(100);

output_bit(CS_PULSE,0);
delay_ms(100);
}

disable_interrupts(int_ext);
}

The line in bold is never executed. It doesn't do anything. Delete it.


There are other things, such as the TRIS settings on Port D.
You've defined Port D to use Standard I/O. In that mode, the compiler
will set the TRIS, as long as you use CCS pin i/o functions. You are
doing that. Therefore, you don't need those set_tris_d() statements.
cypher



Joined: 05 Oct 2007
Posts: 31

View user's profile Send private message

PostPosted: Fri Oct 19, 2007 7:48 pm     Reply with quote

Thanks...enabling the interrupts globally worked!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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