主题:ESM3354中应用SPI的问题 共有84266人关注过本帖 |
---|
![]() lqluo |
1楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
ESM3354中应用SPI的问题 ![]()
我所用的ESM3354系统是linux
有三个问题: 我在应用SPI时,把ESM3354做为slave,把fpga做为主机。时钟选择了12.5M。发送数据为16位,DB15先发送 (1) 用fpga发送后,在用ESM3354的函数接收到的数据是8位的,显示是低8位在前,高8位在后。是这样的吗? (2) 我一次用fpga要发送160K(16位)的数据,怎么把每个数的起始位对位? 我的意思是说:我发送完一个16位数据后,如果ESM3354只收到15位。我再发送下一个16位数, 结果ESM3354没识别出来这是一个新的数据,还把它刚接收到的DB15当成上一个数的DB0。这样后面所有接收的数都是错的。 这种情况下怎么处理? (3) 我电路板中只有一个SPI,ESM3354做为从机时,SPI的cs信号还有用吗? |
单帖管理 | 引用 | 回复 ![]() |
ccl |
2楼 |
![]() |
![]()
你好!
1、是这样的,在应用程序端read到的数据是按字节copy出来的,所以16位数据对应两个字节,低八位在前。 2、SPI是同步时钟,主机发送16位数据会有16个时钟信号,esm3354应该会收到16位数据,只要spi的工作模式设置正确,应该不会出现这种情况。 3、做从机时,cs信号作为从机的输入信号,低有效。
|
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
3楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]()
我是想这样:主机想发送一个数据包给ESM3354,希望发送初始时ESM3354处于初始状态:
即假设这时ESM3354接收过程中出现错误,还没接收完一个完整的16位数据(比如只接收完15位),还在等主机送来的时钟, 而这时主机送过来的第一个时钟是本应该对应新数据的DB15,而不是对应上一个数据位(比如DB0),但ESM3354会把它当作对应上一个数据位(比如DB0)的时钟。这样后面所有的数据都会出错。 所以我希望主机给ESM3354一个信号时,比如外部中断,能让ESM3354的SPI恢复初始状态。 或者说,每次主机在令cs变低后发送完16个时钟,然后令cs变高,如果此次esm3354没接收到16个时钟,而检测到cs变高,esm3354会怎么处理这种情况? [此贴子已经被作者于2017-5-9 22:14:35编辑过]
|
单帖管理 | 引用 | 回复 ![]() |
x10 |
4楼 |
![]() |
![]()
SPI是一种近距离的同步串行接口,且发送-接收双方都是硬件操作,应当不存在SPI_CLOCK丢失的问题。否则SPI就没有意义了。
|
单帖管理 | 引用 | 回复 ![]() |
ccl |
5楼 |
![]() |
![]()
片选信号一变高,那么本次接收就结束了,再次拉低,新的一次接收开始,不会影响后边的数据。但是在一次接收还没有完成时,片选信号被拉高,从机接收到的数据是什么样的还不确定,需要做实验验证,稍后回答你。
|
单帖管理 | 引用 | 回复 ![]() |
ccl |
6楼 |
![]() |
![]()
你好,经过实验确认,我的上一个回答是错误的,片选拉高只表示发送方结束了,接收方(从设备)依然要接收16个时钟才会读出数据,并且不受片选信号影响。也就是说从设备接收15位数据后,片选信号拉高,从设备依然会等待第16个时钟的到来,会影响后面的数据。
我们实验是让主机发送15位,从机接收16位,这是两边设置上的错误导致的。实际应用中,两边设置相同的情况下,同步时钟应该不会出现丢失时钟的情况,并且时钟信号是非常重要的,电路上应该优先保护,请问你出现这种情况的应用场景是什么样的?
|
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
7楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]()
我是在主机fpga运行时,从机esm3354更新程序后再运行。此时ESM3354与主机就失去了同步,丢失了很多时钟。
所以我想知道:在运行中如果发生错误,如何恢复。 不能因为一个时钟错误,后面再发给SPI的数据,结果SPI接收到全是错的。假设这一次发送的数据包我可以丢弃,但后面所有的数据包不能丢弃啊。 |
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
8楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]()
给我的感觉是一旦spi错误一次,以后spi就不能恢复正常了,也没法用了。
|
单帖管理 | 引用 | 回复 ![]() |
ccl |
9楼 |
![]() |
![]()
spi协议本身没有握手信号,所以时钟丢失必然会影响后边的通信。建议在esm3354更新程序之前,向主机发送更新程序的信号,主机接收到信号后停止发送数据。esm3354更新完程序后,向主机发送程序更新完毕的信号,进入spi slave模式,主机接收到程序更新完毕的信号之后,再发送数据。
|
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
10楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]() 那我每秒向ESM3354发送300K数据,1天24小时不停的发,每天送几十G的数据存入硬盘。设备一运行可能就是几个月,发送的数据是几个T。 中间要是出现一个时钟误差,设备就没法传送正常的数据了。是这样吗? |
单帖管理 | 引用 | 回复 ![]() |
x10 |
11楼 |
![]() |
![]()
对大数据采集存储的应用,从设计角度讲,肯定会把数据分块“传输-验证-存储”,并对出错情况加以处理。英创的工控主板,除了SPI接口外,还有很多其他接口资源,足以完成这些功能。如果仅仅依靠一个SPI接口,按上贴描述的那样连续不断的接收数据,显然不是一个完备的设计方案。
|
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
12楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]()
焦点主要在: ESM3354知道数据接收错了,怎么才能让ESM3354接收一下个数据包的时候不受前面的状态的影响?也就是说,让ESM3354的spi口在接收下一数据包前恢复初始状态,即它接收的一下个数据包的第一个时钟是新数据的DB15,而不是旧数据的DB0
|
单帖管理 | 引用 | 回复 ![]() |
x10 |
13楼 |
![]() |
![]()
我理解就是需要实现流控功能,比如ESM3354有一个输出READY#(可用GPIO充当),当READY#为低时,表示可接收SPI数据流;当READY#为高时,则停止发送数据。ESM3354在接收过程中,可对接收的数据进行校验,若出错则让READY#=H,同时reset SPI,再重新启动SPI接收(READY#=L)。
|
单帖管理 | 引用 | 回复 ![]() |
![]() lqluo |
14楼 信息 | 搜索 | 邮箱 |
![]() ![]() ![]() ![]() |
![]()
怎样复位ESM3354的SPI?
|
单帖管理 | 引用 | 回复 ![]() |
x10 |
15楼 |
![]() |
![]()
从应用程序的角度就是关闭SPI设备文件,然后再打开即可。
|
单帖管理 | 引用 | 回复 ![]() |