关于spi传输速度的疑问

2019-07-20 08:38发布

关于hal库里的 HAL_SPI_TransmitReceive这个函数
之前没用过spi,目前在调一个spi摄像头,时序要求1/27s内传输读取完一帧的图像数据,一帧图像9840个字节
通过使用下面这个函数
u8 SPI5_ReadWriteByte(u8 TxData)
{
    u8 Rxdata;
    HAL_SPI_TransmitReceive(&SPI5_Handler,&TxData,&Rxdata,1, 1000);      
     return Rxdata;                        
}
传输一个字节的数据,我用st-link Debug调试发现执行一次HAL_SPI_TransmitReceive()需要大概0.16ms的时间,这样算下来,光读完这一帧图像的数据就要1s多,
系统时钟方面也有尝试调高频率,但是并没有明显的改善。
是这个函数的效率问题么?还是我计算的方式问题?有什么建议的解决方案。

请各位大佬指点迷津,不胜感激。


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
正点原子
1楼-- · 2019-07-20 12:11
 精彩回答 2  元偷偷看……
正点原子
2楼-- · 2019-07-20 17:16
直接写寄存器。
嘬腮怪人
3楼-- · 2019-07-20 22:30
 精彩回答 2  元偷偷看……
正点原子
4楼-- · 2019-07-20 23:31
嘬腮怪人 发表于 2018-4-1 11:52
原子哥你好,我改操作寄存器,速度上有了改善,但还是达不到预期
u8 SPI5_ReadWriteByte(u8 TxData) // ...

用dma读
嘬腮怪人
5楼-- · 2019-07-21 01:33
正点原子 发表于 2018-4-2 01:32
用dma读

原子哥你好,我在F767的板子上使用这个函数
u8 SPI5_ReadWriteByte(u8 TxData) //读一个字节
{                                          
        while((SPI5->SR&1<<1)==0);               
        SPI5->DR=TxData;                                   
        while((SPI5->SR&1<<0)==0);               
         return SPI5->DR;                                             
}
并通过示波器观察时钟信号发现,执行一步a=SPI5_ReadWriteByte(0x00);的操作,实际上sck引脚发送了16个周期的时钟,因此会少读8位的数据。SPI设置的是8位的读取, SPI5_Handler.Init.DataSize=SPI_DATASIZE_8BIT;   
尝试过将上面的函数改成:
u16 SPI5_ReadWriteByte(u16 TxData) //读一个字节
{                                          
        while((SPI5->SR&1<<1)==0);               
        SPI5->DR=TxData;                                   
        while((SPI5->SR&1<<0)==0);               
         return SPI5->DR;                                             
}
然后使用a=SPI5_ReadWriteByte(0x0000); 读取出来的数据顺序存在问题,例如按示波器的波形取出来的数据应该是0x0FFF,而函数返回的数据是0xFF0F,也就是0F和FF的顺序反了一下,后续收到的每个16位数据的顺序也都是这样反的。
改回 使用HAL_SPI_TransmitReceive()后收到的数据就正常了。
通过网上查询资料发现有人给出部分解答:
   SPI结构体定义DR这个成员是16位,因此【SPI2->DR=(uint8_t)TxData;】是把一个8位数据写到16位指针所指的地址;后者【 *(__IO uint8_t *) spixbase = TxData;】即库里的SPI_SendData8()是把一个8位数据写到8位指针所指向的地址。因此当使用前者的写法,如果编译器作为一个16位写入的操作,则实际写入了两个8位长度的数据帧,因此会看到时钟出来了16个脉冲,对应2个8位数据帧。
那么这个读取8位的函数该如何更改?如果想要读取16位,如何解决数据顺序错误的问题?
望原子哥为我解惑。
嘬腮怪人
6楼-- · 2019-07-21 07:06
 精彩回答 2  元偷偷看……

一周热门 更多>