【简介】
本文实现了驱动高速采集模块AD9220进行信号采集
【实验说明】
利用GD32H7高主频的特性,输出脉冲信号驱动驱动AD9220进行信号采集,理论上可以达到模块的上限10MHz的采集速率。
【实验效果】
下图是以20M的时钟频率,占空比50%采集1MHz的正弦信号得到的结果。
下图是以20M的时钟频率,占空比50%采集2MHz的正弦信号得到的结果。
【源代码】
DMA部分配置
注意一下采集的宽度,地址自增,采集个数等等配置
dma_multi_data_parameter_struct dma0;
dma_deinit(DMA0, DMA_CH0);
dma_multi_data_para_struct_init(&dma0);
dma0.request = DMA_REQUEST_TIMER0_UP;
dma0.periph_addr = (uint32_t) (&GPIO_ISTAT(GPIOB));
dma0.periph_width = DMA_PERIPH_WIDTH_32BIT;
dma0.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // 开启地址自增
dma0.memory0_addr = (uint32_t) AD9920Buf;
dma0.memory_width = DMA_PERIPH_WIDTH_32BIT;
dma0.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // 地址自增
dma0.circular_mode = DMA_CIRCULAR_MODE_DISABLE; // 循环关闭
dma0.direction = DMA_PERIPH_TO_MEMORY; // P T M
dma0.number = 2048; // 这个是什么配置
dma0.priority = DMA_PRIORITY_ULTRA_HIGH; // very high
dma_multi_data_mode_init(DMA0, DMA_CH0, &dma0);
复制代码定时器部分配置
timer0.prescaler = 5 - 1; // PSC
timer0.alignedmode = TIMER_COUNTER_EDGE;
timer0.counterdirection = TIMER_COUNTER_UP; // 向上计数
timer0.period = 6-1; // ARR
timer0.clockdivision = TIMER_CKDIV_DIV1; // 不分频
timer0.repetitioncounter = 0U;
timer_init(TIMER0, &timer0);
复制代码PWM输出配置
记得写端口复用
/* CH0 configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER0, TIMER_CH_3, &timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_3, 3);
timer_channel_output_mode_config(TIMER0, TIMER_CH_3, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
timer_dma_enable(TIMER0, TIMER_DMA_UPD);
timer_primary_output_config(TIMER0, ENABLE);
// auto preload enable
timer_auto_reload_shadow_enable(TIMER0);
timer_enable(TIMER0);
/// PWM GPIO
gpio_af_set(GPIOC, GPIO_AF_1, GPIO_PIN_7); // 这里记得一定要写端口复用
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);
复制代码串口重定向
这里用的是GCC编译,所以改的是_write()函数
int _write (int fd, char *pBuffer, int size)
{
for (int i = 0; i < size; i++)
{
while(RESET == usart_flag_get(USART0, USART_FLAG_TC));//等待上一次串口数据发送完成
usart_data_transmit(USART0, pBuffer[i]);
}
return size;
}
复制代码本文源码:https://github.com/shengxi-rise/GD32H7_AD9220
【总结】
GD32单片机在驱动AD9220信号采集模块时表现出良好的性能,能够满足1MHz正弦波信号的采集需求。实验结果表明,系统设计合理,能够有效地处理高速数据传输和采集任务。未来可以通过优化系统设计和外围电路,进一步提高系统的采样率和性能。后续将使用GD32的DSP库对采集到的信号进行FFT分析,计算信号的频率等参数。
【致谢】
感谢兆易创新这次测评机会,感谢xtx师兄对本项目的指导,感谢评测群里工作人员以及群大佬分享的资料。