新手入门
- 积分
- 12
- 金钱
- 12
- 注册时间
- 2022-6-10
- 在线时间
- 2 小时
|
发表于 2022-6-14 13:28:26
|
显示全部楼层
这个问题其实很简答,原子大侠的做法是追求极致速度的做法,如果要按照特定的节奏读取GPIO数据,这种做法就不适合。
我的设计是工作的一部分,很抱歉不能贴出代码,但可以用文字简单说明。
先说一下硬件背景,CPU是STM32F405RGT6,即64脚LQFP封装的器件,只有GPIOA~C三个口可用,不过也足够了。数据从GPIOC的低字节输入,每250ns一个字节,因此只能使用DMA。
由TIM8定时产生DMA请求,DMA采用双缓冲区的方式,每传输64(256字节)个字节中断一次,由软件把数据倒腾出来并进行初步的预处理。
DMA的配置中,这里只挑重点说:
首先传输方向自然是PeripheralToMemory,设备数据宽度为字节,内存数据宽度为32位字,外设地址设置为GPIOC->IDP的地址。DMA缓冲区为一个二维数组,其基地址设置在DMA_SxM0AR中,后半区地址通过设置双缓冲区的函数设置。使能FIFO模式,外设和内存的突发模式都选择单次,而突发大小其实已经不重要了。
这里需要说明一下:其实内存的数据宽度也可以选择字节,然后禁止FIFO模式(即采用直接模式)。不过这种做法并太好,因为每250ns就需要触发一次写内存的DMA,会影响主程序的执行效率。如果每次DMA传输的数据量是4字的整数倍,甚至可以采用更大的突发模式,例如突发阈值设置成全满,内存突发大小设置成4拍,这样每4个字才触发写内存的DMA操作,充分利用器件内部的FIFO资源。
DMA中断服务例程使用汇编语言编写,是为了能够足够快地完成。实际上即使用C语言也没有问题。
我的设计已经通过验证。
|
|