本帖最后由 一碗面 于 2024-5-26 18:07 编辑

【简介】
本文实现了驱动高速采集模块AD9220进行信号采集

【实验说明】
利用GD32H7高主频的特性,输出脉冲信号驱动驱动AD9220进行信号采集,理论上可以达到模块的上限10MHz的采集速率。

【实验效果】
下图是以20M的时钟频率,占空比50%采集1MHz的正弦信号得到的结果。
1M.png
  下图是以20M的时钟频率,占空比50%采集2MHz的正弦信号得到的结果。
2.png

【源代码】
DMA部分配置
注意一下采集的宽度,地址自增,采集个数等等配置
  1. dma_multi_data_parameter_struct dma0;
  2.     dma_deinit(DMA0, DMA_CH0);
  3.     dma_multi_data_para_struct_init(&dma0);
  4.     dma0.request = DMA_REQUEST_TIMER0_UP;
  5.     dma0.periph_addr = (uint32_t) (&GPIO_ISTAT(GPIOB));
  6.     dma0.periph_width = DMA_PERIPH_WIDTH_32BIT;
  7.     dma0.periph_inc = DMA_PERIPH_INCREASE_DISABLE;   // 开启地址自增
  8.     dma0.memory0_addr = (uint32_t) AD9920Buf;
  9.     dma0.memory_width = DMA_PERIPH_WIDTH_32BIT;
  10.     dma0.memory_inc = DMA_MEMORY_INCREASE_ENABLE;   // 地址自增
  11.     dma0.circular_mode = DMA_CIRCULAR_MODE_DISABLE;     // 循环关闭
  12.     dma0.direction = DMA_PERIPH_TO_MEMORY; // P T M
  13.     dma0.number = 2048;           // 这个是什么配置
  14.     dma0.priority = DMA_PRIORITY_ULTRA_HIGH; // very high
  15.     dma_multi_data_mode_init(DMA0, DMA_CH0, &dma0);

定时器部分配置
  1.     timer0.prescaler = 5 - 1;       // PSC
  2.     timer0.alignedmode = TIMER_COUNTER_EDGE;
  3.     timer0.counterdirection = TIMER_COUNTER_UP;    // 向上计数
  4.     timer0.period = 6-1;           // ARR
  5.     timer0.clockdivision = TIMER_CKDIV_DIV1;    // 不分频
  6.     timer0.repetitioncounter = 0U;
  7.     timer_init(TIMER0, &timer0);

PWM输出配置
记得写端口复用
  1.     /* CH0 configuration in PWM mode */
  2.     timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
  3.     timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
  4.     timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
  5.     timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
  6.     timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
  7.     timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
  8.     timer_channel_output_config(TIMER0, TIMER_CH_3, &timer_ocintpara);

  9.     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_3, 3);
  10.     timer_channel_output_mode_config(TIMER0, TIMER_CH_3, TIMER_OC_MODE_PWM0);
  11.     timer_channel_output_shadow_config(TIMER0, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
  12.     timer_dma_enable(TIMER0, TIMER_DMA_UPD);
  13.     timer_primary_output_config(TIMER0, ENABLE);

  14.     // auto preload enable
  15.     timer_auto_reload_shadow_enable(TIMER0);
  16.     timer_enable(TIMER0);

  17.     /// PWM GPIO
  18.     gpio_af_set(GPIOC, GPIO_AF_1, GPIO_PIN_7);    // 这里记得一定要写端口复用
  19.     gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
  20.     gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);

串口重定向
这里用的是GCC编译,所以改的是_write()函数
  1. int _write (int fd, char *pBuffer, int size)
  2. {
  3.     for (int i = 0; i < size; i++)
  4.     {
  5.         while(RESET == usart_flag_get(USART0, USART_FLAG_TC));//等待上一次串口数据发送完成
  6.         usart_data_transmit(USART0, pBuffer[i]);
  7.     }
  8.     return size;
  9. }

本文源码:https://github.com/shengxi-rise/GD32H7_AD9220

【总结】
GD32单片机在驱动AD9220信号采集模块时表现出良好的性能,能够满足1MHz正弦波信号的采集需求。实验结果表明,系统设计合理,能够有效地处理高速数据传输和采集任务。未来可以通过优化系统设计和外围电路,进一步提高系统的采样率和性能。后续将使用GD32的DSP库对采集到的信号进行FFT分析,计算信号的频率等参数。

【致谢】
感谢兆易创新这次测评机会,感谢xtx师兄对本项目的指导,感谢评测群里工作人员以及群大佬分享的资料。