![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
rvalor
Joined: 16 Apr 2009 Posts: 18 Location: Spain
|
Problem with a parameter in a function call... |
Posted: Wed Nov 17, 2010 3:48 am |
|
|
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 !!! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Nov 17, 2010 4:38 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
rvalor
Joined: 16 Apr 2009 Posts: 18 Location: Spain
|
|
Posted: Wed Nov 17, 2010 5:08 am |
|
|
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... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Nov 17, 2010 5:34 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|