你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。
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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号
手机版
快速回复
返回顶部
返回列表
以下为串口打印出来的数据.上电后,前两秒数据是正确的.然后就出错了.好像接受了第一帧的数据后,判断为帧首,然后可能由于某种原因该帧的余下部分没有接收,然后接收到下一帧信息,由于接收数组的第一个位置已被放置数据,那么就从第二个位置开始放置接收到的数据.这样帧首就重复接收了两次,帧尾没被放到接收数组里.
不过按说接收超过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]