我在之前的一篇文中,写过关于CAN发送功能如何使用,但是当时由于时间匆忙,赶项目,按照对USART中断发送的理解,在数据成功发送出去的情况下,写了那篇误人子弟的文,在这里向大家道歉,实在不好意思,现在我重新阐述下CAN中断发送原理。
1、USART发送中断与CAN发送中断的区别
USART发送中断,是因为发送缓冲区为空,CAN发送中断的中断源是成功(或者abort)发送一次,正是这种区别误导了我。
2、我之前的CAN中断发送的处理方法是,将数据填充到发送缓冲区,由CAN中断提取进行发送,为了启动CAN的发送,我写了一句话CAN->sTxMailBox[0].TIR |= 1;就是启动发送,我以为在这以后CAN执行的动作是:产生中断,将数据从发送缓冲区提取,发送,进入完成中断,判断有无数据,没有就关闭中断,否则继续发送。但是CAN实际执行的动作是:发送,进入发送完成中断,提取数据,发送,进入完成中断,判断有无数据,没有就关闭中断,否则继续发送。由此可见,CAN实际上是多发送了一次数据,这个数据就是当前CAN寄存器里面的数据,而这次发送,应用层和CAN中断程序里都没有参与,所以是不被发现的,这也据解释了为什么对方收到的数据比我发送的数据多,在A发送大量数据的时候,B做应答,但是每次都请求发送,由于速度快,B每次实际发送了同样的数据给A,A所以收到 很多相同的数据。
3、解决办法,就是应用层调用CAN发送数据时,将数据填充到缓冲区,使能中断,但是不请求发送,因为使能中断,在中断里面发送,发送完毕后关闭中断。这里有两点需要注意:1是第一次的时候没有所谓的发送完成中断,所以程序开始要产生一个发送完成中断,以启动发送中断,第二就是为了使用中断发送,在发送中断函数里,要判断当前是否有数据发送,有的话可以清除中断标志,没有的话只能关闭中断,不能清除中断,否则下次据没法发送了。