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

[INTERRUPTS] int_ext, int_ext1, int_ext2

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



Joined: 02 Jun 2006
Posts: 6

View user's profile Send private message

[INTERRUPTS] int_ext, int_ext1, int_ext2
PostPosted: Fri Jun 02, 2006 10:20 am     Reply with quote

Hello everyone !

I'm programming a PIC18F2520 and I would like to use external interrupts on pinB0, pinB1 and pinB2.

This is my program for now :

----------------------

//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// INITIALISATION ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////



#include <18F2520.h>
#device adc=8

#include <string.h>
#include <stdlib.h>
#include <stdio.h>


#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOIESO //Internal External Switch Over mode enabled
#FUSES NOFCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOLPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=20000000) // Fréquence du Quartz

#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=WiFi) //UART PIC à WiFi

#bit INTF_BIT = 0x0B.1



/*************************************************************************
* END INITIALISATION *
*************************************************************************/


//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// Prototypage ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////

init();

/*************************************************************************
* END Prototypage *
*************************************************************************/



//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// VAR GLOBALES ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////

char trame_RFID[20]=""; //Récupération ID en provenance du module RFID
char ID [20]=""; //Identifiant PREsensiA recherché --> psia-pw-fc-
char IDWiFi[5]=""; //Partie tronquée de la trame RFID --> seulement les 4 derniers caractères
char n_video[7]="";
char n_video1[9]="";
char n_video2[9]="";
char temp_TTL; //Buffer trame RS232

int i =0; //Variable utilisée dans les boucles for
int single_send = 0; //Variable utilisée afin de s'assurer que l'on envoie une seule et unique fois l'identifiant du flacon de parfum


/*************************************************************************
* END VAR GLOBALES *
*************************************************************************/

env_num()
{


strcpy(n_video,"13:0:0");
printf("%s",n_video);

//fputs(n_video,WiFi);
//printf("13:0:0");
//fprintf(WiFi,n_video);

}

env_num1()
{


strcpy(n_video1,"2556:0:0");
printf("%s",n_video1);

//fputs(n_video,WiFi);
//printf("13:0:0");
//fprintf(WiFi,n_video);

}

env_num2()
{


strcpy(n_video2,"6662:0:0");
printf("%s",n_video2);

//fputs(n_video,WiFi);
//printf("13:0:0");
//fprintf(WiFi,n_video);

}
//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// LCD ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////

//Nothing this time

/*************************************************************************
* END LCD *
*************************************************************************/


#int_EXT
EXT_isr()
{

disable_interrupts(GLOBAL);

output_bit(PIN_C0,1);
env_num();
delay_ms(500);
output_bit(PIN_C0,0);
clear_interrupt(int_ext);

enable_interrupts(GLOBAL);

reset_cpu();

}

#int_EXT1
EXT1_isr()
{

disable_interrupts(GLOBAL);

output_bit(PIN_C1,1);
env_num1();
delay_ms(500);
output_bit(PIN_C2,0);
clear_interrupt(int_ext1);

enable_interrupts(GLOBAL);

reset_cpu();


}

#int_EXT2
EXT2_isr()
{

disable_interrupts(GLOBAL);

output_bit(PIN_C2,1);
env_num2();
delay_ms(500);
output_bit(PIN_C2,0);
clear_interrupt(int_ext2);

enable_interrupts(GLOBAL);

reset_cpu();

}

//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// ID WiFi ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////

//Nothing this time

/*************************************************************************
* END ID WiFi *
*************************************************************************/




//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// Trame RFID ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////

// Nothing this time

/*************************************************************************
* END Trame RFID *
*************************************************************************/


//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// INIT ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////



/*************************************************************************
* END Init *
*************************************************************************/



//////////////////////////////////////////////////////////////////////////
/////// ///////
/////// MAIN ///////
/////// ///////
//////////////////////////////////////////////////////////////////////////


void main()
{


setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,255,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
setup_oscillator(FALSE);

port_b_pullups(TRUE);

ext_int_edge( H_TO_L );
ext_int_edge(1,H_TO_L );
ext_int_edge(2,H_TO_L );

INTF_BIT = 0;



//Configuration des interruptions

enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT2);


SET_TRIS_A(0x80);
SET_TRIS_B(0xFF);
SET_TRIS_C(0x80);


output_bit(PIN_C0,0);
output_bit(PIN_C1,0);
output_bit(PIN_C2,0);
output_bit(PIN_C3,0);
output_bit(PIN_C4,0);
output_bit(PIN_C5,0);


output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);

output_bit(PIN_A0,0);
output_bit(PIN_A1,0);
output_bit(PIN_A2,0);
output_bit(PIN_A3,0);
output_bit(PIN_A4,0);
output_bit(PIN_A5,0);


while(true)
{


}//end while


}



/*************************************************************************
* END MAIN *
*************************************************************************/


The problem I'm facing is the following: I thought that int_ext, int_ext1 and int_ext2 were respectively associated with B0, B1 and B2. I'm using three buttons to set a low level on pins. When I'm using only int_ext with on button connected to B0 it's working perfectly. However, when I'm using two or three buttons, it's like the PIC doesn't know which pin enabled the interrupt.
I would like to do this :
:: When I press the button connected to B0, it sends a specific string
:: When I press the button connected to B1, it sends a different string
:: When I press the button connected to B2, it sends another string
Quite simple in fact but I'm experiencing problems using the different interrupts.

Sorry if my english is not so well. I've tried to do my best !

Thanks to all.
ckielstra



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

View user's profile Send private message

PostPosted: Fri Jun 02, 2006 11:32 am     Reply with quote

You have a very _unusual _ way of using the interrupts...
Normally interrupts are used to execute a routine that happens many times a second and must be handled as fast as possible. You are using the interrupts to handle a situation that will very rarely happen. Very unusual, but none-the-less it should work.

I haven't spotted the obstructing error in your code but here are some other remarks:

- When posting code to this forum please use the 'Code' button. This will help to preserve the layout of your program and makes it easier for us to read your program.
- Always mention the compiler version. Maybe it is a known compiler error and we can try to test with the same version.

Quote:
#FUSES NOPBADEN //PORTB pins are configured as analog input channels on RESET
In my fuses.txt the explanation of this fuse is different:
Quote:
NOPBADEN PORTB pins are configured as digital I/O on RESET


Code:
#bit INTF_BIT = 0x0B.1
What is this line doing here? It is a register definition for a PIC16 processor but in the PIC18 it is just pointing to RAM.

Code:
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=WiFi) //UART PIC à WiFi
Add the ERRORS directive, this will prevent the hardware UART from halting on receive buffer overflow.

Code:
#int_EXT1
EXT1_isr()
{
disable_interrupts(GLOBAL);    // This line does nothing. On entering an interrupt handler the interrupts are disabled by hardware already.

output_bit(PIN_C1,1);
env_num1();
delay_ms(500);
output_bit(PIN_C2,0);       // I guess you meant PIN_C1 ??
clear_interrupt(int_ext1);  // Not required, the compiler also adds code for clearing the interrupt.

enable_interrupts(GLOBAL);  // See the note above on disabling interrupts

reset_cpu();     // This is extremely unusual. Often a bad program design.
}


Code:
 SET_TRIS_A(0x80);
SET_TRIS_B(0xFF);   Here you define all pins as input
SET_TRIS_C(0x80);


output_bit(PIN_C0,0);
output_bit(PIN_C1,0);
output_bit(PIN_C2,0);
output_bit(PIN_C3,0);
output_bit(PIN_C4,0);
output_bit(PIN_C5,0);


output_bit(PIN_B4,0);  // Port B pins were defined as inputs before
output_bit(PIN_B5,0);  //
output_bit(PIN_B6,0);  //
output_bit(PIN_B7,0);  //

output_bit(PIN_A0,0);
output_bit(PIN_A1,0);
output_bit(PIN_A2,0);
output_bit(PIN_A3,0);
output_bit(PIN_A4,0);
output_bit(PIN_A5,0);
The compiler will add code for setting the TRIS register on each I/O-operation so you don't have to do it also. Or, you can save some code space by defining the TRIS registers like you do, but then you need to add the #use fast_IO at the top of your program. Also check you settings of the TRIS registers as they don't map to your output commands.
AcquaVx



Joined: 02 Jun 2006
Posts: 6

View user's profile Send private message

PostPosted: Fri Jun 02, 2006 12:12 pm     Reply with quote

Ok, thanks for the remarks. Some of them weren't supposed to be there like set_tris_b(0xFF) or #bit INTF_BIT = 0x0B.1. I was just testing something with the first one and regarding the second one I copy/paste it from this forum. My mistake it wasn't for the right microcontroller. Nevertheless, thanks for the other remarks because I thought I was right to disable all interrupts for example and I didn't know the compiler was doing it itself. It will help me.


You're saying that using interrupts the way I do it is strange. I can understand that. Can I do it differently ? Because all I want to do here is to send a string to another equipment when a button is pressed. I'm using more than one button and I thought using external interrupt and int_ext was not a bad idea because using the pull-up resistors it's quite easy to trigger an interruption connecting the right pin to ground.

Thank you for your answer.
Ttelmah
Guest







PostPosted: Fri Jun 02, 2006 2:43 pm     Reply with quote

The thing that may well cause problems, is enabling the interrupt inside the handler. This is an absolute 'no no' on the PIC. First, you don't have to disable the interrupts in the handler,the hardware allready does this for you, but if an interrupt event on any source, has occured from the start of the handler, and you enable the interrupts inside the handler, the code will immediately jump back into the global interrupt handler, with the stack now having an extra value in place, and destroy the contents of the buffers used to save the needed registers. This will lead to an eventual stack overflow, and things will not behave as expected.
Using reset_cpu, is a really awful way of working, and I am not suprised it doesn't work as expected. The code is a bit like the driver who stops his car, by driving into a wall repeatedly, and is then suprised that things like the lights don't work...

Best Wishes
AcquaVx



Joined: 02 Jun 2006
Posts: 6

View user's profile Send private message

PostPosted: Mon Jun 05, 2006 4:14 am     Reply with quote

Thanks for the reply.
Regarding the reset_cpu() I was following someone's advice but you're totally right, it awful. I'll try rigth away the advice you gave me.
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