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

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

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

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

【源代码】
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师兄对本项目的指导,感谢评测群里工作人员以及群大佬分享的资料。