tomzbj 发表于 2022-6-26 16:08:23

[原创] 用SPI_MOSI输出任意频率方波

本帖最后由 tomzbj 于 2022-6-26 16:20 编辑

前两天试了一下用GD32的一组8位GPIO接成R2R DAC做DDS
https://www.amobbs.com/thread-5767262-1-1.html

之后想到如果只需要方波的话, 用SPI的MOSI就可以了. 256字节的波形表不需要了,只需要32字节的输出缓冲区, DMA循环输出, 正好是256比特.
DMA的半满和全满中断改成这样, 循环展开是必须的, 否则实在太慢.

void DS_DMA_FTF(void)
{
    for(register int i = 0; i < 16; i++) {
      dma_tab = 0;
      counter += step;
      dma_tab |= ((counter >> 31) << 7);
      counter += step;
      dma_tab |= ((counter >> 31) << 6);
      counter += step;
      dma_tab |= ((counter >> 31) << 5);
      counter += step;
      dma_tab |= ((counter >> 31) << 4);
      counter += step;
      dma_tab |= ((counter >> 31) << 3);
      counter += step;
      dma_tab |= ((counter >> 31) << 2);
      counter += step;
      dma_tab |= ((counter >> 31) << 1);
      counter += step;
      dma_tab |= ((counter >> 31) << 0);
    }
}
void DS_DMA_HTF(void)
{
    for(register int i = 0; i < 16; i++) {
      dma_tab = 0;
      counter += step;
      dma_tab |= ((counter >> 31) << 7);
      counter += step;
      dma_tab |= ((counter >> 31) << 6);
      counter += step;
      dma_tab |= ((counter >> 31) << 5);
      counter += step;
      dma_tab |= ((counter >> 31) << 4);
      counter += step;
      dma_tab |= ((counter >> 31) << 3);
      counter += step;
      dma_tab |= ((counter >> 31) << 2);
      counter += step;
      dma_tab |= ((counter >> 31) << 1);
      counter += step;
      dma_tab |= ((counter >> 31) << 0);
    }
}

实测这两个中断子程序需要470个时钟周期左右, SPI时钟用主频的四分频, 128*4=512, 稍微有点紧张, 用8分频就很宽松了.
其他基本不变, 把涉及dac的部分改成spi就完事.

实测在200M左右的GD32上输出几百k的方波, 波形相当稳, 输出几M时就比较抖了.

huangqi412 发表于 2022-6-26 17:07:28

SPI是单线,要输出DA, 当成PWM用? 跟IO并口比,速度不是慢了很多吗。

tomzbj 发表于 2022-6-26 17:13:12

huangqi412 发表于 2022-6-26 17:07
SPI是单线,要输出DA, 当成PWM用? 跟IO并口比,速度不是慢了很多吗。
(引用自2楼)

不是pwm, 和dds类似, 关键是可以输出任意频率啊.

rei1984 发表于 2022-6-26 20:33:42

tomzbj 发表于 2022-6-26 17:13
不是pwm, 和dds类似, 关键是可以输出任意频率啊.
(引用自3楼)

lz 是高手, 看了知乎上的回答,感觉高度很高

zrp123 发表于 2022-6-27 08:07:52

DMA全传输完成中断改成
for(i = 16; i < 32; i++)
{
tab = ...;
}

是否能快一点?

tomzbj 发表于 2022-6-27 09:00:40

zrp123 发表于 2022-6-27 08:07
DMA全传输完成中断改成

是否能快一点?
(引用自5楼)

有可能, 不过估计这里编译器已经给优化过了吧

sczh0001 发表于 2022-6-29 13:57:44

改成汇编470 clock是否会明显减少么

tomzbj 发表于 2022-6-29 15:59:50

sczh0001 发表于 2022-6-29 13:57
改成汇编470 clock是否会明显减少么
(引用自7楼)

应该差不多到头了, 128个点, 470/128, 一个点只有3.67个时钟周期

每个点要累加, 两次移位, 再位与, 应该是这部分优化到了3个时钟周期, 128*3=384.

再加上循环体两头的load/store, 循环变量累加, 比较, 函数体入栈/出栈, 没多少优化空间了.
页: [1]
查看完整版本: [原创] 用SPI_MOSI输出任意频率方波