搜索
bottom↓
回复: 7

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

[复制链接]

出0入362汤圆

发表于 2022-6-26 16:08:23 | 显示全部楼层 |阅读模式
本帖最后由 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的半满和全满中断改成这样, 循环展开是必须的, 否则实在太慢.

  1. void DS_DMA_FTF(void)
  2. {
  3.     for(register int i = 0; i < 16; i++) {
  4.         dma_tab[i + 16] = 0;
  5.         counter += step;
  6.         dma_tab[i + 16] |= ((counter >> 31) << 7);
  7.         counter += step;
  8.         dma_tab[i + 16] |= ((counter >> 31) << 6);
  9.         counter += step;
  10.         dma_tab[i + 16] |= ((counter >> 31) << 5);
  11.         counter += step;
  12.         dma_tab[i + 16] |= ((counter >> 31) << 4);
  13.         counter += step;
  14.         dma_tab[i + 16] |= ((counter >> 31) << 3);
  15.         counter += step;
  16.         dma_tab[i + 16] |= ((counter >> 31) << 2);
  17.         counter += step;
  18.         dma_tab[i + 16] |= ((counter >> 31) << 1);
  19.         counter += step;
  20.         dma_tab[i + 16] |= ((counter >> 31) << 0);
  21.     }
  22. }
  23. void DS_DMA_HTF(void)
  24. {
  25.     for(register int i = 0; i < 16; i++) {
  26.         dma_tab[i] = 0;
  27.         counter += step;
  28.         dma_tab[i] |= ((counter >> 31) << 7);
  29.         counter += step;
  30.         dma_tab[i] |= ((counter >> 31) << 6);
  31.         counter += step;
  32.         dma_tab[i] |= ((counter >> 31) << 5);
  33.         counter += step;
  34.         dma_tab[i] |= ((counter >> 31) << 4);
  35.         counter += step;
  36.         dma_tab[i] |= ((counter >> 31) << 3);
  37.         counter += step;
  38.         dma_tab[i] |= ((counter >> 31) << 2);
  39.         counter += step;
  40.         dma_tab[i] |= ((counter >> 31) << 1);
  41.         counter += step;
  42.         dma_tab[i] |= ((counter >> 31) << 0);
  43.     }
  44. }
复制代码

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

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2022-6-26 17:07:28 | 显示全部楼层
SPI是单线,要输出DA, 当成PWM用? 跟IO并口比,速度不是慢了很多吗。

出0入362汤圆

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

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

出0入25汤圆

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

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

出0入0汤圆

发表于 2022-6-27 08:07:52 | 显示全部楼层
DMA全传输完成中断改成
  1. for(i = 16; i < 32; i++)
  2. {
  3. tab[i] = ...;
  4. }
复制代码

是否能快一点?

出0入362汤圆

 楼主| 发表于 2022-6-27 09:00:40 | 显示全部楼层
zrp123 发表于 2022-6-27 08:07
DMA全传输完成中断改成

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

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

出0入0汤圆

发表于 2022-6-29 13:57:44 | 显示全部楼层
改成汇编470 clock是否会明显减少么

出0入362汤圆

 楼主| 发表于 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, 循环变量累加, 比较, 函数体入栈/出栈, 没多少优化空间了.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-16 10:35

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表