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

#INT_EXT
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
gg
Guest







#INT_EXT
PostPosted: Sun Sep 02, 2007 1:06 am     Reply with quote

i'm using 12F683 and I need to know if it is possible to use PIN interrupt (#INT_EXT) on other IO pins instead of pin 5. Pin 5 in the datasheet has "INT" label.

Because I want to use PWM output in my program, I need to free up pin 5. I also need ext interrupt so this is a problem for me.

Thanks.
Ttelmah
Guest







PostPosted: Sun Sep 02, 2007 2:19 am     Reply with quote

Simple answer. No.
This is a problem of these very small chips. They have more abilities, than there are pins, and in some cases, using one ability, prevents another from being used. :-(
However, that having been said, there may be another solution. There is the 'pin changed' interrupt, which on this chip (unlike most others), is programmable on a 'per pin' basis. This will give you an interrupt on both the rising edge, and falling edge of the selected pin(s), and you will need to read the pin(s) in the interrupt handler to clear the event, and to find out which edge is being responded to. This interrupt can be setup/used, with the 'INT_RAx' definitions, where the 'x' selects the required pin. :-)

Best Wishes
libor



Joined: 14 Dec 2004
Posts: 288
Location: Hungary

View user's profile Send private message

PostPosted: Sun Sep 02, 2007 10:21 am     Reply with quote

There's also another option: You can use the built-in analog comparator ported on pins 6 and 7. It can trigger an interrupt when the voltage on one input crosses the other input's level. You can set the reference to the half of the supply voltage, and use the comparator's other input as a 'digital' PIN interrupt.
gg
Guest







PostPosted: Sun Sep 02, 2007 9:46 pm     Reply with quote

I did a search and found some example code

Code:
#include <12F683>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR
#use delay(clock = 8000000)
#use rs232(baud=9600, xmit=PIN_A1,rcv=PIN_A3)
#byte INTCON = 0x8B

#int_ra
void ioc_isr(void)
{
int8 c;

c = input_a();
output_high(PIN_A5);
}



//============================
void main()
{
int c;

c = input_a();
clear_interrupt(INT_RA);
clear_interrupt(INT_EXT);

// Then enable the interrupts.
enable_interrupts(INT_RA);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);

while(1)
{

}

}


I tried this code but it doesn't seem to work. My test LED should light up when an interrupt breaks when I input a squarewave to RA4.

What is the problem?

Thanks.
gg
Guest







PostPosted: Mon Sep 03, 2007 12:17 am     Reply with quote

problem solved.

I didn't correctly setup the IO pins.
Ttelmah
Guest







PostPosted: Mon Sep 03, 2007 2:29 am     Reply with quote

If you change it, so that the references to 'INT_RA', are to 'INT_RA4', then the compiler wll automatically add the bit masking, so this only responds to RA4, not any other pin. :-)
The comparator solution is another neat approach. Potentially allows three separate external interrupts on this chip.

Best Wishes
Kova



Joined: 06 May 2007
Posts: 35

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 2:41 am     Reply with quote

I have the same problem.
I have a 12F683 pic with the:
-GP2 setted like PWM
-GP0 input (a switch)
-GP5 setted in output (a LED)

This is my code:
Code:

#include <12F683.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPUT                      //Power Up Timer
#FUSES BROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#byte INTCON = 0x8B

#int_ra
void ioc_isr(void)
{
int8 c;
output_high(PIN_A5);
c = input_a();

}

void main()
{
set_tris_a(1);
clear_interrupt(INT_RA);
clear_interrupt(INT_EXT);

// Then enable the interrupts.
enable_interrupts(INT_RA0);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
   
   //36Khz
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,55,1);
   
   setup_ccp1(CCP_PWM);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   
   setup_oscillator(OSC_8MHZ);
   
   while(1)
  {
   setup_timer_2(T2_DIV_BY_1,55,1);
   set_pwm1_duty(27);
   }
}


The PWM works until the GP0 switch is pressed Crying or Very sad
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 3:25 am     Reply with quote

Quote:
The PWM works until the GP0 switch is pressed
There is no interrupt handler for INT_EXT. Without a handler the interrupt is never cleared and the processor will forever process the interrupt.


Another few minor remarks:
Code:
   setup_oscillator(OSC_8MHZ);
This line is very late in your code. The code works because this line is not needed at all since you have a '#use delay' line as well which is doing the same thing.

Code:
   while(1)
  {
   setup_timer_2(T2_DIV_BY_1,55,1);
   set_pwm1_duty(27);
   }
You have to configure the timer and pwm routines only one time. Now you are wasting CPU power and there are some nasty side effects possible so move this out of the loop.
Kova



Joined: 06 May 2007
Posts: 35

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 4:20 am     Reply with quote

ckielstra wrote:
Without a handler the interrupt is never cleared and the processor will forever process the interrupt.

Sorry, which handler I can put under the INT_EXT tag?
In the 12F683 the external interrupt is on the same pin of PWM :(

Rolling Eyes Rolling Eyes
Ttelmah
Guest







PostPosted: Mon Sep 03, 2007 5:14 am     Reply with quote

Get rid of the enable for INT_EXT.
If you enable an interrupt wthout a handler, and the interrupt flag gets set by any means, it hangs the processor in the global interrupt hadler. Now, the 12F683, has the internal 'INT' connection, made all the time, even if the pin is used for something else (the only exception is when the port is used as an analog input - look at Fig 4-3 in the data sheet). You are enabling this interrupt, which will get triggered by the PWM, and then have no handler, so the code will hang...

Best Wishes
Kova



Joined: 06 May 2007
Posts: 35

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 8:44 am     Reply with quote

Ttelmah wrote:
Get rid of the enable for INT_EXT.


Without the INT_EXT tag the program no execute the INT_RA handle :( (the led connected to GP5 doesn't flash when I push the switch connected to GP0)

This is the code:

Code:

#include <12F683.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPUT                      //Power Up Timer
#FUSES BROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#byte INTCON = 0x8B

#int_ra
void ioc_isr(void)
{
output_high(PIN_A5);
}


void main()
{
set_tris_a(1);
clear_interrupt(INT_RA);

// Then enable the interrupts.
enable_interrupts(INT_RA0);
   
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,55,1);

setup_ccp1(CCP_PWM);
setup_comparator(NC_NC);
setup_vref(FALSE);

setup_timer_2(T2_DIV_BY_1,55,1);
set_pwm1_duty(27);

while(1)
  {
   }
}


Thanks for the help ;)
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 9:17 am     Reply with quote

You removed two instead of one line. restore the line
Code:
enable_interrupts(GLOBAL);

'Global' is not an interrupt by itself but more like a master switch, this single identifier disables or enables all selected interrupts.
Kova



Joined: 06 May 2007
Posts: 35

View user's profile Send private message

PostPosted: Mon Sep 03, 2007 10:00 am     Reply with quote

ckielstra wrote:
'Global' is not an interrupt by itself but more like a master switch, this single identifier disables or enables all selected interrupts.


It works perfectly.
Thanks a lot ;)
Kova



Joined: 06 May 2007
Posts: 35

View user's profile Send private message

PostPosted: Tue Sep 04, 2007 1:31 am     Reply with quote

Kova wrote:
It works perfectly.
Thanks a lot ;)


This is my code.
The program change the frequency of PWM (duty is always 50%) only when the switch (GP0) goes on (VCC) . A led connected to GP5 invert its state when the switch is HIGH

Code:

#include <12F683.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPUT                      //Power Up Timer
#FUSES BROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#byte INTCON = 0x8B

int ct=1;

#int_ra
void ioc_isr(void)
{
delay_ms(10); //Debounce
if (input(PIN_A0)
{
  switch(ct)
   {
   case 0x00: //36Khz
      {
         setup_timer_2(T2_DIV_BY_1,55,1);
         set_pwm1_duty(27);
         ct=1;
         break;
      }
   case 0x01: //38Khz
      {
         setup_timer_2(T2_DIV_BY_1,52,1);
         set_pwm1_duty(26);
         ct=2;
         break;
      }
   case 0x02: //40Khz
      {
         setup_timer_2(T2_DIV_BY_1,49,1);
         set_pwm1_duty(24);
         ct=0;
         break;
      }
   }
   output_toggle(PIN_A5); //Invert led
}
}

void main()
{
setup_oscillator(OSC_8MHZ); //Without this line the program doesnt works correctly (?)
set_tris_a(1); //Switch on GP0
clear_interrupt(INT_RA);

// Then enable the interrupts.
enable_interrupts(INT_RA0);
enable_interrupts(GLOBAL);
   
//36Khz
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,55,1);

setup_ccp1(CCP_PWM);
setup_comparator(NC_NC);
setup_vref(FALSE);

setup_timer_2(T2_DIV_BY_1,55,1);
set_pwm1_duty(27);

while(1)
{
}

}
gg
Guest







PostPosted: Tue Sep 04, 2007 10:19 pm     Reply with quote

When using other pins for INT such as RA4, what register do I look in to see if it is a rising or failling edge interrupt?
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