【精品博文】MCP2510CAN控制器发现的bug
前言:首先声明一下,不黑不吹,由于笔者技术水平有限,下面说的如果有错误希望大家给指正哈,主要是互相沟通多多交流,勿喷勿黑啊!
MCP2510是一种带有SPI接口的CAN控制器,具有两个收数缓存区,RXB0和RXB1,RXB0对应一个mask和两个filter,RXB1对应一个mask和两个filter,mask和filter非常重要,可以在大数据量的时候可以通过过滤滤掉没必要的数据(下图见数据手册22页),当数据RXB0和RXB1没有被取走,如果数据继续来就会被放在MAB区中,记住这点,下面还要说这个呢。
MCP2510收数过程如下,大家自己查看一下数据手册第23页。概括一下就是先用硬件判数据是否正确,然后根据寄存器设置来决定数据被分配到那个缓存区。
现在说一种情况,如果对RXB0CTRL的bit5 bit6设置为11(Turn mask/filters off; receive any message),bit2设置为1(RXB0 message will rollover and be written to RXB1 if RXB0 is full),上面说过,如果数据在缓存区中已经满了,数据继续来就会被放在MAB区中,如果多组数据到来都在MAB中,MAB就会溢出,这样就会出现拼帧现象,比如前一包数据是 00 00 00 00 00 00 00 00,后一包数据是11 11 11 11 11 11 11 11,那么这个拼帧的数据就有可能是 00 00 00 00 11 11 11 11,所以当你读到数据就是错误的。An overflow condition occurs when the MAB has assembled a valid received message (the message meets the criteria of the acceptance filters) and the receive buffer associated with the filter is not vailable for loading of a new message. The associated EFLG.RXNOVR bit will be set to indicate the overflow condition. This bit must be cleared by the MCU.
不过这也不是问题,因为在在寄存器EFLG中会有相应的标志告诉你这包数据是否是拼帧的。EFLG中的bit6 和bit7分别就是这个作用,告诉你这个数据是不是overflow的。
bit 7 RX1OVR: Receive Buffer 1 Overflow Flag
- Set when a valid message is received for RXB1 and CANINTF.RX1IF = 1
- Must be reset by MCU
bit 6 RX0OVR: Receive Buffer 0 Overflow Flag
- Set when a valid message
- Must be reset by MCU
如果判到这位,那么这包数据不要就可以了。现在开始说bug的事情,当时我也天真的认为只要这样判断就可以保证收到的数据都是正确的了,但是当我在大数据量情况下收这个数据的时候,我发现还有问题,当时心中真是一万匹那个什么马奔腾而过啊,查不到什么原因只能通过多次测试来查找问题。经过多次测试发现,每次收到收到overflow的时候,收到数据都是RXB0,而RXB1从来没有被置上过overflow的标志,然后再继续测试,发现每次收到错误数据也就是拼帧的时候,接收的通道都是RXB1,那也就是说RXB1的overflow的标志都因为某种原因没有被置上过即使收到了已经是拼帧的信息。这里再说一下,对于RXB0,就算是overflow被置上了收到的数据不一定错,当收到的数据是错的时候,overflow一定会被置上。
再看下面这段:
RXB0 is the higher priority buffer and has two message acceptance filters associated with it. RXB1 is the lower priority buffer and has four acceptance filters associated with it. The lower number of acceptance filters makes the match on RXB0 more restrictive and implies a higher priority for that buffer. Additionally, the RXB0CTRL register can be configured such that if RXB0 contains a valid message, and another valid
message is received, an overflow error will not occur and the new message will be moved into RXB1 regardless of the acceptance criteria of RXB1.
如果RXB0CTRL寄存器bit2设置为1, RXB0 message will rollover and be written to RXB1 if RXB0 is full,在这种情况下如果该帧数据是overflow的,那么EFLG的bit7是不会被置上的,这是通过测试得出的结论,我就被这个bug坑苦了。大家使用的时候一定要注意这个,果RXB0CTRL寄存器bit2一定要设置为0,否则就苦逼了。会收到错误的数据,大家在使用过程中一定要注意啊~
好了,bug说完了,欢迎板砖~
下面这段是抄的啊,先谢谢原创作者,验证过了,写的非常好,原文链接是这个http://blog.sina.com.cn/s/blog_62b250b50101ob3p.html
(1)因为 MCP2510在初始化完成后默认处Configuration模式下,所以就需要在MCP2510的初始化完后将其置为 Normal模式,否则MCP2510将一直停留在Configuration 模 式 下, 不 能 进 行 正 常 工 作。将MCP2510置Normal模式可通过使用 MCP2510内置的BitModify(位修改)4指令向CANCTRL控制字写入一个0字节来实现.
(2)在对MCP2510做任何操作之前,都要由微处理器向MCP2510的片选CS输出一个低电平,使得MCP2510被选通。
(3)在进行MCP2510的“读”操作时,发送完读指令及其地址码之后,仍然需要向MCP2510提供时钟,以接收“读”到的数据。可以通过向MCP2510发送一个“0”字节来实现。
(4)在对MCP2510做完任意操作后,都要延时一段时间,使其有足够的时间来准备接收下次操作的命令,防止出现MCP2510“忙”的情况。