|
|
View previous topic :: View next topic |
Author |
Message |
_olaf_
Joined: 24 Feb 2005 Posts: 32
|
RB-Interrupt problem when occuring the second time |
Posted: Tue Feb 28, 2006 1:11 am |
|
|
Hi,
I have a small problem with my program. In this program I want to switch different voltages on. With the RB_Interrupts I want to check if everything is working correct.
When the program starts from a power-on reset everything is ok. The initialisation is working and the outputs are set. If I make an interrupt on the RB-Ports (e.g. RB4) then the controller goes into the RB_ISR(). After that the controller goes to the next sleep operation but does not wake up again when an RB-Interrupt occurs. I can do what I want, but there is no possibility to wake it up. Does somebody have an idea where the problem could be.
MPLAB V7.30
Compiler PCM 3.223
Olaf
Code description
In the
RB_isr(char i) {} -> I get the portnumber of the RB-Interrupt and printout a corresponding errormessage.
Initialisierung() -> makes the initilisation of the PIC
Fehlermeldung(int e) -> print out an errormessage
Power_On_PIC() -> check the voltage of the PIC (Voltage regulator has a errorflag which is set at voltages below 5V, used PIC is 16LF84)
Power_On_Wandler() -> switching on the other voltages
Code:
#include "CCD_SPG1.h"
#int_RB
int EF[6]; // ERRORFLAGS
// declare functions
void Initialisierung(void);
void Fehlermeldung(int e);
void Power_On_PIC(void);
void Wait(unsigned int t);
void RB_isr(char i);
//PORT_B Interrupt Service Routine
RB_isr(char i)
{
unsigned int statusregister;
// statusregister=_STATUS;
DISABLE_Interrupts(INT_RB);
i=0xFF;
i=0x00;
i=INPUT_B();
switch (i) {
Case 0x10: OUTPUT_B(0x00);
Fehlermeldung(2);
break;
Case 0x20: OUTPUT_B(0x01);
Fehlermeldung(5);
break;
Case 0x40: OUTPUT_B(0x01);
Fehlermeldung(4);
break;
Case 0x80: OUTPUT_B(0x01);
Fehlermeldung(5);
break;
}
ENABLE_Interrupts(GLOBAL);
CLEAR_Interrupt(INT_RB);
ENABLE_Interrupts(INT_RB);
}
// initialise Controller
Initialisierung()
{
DISABLE_Interrupts(INT_RB); // PORT-B Interrupts disable
DISABLE_Interrupts(INT_EXT); // Externer Interrupt disable
DISABLE_Interrupts(GLOBAL); // globel Interrupt disable
OUTPUT_A(0x00); // Testsequence switching LED on/off
OUTPUT_A(0b00110); //
delay_ms(500); //
OUTPUT_A(0b00000);
delay_ms(500);
OUTPUT_A(0b00110);
delay_ms(500);
OUTPUT_A(0b00000);
OUTPUT_B(0x00); // End Testsequence
SET_TRIS_A(0x11); // Configure I/O
SET_TRIS_B(0xF0);
EF[0]=0; // preset errorflags
EF[1]=0;
EF[2]=0;
EF[3]=0;
EF[4]=0;
EF[5]=0;
}
// output Errormessages
Fehlermeldung(int e)
{
switch (e) {
Case 1: printf("Something\n");
break;
Case 2: printf("Something\n");
break;
Case 3: printf("Something\n");
break;
Case 4: printf("Something\n");
break;
Case 5: printf("Something\n");
break;
Case 6: printf("Something\n");
break;
}
printf("Something\n");
}
Wait(unsigned int t)
{
Delay_ms(t);
}
// Check Voltage for UB PIC
Power_On_PIC()
{
int i, j, k, l;
DISABLE_INTERRUPTS(INT_RB); // PORT-B Interrupts disable
Check_UB_PIC: // label for testloop
if ( (Input(ERROR_UB_PIC)) && (EF[0]<=5) ) // check UB-PIC
{
Wait(100); // wait 100ms
EF[0]++; // increment ERROR-Flag
if (EF[0]==5)
{
Write_EEPROM(0, EF[0]);// write value to eeprom
Fehlermeldung(1); // test for 5 times. more then 5 times false -> exit
goto Power_Off;
}
goto Check_UB_PIC;
}
else
{
EF[0]==0;
printf("everything o.k.");
}
Power_Off:
ENABLE_Interrupts(GLOBAL);
ENABLE_INTERRUPTS(INT_RB);
}
//Ausgangsspannungen einschalten
Power_On_Wandler()
{
DISABLE_INTERRUPTS(INT_RB);
if (EF[0]==0) //pr�fen ob UB_PIC ok
{
Output_Bit(CCD_Power_On, 0); // switch on voltage
Output_Bit(SHTDN_5V_POS, 0); // switch on voltage
}
Check_UB_5V: // label for testloop
if ( (Input(ERROR_5V_Pos)) && (EF[1]<=5) ) // check voltage
{
Wait(100); // Warte 100ms
EF[1]++; // increment ERROR-Flag
if (EF[1]==5) // test for 5 times. more then 5 times false -> exit
{
Write_EEPROM(1, EF[1]); // write value to eeprom
Output_Bit(SHTDN_5V_POS, 1); // switch voltage off
Fehlermeldung(2); // test for 5 times. more then 5 times false -> exit
goto Power_Off;
}
goto Check_UB_5V; // next try
}
else
{
EF[0]==0;
Output_Bit(SHTDN_5V_POS,0);
printf("something");
}
Power_Off:
ENABLE_Interrupts(GLOBAL);
ENABLE_INTERRUPTS(INT_RB);
}
void main() {
int x;
Initialisierung();
ENABLE_Interrupts(GLOBAL);
Power_On_PIC();
Power_On_Wandler();
loop:
sleep();
x=INPUT_B();
if (INT_RB!=1)
{
RB_ISR(x);
}
goto loop;
}
*.h-file:
#include <16LF84A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,PUT
#define ERROR_UB_PIC 40
#define POS_UB_OK 41
#define NEG_UB_OK 42
#define SHTDN_5V_POS 48
#define SHTDN_15V_POS 49
#define CCD_POWER_ON 50
#define SHTDN_7V_NEG 51
#define ERROR_5V_POS 52
#define ERROR_15V_POS 53
#define UB_15V_NEG_OK 54
#define UB_15V_POS_OK 55
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A4) |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 28, 2006 4:26 am |
|
|
Do _not_ enable the global interrupt inside the ISR. This is a 'no no' on the PIC.
You don't need to disable interrupts either.
Basically,when an interrupt occurs, the _hardware_ disables the global interrupt flag. This flag is automatically re-enabled, on the return from the global interrupt handler, _when the instruction completes_.
This prevents interrupts interrupting themselves, and prevents recursive calls to the handler routines (which the chip does not support, having no software stack).
Now if you re-enable the global interrupt flag, inside the interrupt handler, you have killed this protection, and an interrupt can now occur inside the interrupt handler. This will destroy the contents of the registers, and result in values being destroyed.
Best Wishes |
|
|
_olaf_
Joined: 24 Feb 2005 Posts: 32
|
|
Posted: Wed Mar 01, 2006 1:17 am |
|
|
Hi,
I tried it with deleting the Code for disabling the interrupts. But it was the same effect. When I debug the program in single step mode, something strange happens.
When I come to
if (INT_RB!=1)
{
RB_ISR(x);
}
in main, the TRISB is changed to 0xFF (all input)
when I continue stepping through the program in the RB_isr at the case command
RB_ISR()
{
...
switch (i) {
Case 0x10: OUTPUT_B(0x00);
Fehlermeldung(2);
break;
Case 0x20: OUTPUT_B(0x01);
Fehlermeldung(5);
break;
....
}
the TRISB is changed to 0x00 (all output)
So it's clear that the controller doesn't react at the second PortB-Change. But what is the reason for this? Another problem is the following. I have an updatet version (Version 3.232) of the Compiler. If I want to compile it with this Version I get the message that the RB_ISR()-description has changed and it generates an error.
Any idea what's the problem with this?
Olaf |
|
|
_olaf_
Joined: 24 Feb 2005 Posts: 32
|
|
Posted: Thu Mar 02, 2006 2:29 am |
|
|
I checked the program with the updated compiler verison (3.232) but it is still the same behaviour. When I go into the RB_ISR() the TRISB is changed and so the RB_ISR can not react on a PortB-Change. I searched in the datasheet of the controller and the examples here in the newsgroup, but I didn't find something about this problem. Does anybody have a explanation for this?
Olaf |
|
|
mpfj
Joined: 09 Sep 2003 Posts: 95 Location: UK
|
Re: RB-Interrupt problem when occuring the second time |
Posted: Thu Mar 02, 2006 5:17 am |
|
|
(1) You should *not* actually call the rb_isr() routine yourself, as you do in main(). The interrupt handler will do this when you use the #int_rb directive.
(2) I would now the #int_rb directive to just before the isr routine.
(3) Remove the interrupt enable / disable code (as stated by Ttelmah).
(4) Add a "default" clause to your switch() statement.
(5) You cannot pass an variables to an isr, because of item (1).
(6) Are you testing for individual bit changes, or only specific bit combinations of PORTB ? For individual bit changes, you will have to use the bit_test() command.
... e.g. ...
Code: |
//PORT_B Interrupt Service Routine
#int_RB
void rb_isr(void)
{
unsigned int i;
unsigned int statusregister;
// statusregister=_STATUS;
i=INPUT_B();
switch (i) {
Case 0x10:
OUTPUT_B(0x00);
Fehlermeldung(2);
break;
Case 0x20:
OUTPUT_B(0x01);
Fehlermeldung(5);
break;
Case 0x40:
OUTPUT_B(0x01);
Fehlermeldung(4);
break;
Case 0x80:
OUTPUT_B(0x01);
Fehlermeldung(5);
break;
default:
break;
}
}
|
|
|
|
|
|
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
|