stm32H7的ADC极具使用价值,使用定时器的更新事件作为触发时钟源,可以在任意时钟下便捷的采集模拟硅麦的信号。下述是调试记录。
首先基于cubemx创建工程,并配置好时钟。其中ADC时钟配置需按照手册要求,不可过高,对于声音信号采集,10MHz已经足够。然后在对应管脚选择输入,大多数硅麦都是单端输入,选择"Single-ended"即可,其它保持默认。然后在参数中选择独立模式即"Independent mode" 。主要配置:
由于不需要过采样,因此过采样相关配置均关闭。在 "ADC_Regular_ConversionMode" 的详细配置如下:
此外,需注意Rank的配置,这里用来配置单独通道的采样。"Offset Number"和"Offset Signed Saturation"分别设置为"no offset"和"Disable",采样时间可以按需选择,周期越长理论上越精确。
其他设置组均保持关闭或禁用状态,然后在DMA中添加对应的配置,mode选择"从外设到memory",mode设置为 "circular",memory选择"Increment Address"即地址自增。同时打开 FIFO 半满阈值:勾选"Use FIFO",threshold 选择 "Half Full",Data Width均选择"Half Word",Brust Size 选择 "Single"。最后使能DMA中断。
将定时器设置为ADC的触发源时,“Mode”配置栏中仅需选择时钟源。在这里 Counter Mode 选择 "up",禁用Auto-load preload,不分频,此时触发频率即为 定时器时钟频率 / (Prescaler + 1) / (Counter Period + 1)。
这里采样率为44.1 Khz,Timer 时钟频率为100Mhz,则Prescaler 设置为9,Counter Period设置为226,实际频率 = 100_000_000/ (9+1) / (226 + 1) ≈ 44.052 Khz。
最后在 Trigger Out Parameters中做如下配置:
在启动ADC传输之前,需要先使能定时器,相关HAL库代码如下:
// htim4按需替换
HAL_TIM_Base_Start(&htim4);
// 启动传输
uint16_t ADCValue[512] = {0};
HAL_ADC_Start_DMA(&hadc2, (void *)ADCValue, 512);
// 终止传输
HAL_ADC_Stop_DMA(&hadc2);
在启动传输后,需要在DMA回调函数中处理采集到的数据,即:
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc);
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc);
参考资料: