Actualización 1
el problema desapareció cuando cambié la forma de cambiar de contexto durante la interrupción de srs a soft
#pragma interrupt InterruptHandler ipl1srs vector 0
a
#pragma interrupt InterruptHandler ipl1soft vector 0
Es algo relacionado con la corrupción del conjunto de registro sombra, que no entiendo por qué?
Cualquier sugerencia sobre el conjunto de registro sombra y su corrupción se apreciarán.
Pregunta original
El siguiente código es para el programa (aún no completado) que hace un cronómetro con interrupciones en la pantalla multiplexada de 4 dígitos y 7 segmentos.
El comportamiento inesperado: el parámetro n
en delay
se vuelve más grande que el valor pasado ( 100
) aunque decremento y se atasca dentro del bucle.
Realmente no puedo pensar en nada en la tierra que lo haga posible mientras uso las interrupciones.
IDE utilizado: MPLAB X v4.01 Compilador usado: XC32 v1.44
// PIC32MX320F128H Configuration Bit Settings
// 'C' source line config statements
// DEVCFG3
// USERID = No Setting
// DEVCFG2
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier (24x Multiplier)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)
// DEVCFG1
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_8 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <plib.h>
#define A BIT_0
#define B BIT_1
#define C BIT_3
#define D BIT_6
#define E BIT_5
#define F BIT_2
#define G BIT_4
#define ZERO A|B|C|D|E|F
#define ONE B|C
#define TWO A|B|G|E|D
#define THREE A|B|C|D|G
#define FOUR B|C|F|G
#define FIVE A|C|D|F|G
#define SIX A|C|D|E|F|G
#define SEVEN A|B|C
#define EIGHT A|B|C|D|E|F|G
#define NINE A|B|C|D|F|G
#define DIGIT_0 BIT_0
#define DIGIT_1 BIT_1
volatile unsigned short counter = 0;
#pragma interrupt InterruptHandler ipl1srs vector 0
void InterruptHandler(void) {
if (mT1GetIntFlag()) {
counter= (counter+1)%10;
mT1ClearIntFlag();
}
}
void delay(unsigned int n ) {
for(;n>0;n--)
{
int j = 0;
while (j < 1000) {
j++;
}
}
}
int outputnumber(unsigned short n,unsigned short digit) {
mPORTDWrite(digit);
if (n > 9)
return -1;
switch (n) {
case 0:
mPORTEWrite(ZERO);
break;
case 1:
mPORTEWrite(ONE);
break;
case 2:
mPORTEWrite(TWO);
break;
case 3:
mPORTEWrite(THREE);
break;
case 4:
mPORTEWrite(FOUR);
break;
case 5:
mPORTEWrite(FIVE);
break;
case 6:
mPORTEWrite(SIX);
break;
case 7:
mPORTEWrite(SEVEN);
break;
case 8:
mPORTEWrite(EIGHT);
break;
case 9:
mPORTEWrite(NINE);
break;
}
return 0;
}
int main(void) {
mPORTFSetPinsDigitalOut(0xFF);
mPORTESetPinsDigitalOut(0x7F);
mPORTDSetPinsDigitalOut(BIT_0 | BIT_1);
OpenTimer1(T1_ON | T1_PS_1_256, 0x9897);
INTEnableSystemSingleVectoredInt();
mT1SetIntPriority(1);
mT1IntEnable(1);
while (1) {
outputnumber(counter,DIGIT_0);
mPORTFToggleBits(0xFF);
delay(100);
}
return 0;
}