轉(zhuǎn)自:http://yiyutingmeng.blog.163.com/blog/static/124258578201191584629146/ 我在之前的一篇博客日志中,寫(xiě)過(guò)關(guān)于CAN發(fā)送功能如何使用,但是當(dāng)時(shí)由于時(shí)間匆忙,趕項(xiàng)目,按照對(duì)USART中斷發(fā)送的理解,在數(shù)據(jù)成功發(fā)送出去的情況下,寫(xiě)了那篇誤人子弟的日志,在這里向大家道歉,實(shí)在不好意思,現(xiàn)在我重新闡述下CAN中斷發(fā)送原理。 1、USART發(fā)送中斷與CAN發(fā)送中斷的區(qū)別 USART發(fā)送中斷,是因?yàn)榘l(fā)送緩沖區(qū)為空,CAN發(fā)送中斷的中斷源是成功(或者abort)發(fā)送一次,正是這種區(qū)別誤導(dǎo)了我。 2、我之前的CAN中斷發(fā)送的處理方法是,將數(shù)據(jù)填充到發(fā)送緩沖區(qū),由CAN中斷提取進(jìn)行發(fā)送,為了啟動(dòng)CAN的發(fā)送,我寫(xiě)了一句話(huà)CAN->sTxMailBox[0].TIR |= 1;就是啟動(dòng)發(fā)送,我以為在這以后CAN執(zhí)行的動(dòng)作是:產(chǎn)生中斷,將數(shù)據(jù)從發(fā)送緩沖區(qū)提取,發(fā)送,進(jìn)入完成中斷,判斷有無(wú)數(shù)據(jù),沒(méi)有就關(guān)閉中斷,否則繼續(xù)發(fā)送。但是CAN實(shí)際執(zhí)行的動(dòng)作是:發(fā)送,進(jìn)入發(fā)送完成中斷,提取數(shù)據(jù),發(fā)送,進(jìn)入完成中斷,判斷有無(wú)數(shù)據(jù),沒(méi)有就關(guān)閉中斷,否則繼續(xù)發(fā)送。由此可見(jiàn),CAN實(shí)際上是多發(fā)送了一次數(shù)據(jù),這個(gè)數(shù)據(jù)就是當(dāng)前CAN寄存器里面的數(shù)據(jù),而這次發(fā)送,應(yīng)用層和CAN中斷程序里都沒(méi)有參與,所以是不被發(fā)現(xiàn)的,這也據(jù)解釋了為什么對(duì)方收到的數(shù)據(jù)比我發(fā)送的數(shù)據(jù)多,在A發(fā)送大量數(shù)據(jù)的時(shí)候,B做應(yīng)答,但是每次都請(qǐng)求發(fā)送,由于速度快,B每次實(shí)際發(fā)送了同樣的數(shù)據(jù)給A,A所以收到 很多相同的數(shù)據(jù)。 3、解決辦法,就是應(yīng)用層調(diào)用CAN發(fā)送數(shù)據(jù)時(shí),將數(shù)據(jù)填充到緩沖區(qū),使能中斷,但是不請(qǐng)求發(fā)送,因?yàn)槭鼓苤袛?,在中斷里面發(fā)送,發(fā)送完畢后關(guān)閉中斷。這里有兩點(diǎn)需要注意:1是第一次的時(shí)候沒(méi)有所謂的發(fā)送完成中斷,所以程序開(kāi)始要產(chǎn)生一個(gè)發(fā)送完成中斷,以啟動(dòng)發(fā)送中斷,第二就是為了使用中斷發(fā)送,在發(fā)送中斷函數(shù)里,要判斷當(dāng)前是否有數(shù)據(jù)發(fā)送,有的話(huà)可以清除中斷標(biāo)志,沒(méi)有的話(huà)只能關(guān)閉中斷,不能清除中斷,否則下次據(jù)沒(méi)法發(fā)送了。 |
|