stm32之串口DMA接收丢数问题 程序上设置两个512字节的数组轮流接收串口DMA数据,将接收的数据放入一个大的缓冲数组buffer[0x4000]中,当凑够接近16k就时就写入u盘一次, 发现每次快要达到16k,执行写入u盘的时候,接收的后面的串口数据会丢字节。
举个例子,例子中又多定义了个0x4000的数组,以便在一个执行写u盘过程时,另一个作为数据接收缓冲。
char DMA_buf1[512]; //两个512字节大小的DMA缓冲来轮流切换接收串口数据,并放置到后面的16k字节的缓冲区内 char DMA_buf2[512]; char buf1[0x4000]; char buf2[0x4000]; 当DMA_buf1接收满512字节时,触发DMA满中断,设置DMA缓冲区为DMA_buf2,并将DMA_buf1数据复制到buf1中,等下次DMA满中断在切换DMA_buf,并将DMA_buf2连接到buf1中。依次循环 当判断buf1若超过了(16k减去512字节大小时),将DMA_buf1和2缓存满后放入buf2中,并执行写u盘操作,将buf1中的数据写入u盘 ,等buf2满了,在轮流切换。 我保存出来的文件发现,每次在(16k减去512字节)的位置,随后的几个字节会丢失。
我分析原因是写入u盘时占用了spi外设也就占用了系统总线,导致DMA无法传输。 因为我写u盘需要用spi操纵一个ch376芯片写入,如果是想我分析的那样spi占用了系统总线导致DMA接收数据丢失,我该怎么办呢?
硬件资源上应该不会冲突,还是仔细分析一下你的代码 像这一类缓冲区轮换、转圈的处理很容易在边界处出问题
这种情况多数是自己代码里面有bug造成的。如果有for循环之类,试试更改缓冲区大小,更改循环体的上限,看看出错的位置是不是有相应的变化。如果实在怀疑IC内部冲突,可以分离你的SPI代码,做一个最小工程测试。N次循环使用一段数据通过SPI写入U盘,故意造成总线长时间占用。在这个情况下驱动串口DMA来验证你的推断。
我分析原因是写入u盘时占用了spi外设也就占用了系统总线,导致DMA无法传输。 因为我写u盘需要用spi操纵一个ch376芯片写入,如果是想我分析的那样spi占用了系统总线导致DMA接收数据丢失,我该怎么办呢? 上面是你分析的原因,按你这么说不管写多少个字节的数据都会有数据丢失,那你少写点数据看看也会不会有这问题。
|