STM32作为SPI从设备,中断接收5个数据,偶尔会出错。
用STM32的SPI2口,主设备不停的发送0x3a05,0x010a,0x0100,0x0000,0x9d76;以上5个16位数据为一帧,每帧间有一段时间间隔。
从设备我是这么处理的,利用SPI2的中断接收。
中断程序里,定义个spi2Num作为存放接收数据的位置,如果spi2Num == 0,先判断接收到的数据是不是帧首,如果是帧首的话,spi2Num = 1,且将接收到的这个数据放到接收数组的第一个位置;
然后再次接受中断时,依次根据spi2Num的值放到数组的相应位置,每次接收数据后,spi2Num++;
如果spi2Num > 4,说明已经接收到5个数据了,将spi2Num清零,并置个标志位,主程序里查询这个标志位,再做相应处理(串口将接收数组发送出来)。
现在的问题是,通过串口发送过来的数据,有时候是正确的。
有时候,上电前两次接收到的是正确的,然后都是错误帧。错误帧的第一二个数据都是0x3a05,其他数据依次往后推,最后一个没了。
接收错误时观察SCL和MOSI管脚波形,主机发送的数据是正确的。
以下为产生错误时的MSOI波形图,串口发送的数据,以及工程文件。
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 3a05
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
本帖最后由 yonghuzhuce 于 2016-6-8 10:32 编辑
更改了程序,删掉大部分功能。spi2中断接受数据后放到一个30个数据的数组里,接受够30个数据,置个标志位。
主程序里检测到这个标志位后,将30个数据用串口打印出来,如果是3a开头的,前边多加个空行。打印完后,清标志位,继续接受。
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
spi2RecvTemp:0000
spi2RecvTemp:9d76
spi2RecvTemp:3a05
spi2RecvTemp:010a
spi2RecvTemp:0100
看前半部分,好象是有规律的,接受的前两个数据,都是0x3a05。
前两帧有错误,后边开始接受正确了。
我就猜想,可能真的是主设备发送的数据有时候出了问题,联系发送了两个帧首?
看到后半段,貌似大部分又正确了,结果中间有部分丢失后边的数据。
现在只保留了串口中断,SPI中断,定时器中断。
串口只在接受满30个数据并置了标志位后才发送数据,此时虽然有SPI中断,但并不保存数据到数组里。
SPI接受数据时可能影响的只有定时器中断了,不过已经把SPI中断的优先级设最高了。
一会试试关掉定时器。 将程序简化了下,结果还是有问题。
主函数部分
int main(void)
{
Init();
TIM_Cmd(TIM3, ENABLE); //¿ªÆô¶¨Ê±Æ÷
while(1)
{
if(COMP_OK())
{
LVDS_EN(0);
if(spi2RecivOk)
{
spi2RecvNum = 0;
spi2RecivOk = 0;
SPI_I2S_SendData(SPI2, spi2SendBuff);
}
}
else
{
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7) == 0)
{
LVDS_EN(1);
SPI_I2S_SendData(SPI2, spi2SendBuff);
}
}
}
}
SPI中断部分
void SPI2_IRQHandler(void)
{
static u16 spi2Temp;
spi2Temp = SPI_I2S_ReceiveData(SPI2);
if(spi2RecvNum == 0)
{
if((spi2Temp & 0xFF00) == 0x3a00)
{
SPI_I2S_SendData(SPI2, spi2SendBuff);
spi2RecvNum = 1;
}
else
SPI_I2S_SendData(SPI2, spi2SendBuff);
}
else
{
spi2RecvBuff = spi2Temp;
spi2RecvNum++;
if(spi2RecvNum > 5)
{
spi2RecivOk = 1;
}
else
SPI_I2S_SendData(SPI2, spi2SendBuff);
}
}
附图为该设备连续发送两数数据的波形图。
根据图形可看出,发送第一帧是: 0x3a05,0x010a,0x010a,0x0100,0x0000,第二帧全是0x3a05。然后依次循环...
改成下面这样就没事了。主要是进入SPI中断后,SPI发送数据尽量靠前一点。也不知道为什么会这样。
在接收完帧首以后的中断处理里,就是else语句,需要将SPI发送语句放在紧靠else语句的位置。
这样的话,原来想只用spi2RecvNum这个变量控制接收和发送的数据位,现在不那么好实现了,于是又加了个变量spi2SendNum。
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);
spi2RecvBuff = spi2Temp;
spi2RecvNum = 1;
spi2SendNum = 2;
}
}
else
{
SPI_I2S_SendData(SPI2, spi2SendBuff);
spi2RecvBuff = spi2Temp;
spi2RecvNum++;
if(spi2RecvNum > 4)
spi2RecvOk = 1;
spi2SendNum += 1;
spi2SendNum %= 5;
}
}
}
页:
[1]