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

Problem with a parameter in a function call...

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



Joined: 16 Apr 2009
Posts: 18
Location: Spain

View user's profile Send private message

Problem with a parameter in a function call...
PostPosted: Wed Nov 17, 2010 3:48 am     Reply with quote

Hello everybody

I've a function that configures the AD. It accepts as a parameter the channel to be converted. This function is called "Convierte_Canal"
Code:

float Convierte_Canal(char cChan);

In the other hand, I accept commands via serial port using an interrupt.

The way I use "Convierte_Canal" is this:
Code:

#define CH_TEMP_PRECISION_01   16   //AN4         
#define CH_BAT                 28   //AN7                     
#define CH_ACEL_YOUT           44   //AN11               
#define CH_ACEL_XOUT           40   //AN10 

Then I use:
Code:

Convierte_Canal(CH_ACEL_YOUT);

This works fine, but sometimes when an interrupt occurs and execution returns to "Convierte_Canal" the cChan parameter has been modified so no conversion is made.

I know the problems derived of using arrays and writing out of bounds but I don't know how to face this problem kind of problem...

The code of "Convierte_Canal" is this:
Code:

float Convierte_Canal(char cCHAN, boolean bRef){

float fMedida = 0.0;
cCHAN_SELECTED = cCHAN;

//Valores iniciales:
WDTCON_ADSHR = 0;     
ADCON0 = 0;
ADCON1 = 0;
WDTCON_ADSHR = 1;     
ANCON0 = 0;         
ANCON1 = 0;
   
//------------------
//  CONFIG CANAL
//------------------
WDTCON_ADSHR = 0;       //Acceso normal...
ADCON0_ADON = 0;         //ADC off 
ADCON1_ADFM = 1;         //Valor con justificación a izquierdas
ADCON1_ADCAL = 0;        //Conversion normal
WDTCON_ADSHR = 1;       //Acceso registros compartidos...
ANCON0 = 159;            //Canales AN0, AN1, AN2, AN3(Vref+), AN4, AN7, AN10 y AN11 configurados como ANALÓGICOS
ANCON1 = 12;
WDTCON_ADSHR = 0;      //Acceso normal...
ADCON0_VCFG1 = 0;        //VSS
ADCON0_VCFG0 = bRef;     //VDD o VRef+     
   
//Seleccion canal:
ADCON0 &= CH_MASK;   //Borrado canal actual...
ADCON0 |= cCHAN;     //Nuevo canal a convertir...
   
delay_us(50);
   
ADCON1_ACQT2=0;
ADCON1_ACQT1=0;    //TIEMPO ADQUISICION --> 0Tad
ADCON1_ACQT0=0;
ADCON1_ADCS2=0;
ADCON1_ADCS1=0;    //OSCILADOR INTERNO CONVERSOR AD...
ADCON1_ADCS0=1;
   
ADCON0_ADON = 1;   //ADC ON

delay_us(50);
   

switch(cCHAN){
   case CH_BAT:
      Inicializa_200();
      fMedida = FD_mideYfiltra(1,200);
      break;

   case CH_ACEL_YOUT:
      fMedida = (float)read_adc(ADC_START_AND_READ);
      break;

   case CH_ACEL_XOUT:
      fMedida = (float)read_adc(ADC_START_AND_READ);
      break;

   case CH_TEMP_PRECISION_01:
      Inicializa_200();      
      fMedida = FD_mideYfiltra(1,200);
      break;

   case CH_TEMP_PRECISION_02:
      Inicializa_200();      
      fMedida = FD_mideYfiltra(1,200);
      break;

   case CH_TEMP_HABITACION:
      Inicializa_300();         
      fMedida = FD_mideYfiltra(0,250);
      break;

   case CH_TEMP_AMBIENTE:
      Inicializa_300();   
      fMedida = FD_mideYfiltra(0,250);
      break;
      default:
   fprintf(DEBUGG,"------------------------------------> Error canal\n\r");      
   }
   
ADCON0_ADON = 0;    //ADC off

return(fMedida);
}

Have anybody faced this problem before??

Thank you very much in advance !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 18376

View user's profile Send private message

PostPosted: Wed Nov 17, 2010 4:38 am     Reply with quote

Seriously, 'think for a moment'. If data is being overwritten by an interrupt routine, then the place to look, is in this....

Almost exactly the same question was asked only a few days ago, and the answer is the same. Look in the .sym file. Find where the variable being located is stored in RAM, and look at what is immediately in front of this. 99% of 'overwriting' problems, are the result of an array in front, growing over the next variable. Commonest causes:
1) Forgetting that arrays in C are zero referenced, and writing to element '20', in a twenty element array.
2) Forgetting that strings need one extra character for the terminating character.

Best Wishes
rvalor



Joined: 16 Apr 2009
Posts: 18
Location: Spain

View user's profile Send private message

PostPosted: Wed Nov 17, 2010 5:08 am     Reply with quote

In a first time I though that was the problem and tried to check this...


But in the .SYM file I see this:

654 get_str.i
655 get_str.@SCRATCH1
656-659 @PRINTF_L32D_82FPFPF.P1
656-659 TERM_CalculaResCanal.fCuentas
656 Convierte_Canal.cCHAN
656 CAL_Calibra_T_AMB.@SCRATCH1
656 get_str.@SCRATCH2

The variable I think is changing is cCHAN, but the variable "TERM_CalculaResCanal.fCuentas" is used after "Convierte_Canal".
"CAL_Calibra_T_AMB is used at the beginning of the execution....

.SYM file isn't helping me....

Perhaps this could be the problem:
656-659 @PRINTF_L32D_82FPFPF.P1

In the interrupt ISR I use several printf in order to show some debug information....

Thank you in advance...
Ttelmah



Joined: 11 Mar 2010
Posts: 18376

View user's profile Send private message

PostPosted: Wed Nov 17, 2010 5:34 am     Reply with quote

Don't use print, in an interrupt.
If you want to print debugging information, use sprintf, put the data into a buffer, and print it once you get out. Printing is _slow_ in computer terms, and though there are occasions to break this, general 'good rule', is always get out of an interrupt ASAP.
Using printf, in the interrupt handler, will imply that the interrupt is disabled for very large lumps of your normal code. Could in itself be causing problems.
However, though the rule about looking at the variable in front covers 99% of cases, there can be others. Think triply carefully about how array indexes are handled in the interrupt, what variables actually are used, etc. etc.. If you are using anything like get_str in the interrupt, Don't.
Interrupt handlers should be _simple_. They should handle the single hardware event that triggered the interrupt, and get out again. Setting flags, storing data, sending data, but just the one character that has been received, or sending the one that is waiting to send. Complexity in an interrupt handler, is your enemy.

Best Wishes
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