I have a strange behaviour in a part of my code:
I have defined a union which I use:
Code: Select all
union manflg{
struct {
unsigned reg : 16;
};
struct {
unsigned ud1 : 1;
unsigned macu : 2; // macu Mando calculo
unsigned ud2 : 11;
unsigned tambor : 2;
};
struct {
unsigned isactive : 1; //LSB
unsigned fullrange : 1;// if 1 then 0 - 5V range
unsigned inverted : 1; // if 1 then left is full
unsigned remote : 1; // is remote controlled at the moment
unsigned inparo : 1; // if 1 then Mando is in Paro --> relacionado a sus config!!
unsigned b5 : 1;
unsigned b6 : 1;
unsigned b7 : 1;
unsigned b8 : 1;
unsigned b9 : 1;
unsigned b10 : 1;
unsigned b11 : 1;
unsigned b12 : 1;
unsigned b13 : 1;
unsigned tambitL : 1;
unsigned tambitH : 1;
};
};
union manflg MANDO12345FLG;
union manflg MANDOFLG[5];
Code: Select all
if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
MANDOFLG[i].isactive = fsdata[ADR_mando_active]; // after asigning here..
}else{ //...cant resolve this else statement
errorocurred = 1;
}
that still works (i can see in the watch window) but when i am debugging it does not keep going on the else statement. it stops there or to be precise it does not resolve it. it is not frozen(not crashed) because i can pause the debugger with F6 and restart from there but it cant resolve the else statement.
what makes the whole thing really interesting is if i have this statement it works:
Code: Select all
if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
MANDO12345FLG.isactive = fsdata[ADR_mando_active];
}else{ //this one works fine
errorocurred = 1;
}
Code: Select all
if(Dv_bol(fsdata[ADR_fullrecorido]) == 1) {
MANDOFLG[i].fullrange = fsdata[ADR_fullrecorido];
}else{ //and also here we have no problem
errorocurred = 1;
}
Code: Select all
MANDOFLG[i].reg = MANDO12345FLG.reg;
here is the complete section of code but it really is just as i pointed out above that only on this one line it cant resolve
Code: Select all
for(i = 0; i < 5; i++){
errorocurred = 0;
FLASH_Read(MEM_page_config_Mando + (i * 128), flashdata, 128);//FLASH_Read(172032 + (i * 256), flashdata, 128);
for(j = 0;j < 128; j++){
fsdata[2 * j] = Lo(flashdata[j]); // & 0x00FF;
fsdata[2 * j + 1] = Hi(flashdata[j]); // >> 8) & 0x00FF;
}
if(Dv_mima(fsdata[ADR_virarvalue], cVirarminval, cVirarmaxval) == 1){
Mando_var[i].virarvalue = fsdata[ADR_virarvalue];
}else{
errorocurred = 1;
}
if(Dv_mima(fsdata[ADR_desvirarvalue], cDesvirarminval, cDesvirarmaxval) == 1){
Mando_var[i].desvirarvalue = fsdata[ADR_desvirarvalue];
}else{
errorocurred = 1;
}
if(Dv_mima(fsdata[ADR_largarvalue], cLargarminval, cLargarmaxval) == 1){
Mando_var[i].largarvalue = fsdata[ADR_largarvalue];
}else{
errorocurred = 1;
}
if(Dv_mima(fsdata[ADR_margenvalue], cMargenminval, cMargenmaxval) == 1){
Mando_var[i].margenvalue = fsdata[ADR_margenvalue];
}else{
errorocurred = 1;
}
if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
MANDOFLG[i].isactive = fsdata[ADR_mando_active]; //after this line...
}else{ // the debugger stucks here
errorocurred = 1;
}
if(Dv_bol(fsdata[ADR_fullrecorido]) == 1) {
MANDOFLG[i].fullrange = fsdata[ADR_fullrecorido];
}else{
errorocurred = 1;
}
if(Dv_bol(fsdata[ADR_direccion]) == 1) {
MANDOFLG[i].inverted = !fsdata[ADR_direccion];
}else{
errorocurred = 1;
}
if(Dv_bol(fsdata[ADR_remote]) == 1) {
MANDOFLG[i].remote = fsdata[ADR_remote];
}else{
errorocurred = 1;
}
if(errorocurred == 1) {
MANDOFLG[i].isactive = 0;
errhandler(cMandoerror, i);
}
}
but i really would like to understand where the problem is in the above.
has anyone else had a problem like that before?
I am using workstation 7 with a PIC 24EP512GU810
it is not a problem of the debugger because if i program it in release mode i get the same results in the way that the chip does no longer respond if i leave this section but works fine if i comment it out.
Dieter
I reduced the whole thing down and made a complete project if somebody likes to give it a try. There might still some comments floating around in there but well, I am posting it here:
Code: Select all
// my sign ±±±
//#include <p24EP512GU810.h>
//#include "C:\Users\Tecnico\MPLABXProjects\PIC24EP512GU810_Test.X\p24EP512GU810.h"
//****************************PROTOTYPES*********************
void INIT();
void Mandos_init();
void myclrwdt(void);
unsigned char Dv_mima(unsigned int int_data, unsigned int minval, unsigned int maxval);
unsigned char Dv_bol(unsigned char bol_data);
//*******************END OF PROTOTYPE DECLARATIONS***************************
union {
struct {
unsigned loopexit : 4; //LSB
unsigned : 1;
unsigned state : 3; //test,active, compc
};
struct {
unsigned rs232rx : 1; //LSB
unsigned rs232tx : 1;
unsigned temporizador : 1; // The Flag which indicates to send data to PC
unsigned button : 1;
unsigned H_L : 1; //if ADC_POWER is High or Low set--> Digitalñ setting on chckwakeup
unsigned Tam1_TMR_on : 1;
unsigned Tam2_TMR_on : 1;
unsigned Tam3_TMR_on : 1; //MSB
};
} ISRFLG;
union manflg{
struct {
unsigned reg : 16;
};
struct {
unsigned ud1 : 1;
unsigned macu : 2; // macu Mando calculo
unsigned ud2 : 11;
unsigned tambor : 2;
};
struct {
unsigned isactive : 1; //LSB
unsigned fullrange : 1;// if 1 then 0 - 5V range
unsigned inverted : 1; // if 1 then left is full
unsigned remote : 1; // is remote controlled at the moment
unsigned inparo : 1; // if 1 then Mando is in Paro --> relacionado a sus config!!
unsigned b5 : 1;
unsigned b6 : 1; //LSB
unsigned b7 : 1;
unsigned b8 : 1;
unsigned b9 : 1; //if PC_bit == 0 PVG
unsigned b10 : 1; // if PC_bit == 1 Convertidor
unsigned b11 : 1;
unsigned b12 : 1;
unsigned b13 : 1;
unsigned tambitL : 1;
unsigned tambitH : 1;
};
};
union manflg MANDO12345FLG;
union manflg MANDOFLG[5];
unsigned char fsdata[256];
unsigned char i = 0;
#define ADR_mando_active 0x03 // el mando no es activable(like not installed) and therefore not visible on startup 0 = not installed
#define ADR_remote 0x04 // 0 = no es possible remote, 1 = es posible de remote control
#define ADR_direccion 0x05 // 0 es normal, 1 es invertido
#define ADR_fullrecorido 0x10 // cuando lanzando el mando es en modo de completo uso para lanzar
// //****************Registerbits- Interrupts************************************
#define TMR1IF IFS0.T1IF
#define TMR1_on T1CONbits.TON
#define TMR1IE IEC0bits.T1IE
#define GIE INTCON2.GIE
#define TMR1OF_constant 0x0E0E
#define ISRtestled LATFbits.LATF5 //ISR Testled(blinking on ISR TMR 1 OFx5
#include "built_in.h"
void main() {
INIT();
while(1){
if(ISRFLG.button){
ISRFLG.button = 0;
Mandos_init();
}
}
}
void TMR1isr() iv IVT_ADDR_T1INTERRUPT ics ICS_AUTO {
static unsigned char TMR1cnt = 0; //Tmr1 OF every 200ms at the moment
TMR1IF = 0;
TMR1cnt++;
ISRFLG.temporizador = 1;
if(TMR1cnt == 40){
TMR1cnt = 0;
ISRtestled = !ISRtestled;
}
}
void IOCisr() iv IVT_ADDR_CNINTERRUPT ics ICS_AUTO {
IFS1bits.CNIF = 0;
ISRFLG.button = 1;
}
void INIT(void){
unsigned int db1 = 0;
PLLFBD = 38; // M = 65
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2
OSCTUN = 0; //Fin = 7.37MHz
db1 = OSCCONbits.COSC;
while (OSCCONbits.LOCK != 1);
//*************************Analog & TRIS *******************************
ANSELA = 0x0000;
ANSELB = 0x023F; //RB0;RB4;RB5,RB9 analog
ANSELC = 0x0000;
ANSELD = 0x0000;
ANSELE = 0x0100;
ANSELG = 0x0000;
//**************and then input output...************************************
//*********see the Excel for Details***************************
TRISA = 0x0008; //Ra3 = button
TRISB = 0x023F; //RB0 & RB2 analog--> for the debugging Board and therefore input
TRISC = 0x0000;
TRISD = 0x0008;
TRISE = 0x0100;
TRISF = 0x0100;
TRISG = 0x0000;
LATA = 0x0000;
LATB = 0x0000;
LATC = 0x0000;
LATD = 0x0000;
LATE = 0x0000;
LATF = 0x0000;
LATG = 0x0000;
CNPDA = 0x0000;
CNPDB = 0x0000;
CNPDC = 0x0000;
CNPDD = 0x0000;
CNPDE = 0x0000;
CNPDF = 0x0000;
CNPDG = 0x0000;
CNPUA = 0x0000;
CNPUB = 0x0000;
CNPUC = 0x0000;
CNPUD = 0x0000;
CNPUE = 0x0000;
CNPUF = 0x0000;
CNPUG = 0x0000;
//*******************Interrupt on Change**********************
// we try first with RA3-----------------
CNENAbits.CNIEA3 = 1;
IEC1bits.CNIE = 1;
IFS1bits.CNIF = 0;
//*******************configure the Peripheral Pin Select registers here depending on the need **************************
Unlock_IOLOCK();
// *******************************PPS_Mapping UART1**********************
// Rx1 to RD3 that is because WS7 has this distribution
// Tx1 to RD1
RPOR0bits.RP65R = 1; // this command sets RP65--(RD1) to UART1 Tx
RPINR18bits.U1RXR = 67;
// ****************************** PPS_Mapping SPI1***************************
Lock_IOLock();
//****************** TIMER 1 **************************
T1CONbits.TON = 0; // Disable Timer
T1CONbits.TCS = 0; // Select internal instruction cycle clock
T1CONbits.TGATE = 0; // Disable Gated Timer mode
T1CONbits.TCKPS = 3; //0b011; // Select 1:256 Prescaler
TMR1 = 0x00; // Clear timer register
PR1 = TMR1OF_constant; //9; // Load the period value
IPC0bits.T1IP = 0x01; // Set Timer 1 Interrupt Priority Level
IFS0bits.T1IF = 0; // Clear Timer 1 Interrupt Flag
IEC0bits.T1IE = 1; // Enable Timer1 interrupt
T1CONbits.TON = 1; // Start Timer
}
void Mandos_init(){
unsigned char i = 0;
//unsigned char j = 0;
// bit errorocurred;
unsigned char errorocurred;
for(i = 0; i < 5; i++){
fsdata[ADR_mando_active] = 1;
if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
MANDO12345FLG.isactive = fsdata[ADR_mando_active]; //
MANDOFLG[i].isactive = MANDO12345FLG.isactive; //
MANDOFLG[i].isactive = fsdata[ADR_mando_active]; //asigns wrong values and does not work afterwards correctly
}else{ // and keeps stucking here
errorocurred = 1;
}
}
}
unsigned char Dv_bol(unsigned char bol_data){
if(bol_data > 1){
return 0; //datavalidation failed
}else{
return 1; //datavalidation was good
}
}
unsigned char Dv_mima(unsigned int int_data, unsigned int minval, unsigned int maxval){
if((int_data < minval) || (int_data > maxval)){
return 0; //datavalidation failed
}else{
return 1; //datavalidation was good
}
}
void myclrwdt(void){
asm{clrwdt}
}
Dieter