我在C中为STM32F0发现板编写简单代码。我根据外部模拟信号生成不同的波形。
声明具有波形的全局数组:
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,...}
和指向数组的指针
const uint32_t (*currentWave)[WAVELENGHTS];
该指针用于定时器irq以生成所选波形:
void TIM14_IRQHandler()
{
...
TIM2->CCR1 = (*currentWave)[(mainSynth.DDSAccumulator)>>24];
TIM14->SR &= ~(TIM_SR_CC1IF);
}
根据外部值,在主循环中我选择一个波形:
while(1) {
...
if(ADC_values[2] < 2048)
currentWave = &sinus;
else
currentWave = □
...
}
如果没有优化,currentWave值会根据ADC_values [2]的变化而变化(确切地说:到TIM2-> CCR1是从良好的波形,正弦波或方波写入的值),但是启用任何优化都会使代码工作不正常,这意味着分配< / p>
currentWave = &sinus;
或
currentWave = □
永远不会执行,currentWave总是有初始值。
我还尝试将指针和数组声明为volatile,但没有效果。
我需要针对尺寸进行优化以适应设备中的代码。
有什么想法吗?
答案 0 :(得分:0)
我想你可以尝试使指针易变。一定不要将它声明为指向易失性uint32_t值的指针,而是将指针本身声明为volatile。我的猜测是,如果指针本身不是易失性的,编译器会忽略它。
const volatile uint32_t *currentWave; <- "pointer" to "const volatile memory"
const uint32_t * volatile currentWave; <- "volatile pointer" to "const memory"
另外,我认为不需要额外的间接,你可以只使用一个指针,并像下面这样指定:
currentWave = sinus;
完全有效,就像索引一样
currentWave[(mainSynth.DDSAccumulator)>>24]
是有效的C代码。
答案 1 :(得分:0)
我会做出一个疯狂的猜测:你用这种方式尝试了它,它没有工作:
const volatile uint32_t (*currentWave)[WAVELENGHTS];
这是可以预料到的,因为这个声明使得数组的uint32_t
值变为volatile,而不是指针。指针是异步变化的。
尝试改为:
const uint32_t (* volatile currentWave)[WAVELENGHTS];
看看会发生什么。
注意:如果您发现语法笨拙,请尝试使用typedefs:
typedef const uint32_t waveform_t[WAVELENGHTS];
waveform_t *volatile currentWave;
你甚至可以这样做:
typedef waveform_t *waveform_ptr;
volatile waveform_ptr currentWave;
但我觉得它太过分了。