Hi everyone,
I need some help to find a bug in my program I just can't find!
I am using an ADuC7026 which has a ARM7TDMI core. For programming I use
GNUARM and the light version of uVision as an emulator/disassembler.
I want to read the values of 9 different ADC channels and store them
into an array.
The essentials of the code:
1 | uint8_t ADCchannel[9] = {11,2,5,0,3,6,1,4,7};
|
2 | uint16_t values[9] = {0,0,0,0,0,0,0,0,0};
|
3 |
|
4 | uint8_t j = 0;
|
5 | for(j=0; j<9; j++)
|
6 | {
|
7 | ADCCON |= ADC_SINGLESOFTWARECONV;
|
8 | ADCCP = ADCchannel[j]; //select channel
|
9 | ADCCON |= ADC_ENABLE; //start conversion
|
10 | while(ADCSTA==0){} //wait for result
|
11 | values[j] = (uint16_t)(ADCDAT >> 16); //store result
|
12 | }
|
13 | //write one result to DAC to test
|
14 | DAC1_SETVAL(values[0]);
|
The error is that the result that should be stored in value[i] is stored
in value[i+1] instead. And what should be value[8] gets value[0]. So
every entry is shifted by one slot.
I found that when I modify my code so that the for-loop will only take
one value of i, eg:
1 | uint8_t ADCchannel[9] = {11,2,5,0,3,6,1,4,7};
|
2 | uint16_t values[9] = {0,0,0,0,0,0,0,0,0};
|
3 |
|
4 | uint8_t j = 0;
|
5 | for(j=0; j<1; j++)
|
6 | {
|
7 | ADCCON |= ADC_SINGLESOFTWARECONV;
|
8 | ADCCP = ADCchannel[j]; //select channel
|
9 | ADCCON |= ADC_ENABLE; //start conversion
|
10 | while(ADCSTA==0){} //wait for result
|
11 | values[j] = (uint16_t)(ADCDAT >> 16); //store result
|
12 | }
|
13 | //write one result to DAC to test
|
14 | DAC1_SETVAL(values[0]);
|
everything will work fine.(However I only get one out of the 9 values,
of course.)
Adding a j--; j++; around the storing command will get the values stored
at the correct location.
1 | uint8_t ADCchannel[9] = {11,2,5,0,3,6,1,4,7};
|
2 | uint16_t values[9] = {0,0,0,0,0,0,0,0,0};
|
3 |
|
4 | uint8_t j = 0;
|
5 | for(j=0; j<9; j++)
|
6 | {
|
7 | ADCCON |= ADC_SINGLESOFTWARECONV;
|
8 | ADCCP = ADCchannel[j]; //select channel
|
9 | j--;
|
10 | ADCCON |= ADC_ENABLE; //start conversion
|
11 | while(ADCSTA==0){} //wait for result
|
12 | values[j] = (uint16_t)(ADCDAT >> 16); //store result
|
13 | j++;
|
14 | }
|
15 | //write one result to DAC to test
|
16 | DAC1_SETVAL(values[6]);
|
When I emulate my code with uVision from KEIL, I don't get the error.
Looking at the disassembly showed however, that the assembler code of
the first 2 shown codes doesn't change but for the value of the one
comparison at the for loop, (As it should be!) which only serves to
confuse me even more, as now it seems that the same code that works in
one case does something else in the other.
It seems as if code that keeps the value of j for some time works fine,
and code that changes j every time doesn't: switching j between 2 values
with a switch will work fine, e.g.
1 | if((GP4DAT & Pin5_Val)!=0) {j=6;}
|
2 | else{j=0;}
|
3 | ADCCON |= ADC_SINGLESOFTWARECONV;
|
4 | ADCCP = ADCchannel[j];
|
5 | ADCCON |= ADC_ENABLE;
|
6 | while(ADCSTA==0){}
|
7 | values[j] = (uint16_t)(ADCDAT >> 16);
|
8 | DAC1_SETVAL(values[6]);
|
I think that I'm just missing something really small and stupid, but I
just cannot find it! It might also be something with the compiler
options, so I included the makefile I use.
Thanks a lot for your help already. I am really lost here :(
I appreciate any form of advice/ideas/hints!
Sorry for the long post...
Greetings
Henrik