Domanda

I'm writing simple code in C for STM32F0 discovery board. I'm generating different waveforms, according to external analog signal.

Declared global arrays with waveforms:

const uint32_t sinus[WAVELENGHTS] = {128,131,134,137,141,...}
const uint32_t square[WAVELENGHTS] = {0,0,0,0,0,0,0,0,0,0,...}

and pointer to array

const uint32_t (*currentWave)[WAVELENGHTS];

That pointer is used in timer irq to generate chosen waveform:

void TIM14_IRQHandler()
{
    ...
    TIM2->CCR1 = (*currentWave)[(mainSynth.DDSAccumulator)>>24];
    TIM14->SR &= ~(TIM_SR_CC1IF);
}

According to external value, in main loop I choose one of waveforms:

while(1) {
...
    if(ADC_values[2] < 2048)
        currentWave = &sinus;
    else
        currentWave = &square;
...
}

Without optimizations, currentWave value changes according to ADC_values[2] change (exactly: to TIM2->CCR1 are written values from good waveform, sinus or square), but enabling any optimization makes code working bad, it means assignment

currentWave = &sinus;

or

currentWave = &square;

never executes, currentWave always have initial value.

I also tried to declare both pointer and arrays as volatile, with no effect.

I need optimization for size to fit code in my device.

Any ideas?

È stato utile?

Soluzione

I'm going to make a wild guess: you tried the volatile this way and it didn't work:

const volatile uint32_t (*currentWave)[WAVELENGHTS];

And that is to be expected, because this declaration makes volatile the uint32_t values of the array, not the pointer. And the pointer is what changes asynchronously.

Try instead:

const uint32_t (* volatile currentWave)[WAVELENGHTS];

And see what happens.

Note: if you find the syntax awkward, try with typedefs:

typedef const uint32_t waveform_t[WAVELENGHTS];
waveform_t *volatile currentWave;

You could even do:

typedef waveform_t *waveform_ptr;
volatile waveform_ptr currentWave;

but I find it excessive.

Altri suggerimenti

I guess you could try make the pointer volatile. Be sure not to just declare it a pointer to volatile uint32_t values, but to declare the pointer itself as volatile. My guess is that the compiler ignores it if the pointer itself is not volatile.

 const volatile uint32_t *currentWave;  <- "pointer" to "const volatile memory"
 const uint32_t * volatile currentWave;   <- "volatile pointer" to "const memory"

Also, I think there is no need for that extra indirection, you can just use a pointer, and assiging it like:

 currentWave = sinus;

is perfectly valid, just as indexing it like

 currentWave[(mainSynth.DDSAccumulator)>>24]

is valid C code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top