你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。
chrome
firefox
safari
ie8及以上
ST
意法半导体官网
STM32
中文官网
ST
全球论坛
登录/注册
首页
技术问答
话题
资源
创客秀
视频
标签
积分商城
每日签到
SPI从模式接收数据不正确,附波形图。
[复制链接]
any012
提问时间:2016-5-28 09:48 /
本帖最后由 any012 于 2016-5-28 09:52 编辑
用STM32做SPI从设备,接受用的中断,每接收一次数据,将要发送的数据放到发送寄存器里。
第一张是SCL和MOSI的波形图。
第二张是SCL和MISO的波形。
可以看到我的STM32从设备发送到第二和第三个数据是一样的。其实是不一样的,第一个发送的数是正确的,第二个数发送了两遍,然后发送第三、第四个数。想第五个数被吃掉了...
以下为SPI中断函数。
void SPI2_IRQHandler(void)
{
static u8 spi2Num;
u16 spi2Temp;
spi2Temp = SPI_I2S_ReceiveData(SPI2);
if(spi2Num == 0)
{
if(spi2Temp == 0x3a05)
{
spi2Num = 1;
spi2RecvBuff[0] = spi2Temp;
SPI_I2S_SendData(SPI2, spi2SendBuff[1]);
}
}
else
{
spi2RecvBuff[spi2Num] = spi2Temp;
spi2Num++;
if(spi2Num > 4)
{
spi2Num = 0;
spi2ReciveOk = 1;
}
SPI_I2S_SendData(SPI2, spi2SendBuff[spi2Num]);
}
}
复制代码
赞
0
收藏
0
评论
5
分享
发布时间:2016-5-28 09:48
举报
请先
登录
后回复
5个回答
any012
回答时间:2016-5-31 17:33:42
a0a.1 32b0c
现在觉得问题还是出在中断处理函数里.
以下为串口打印出来的数据.上电后,前两秒数据是正确的.然后就出错了.好像接受了第一帧的数据后,判断为帧首,然后可能由于某种原因该帧的余下部分没有接收,然后接收到下一帧信息,由于接收数组的第一个位置已被放置数据,那么就从第二个位置开始放置接收到的数据.这样帧首就重复接收了两次,帧尾没被放到接收数组里.
不过按说接收超过5个数据后,会将spi2Num清零的,重新从接收数组的第一个数据开始存放数据.但问题是,以后每次出现的都是重复两个帧首...
这就不理解了.
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 10a
spi2recvBuff[2]: 100
spi2recvBuff[3]: 0
spi2recvBuff[4]: 9d76
spi2Recive[4]: 9d76
crc: 9d76
CRC校验Ok.
spi2SendBuff[0]: 3a05
spi2SendBuff[1]: 10a
spi2SendBuff[2]: 100
spi2SendBuff[3]: 5556
spi2SendBuff[4]: 289
发送结束
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 10a
spi2recvBuff[2]: 100
spi2recvBuff[3]: 0
spi2recvBuff[4]: 9d76
spi2Recive[4]: 9d76
crc: 9d76
CRC校验Ok.
spi2SendBuff[0]: 3a05
spi2SendBuff[1]: 10a
spi2SendBuff[2]: 100
spi2SendBuff[3]: 5557
spi2SendBuff[4]: 9288
发送结束
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 3a05
spi2recvBuff[2]: 10a
spi2recvBuff[3]: 100
spi2recvBuff[4]: 0
spi2Recive[4]: 0
crc: bf51
CRC校验失败.
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 3a05
spi2recvBuff[2]: 10a
spi2recvBuff[3]: 100
spi2recvBuff[4]: 0
spi2Recive[4]: 0
crc: bf51
CRC校验失败.
赞
0
评论
回复
支持
反对
any012
回答时间:2016-6-1 08:50:53
a0a.1 32b0c
重复回复了,编辑掉。
赞
0
评论
回复
支持
反对
any012
回答时间:2016-6-15 09:23:42
a0a.1 32b0c
改成下面这样就没事了。主要是进入SPI中断后,SPI发送数据尽量靠前一点。也不知道为什么会这样。
在接收完帧首以后的中断处理里,就是else语句,需要将SPI发送语句放在紧靠else语句的位置。
这样的话,原来想只用spi2RecvNum这个变量控制接收和发送的数据位,现在不那么好实现了,于是又加了个变量spi2SendNum。
[mw_shl_code=c,true]void SPI2_IRQHandler(void)
{
static u8 n;
static u16 spi2Temp;
spi2Temp = SPI_I2S_ReceiveData(SPI2);
if(spi2RecvOk == 0)
{
if(spi2RecvNum == 0)
{
if((spi2Temp & 0xff00)== 0x3a00)
{
SPI_I2S_SendData(SPI2, spi2SendBuff[1]);
spi2RecvBuff[0] = spi2Temp;
spi2RecvNum = 1;
spi2SendNum = 2;
}
}
else
{
SPI_I2S_SendData(SPI2, spi2SendBuff[spi2SendNum]);
spi2RecvBuff[spi2RecvNum] = spi2Temp;
spi2RecvNum++;
if(spi2RecvNum > 4)
spi2RecvOk = 1;
spi2SendNum += 1;
spi2SendNum %= 5;
}
}
}[/mw_shl_code]
赞
0
评论
回复
支持
反对
sayuenala
回答时间:2016-6-20 14:49:11
a0a.1 32b0c
楼主找到答案了吗
赞
0
评论
回复
支持
反对
废鱼
回答时间:2016-6-21 09:27:09
a0a.1 32b0c
楼主还是仿真一下看看spi2Num的值,我怀疑是这里出的问题,定义到全局试试。
赞
0
评论
回复
支持
反对
所属标签
相似问题
关于
意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
微信公众号
手机版
快速回复
返回顶部
返回列表
以下为串口打印出来的数据.上电后,前两秒数据是正确的.然后就出错了.好像接受了第一帧的数据后,判断为帧首,然后可能由于某种原因该帧的余下部分没有接收,然后接收到下一帧信息,由于接收数组的第一个位置已被放置数据,那么就从第二个位置开始放置接收到的数据.这样帧首就重复接收了两次,帧尾没被放到接收数组里.
不过按说接收超过5个数据后,会将spi2Num清零的,重新从接收数组的第一个数据开始存放数据.但问题是,以后每次出现的都是重复两个帧首...
这就不理解了.
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 10a
spi2recvBuff[2]: 100
spi2recvBuff[3]: 0
spi2recvBuff[4]: 9d76
spi2Recive[4]: 9d76
crc: 9d76
CRC校验Ok.
spi2SendBuff[0]: 3a05
spi2SendBuff[1]: 10a
spi2SendBuff[2]: 100
spi2SendBuff[3]: 5556
spi2SendBuff[4]: 289
发送结束
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 10a
spi2recvBuff[2]: 100
spi2recvBuff[3]: 0
spi2recvBuff[4]: 9d76
spi2Recive[4]: 9d76
crc: 9d76
CRC校验Ok.
spi2SendBuff[0]: 3a05
spi2SendBuff[1]: 10a
spi2SendBuff[2]: 100
spi2SendBuff[3]: 5557
spi2SendBuff[4]: 9288
发送结束
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 3a05
spi2recvBuff[2]: 10a
spi2recvBuff[3]: 100
spi2recvBuff[4]: 0
spi2Recive[4]: 0
crc: bf51
CRC校验失败.
******************************************************
1s定时到。
spi2recvBuff[0]: 3a05
spi2recvBuff[1]: 3a05
spi2recvBuff[2]: 10a
spi2recvBuff[3]: 100
spi2recvBuff[4]: 0
spi2Recive[4]: 0
crc: bf51
CRC校验失败.
在接收完帧首以后的中断处理里,就是else语句,需要将SPI发送语句放在紧靠else语句的位置。
这样的话,原来想只用spi2RecvNum这个变量控制接收和发送的数据位,现在不那么好实现了,于是又加了个变量spi2SendNum。
[mw_shl_code=c,true]void SPI2_IRQHandler(void)
{
static u8 n;
static u16 spi2Temp;
spi2Temp = SPI_I2S_ReceiveData(SPI2);
if(spi2RecvOk == 0)
{
if(spi2RecvNum == 0)
{
if((spi2Temp & 0xff00)== 0x3a00)
{
SPI_I2S_SendData(SPI2, spi2SendBuff[1]);
spi2RecvBuff[0] = spi2Temp;
spi2RecvNum = 1;
spi2SendNum = 2;
}
}
else
{
SPI_I2S_SendData(SPI2, spi2SendBuff[spi2SendNum]);
spi2RecvBuff[spi2RecvNum] = spi2Temp;
spi2RecvNum++;
if(spi2RecvNum > 4)
spi2RecvOk = 1;
spi2SendNum += 1;
spi2SendNum %= 5;
}
}
}[/mw_shl_code]