CAN基本知識(shí):CAN協(xié)議的特點(diǎn):
本文引用地址:http://www.biyoush.com/article/201611/322581.htm1、多主機(jī)控制。在總線空閑時(shí),所有單元都可以發(fā)送消息,若兩個(gè)以上同時(shí)開始發(fā)送消息,根據(jù)標(biāo)識(shí)符來(lái)決定優(yōu)先級(jí)。優(yōu)先級(jí)高的先發(fā)送。
2、系統(tǒng)的若軟性。與總線相連的單元沒(méi)有類似地址的信息。因此在總線上增加單元時(shí),應(yīng)用層程序基本不需要改變。
3、通信速度快,通信距離遠(yuǎn)。最高1Mbps(距離小于40M),最遠(yuǎn)可達(dá)10Km(速率低于5Kbps)。
4、具有錯(cuò)誤檢測(cè)、錯(cuò)誤通知和錯(cuò)誤恢復(fù)功能。所有單元都可以檢測(cè)錯(cuò)誤,檢測(cè)出錯(cuò)誤的單元會(huì)立即同時(shí)通知其他所有單元,正在發(fā)送消息的單元一旦檢測(cè)出錯(cuò)誤,會(huì)強(qiáng)制結(jié)束當(dāng)前的發(fā)送。前置結(jié)束發(fā)送的單元會(huì)不斷反復(fù)地重新發(fā)送該消息直到發(fā)送成功。
5、故障封閉功能。CAN可以判斷出錯(cuò)誤的類型是總線上的數(shù)據(jù)錯(cuò)誤還是持續(xù)的數(shù)據(jù)錯(cuò)誤。由此功能,當(dāng)總線上發(fā)生持續(xù)數(shù)據(jù)錯(cuò)誤時(shí),可以將引起此故障的單元從總線上隔離出去。
6、連接節(jié)點(diǎn)多。CAN總線是可同時(shí)連接多個(gè)單元的總線??蛇B接的單元總數(shù)理論上是沒(méi)有限制的。單實(shí)際上受到時(shí)間延遲和電氣負(fù)載的限制。降低通信速度,可連接單元增加。反之,反之。
STM32的CAN時(shí)間特性(有關(guān)波特率):
與CAN2.0B的協(xié)議內(nèi)容相比,STM32的CAN時(shí)間特性稍微有些區(qū)別。STM32把傳播時(shí)間段和相位緩沖段1合并了,因此STM32的CAN一個(gè)位只有3段:同步段(SYNC_SEG)、時(shí)間段1(BS1)和時(shí)間段2(BS2)。STM的BS1段可以設(shè)置為1-16個(gè)時(shí)間單元,剛好等于傳播時(shí)間段和相位緩沖段1之和。
波特率=1/正常的位時(shí)間
正常的位時(shí)間=1×tq+tbs1+tbs2
其中:tbps1=tq×(TS1[3:0]+1)
tbps2=tq×(TS2[3:0]+1)
tq=(BRP[9:0]+1)×tpclk
tq是一個(gè)時(shí)間單元
tpclk是APB時(shí)鐘的時(shí)間周期
因此,我們只需要知道BS1和BS2的設(shè)置,以及APB1的時(shí)鐘頻率(一般為36MHz),就可以方便的計(jì)算出波特率。比如設(shè)置TS1=6,TS2=7和BRP=4,在APB1頻率為36MHz的條件下,即可得到CAN通信的波特率=36000/[(7+8+1)*5]=450Kbps。
要用到的寄存器:
主控制寄存器CAN_MCR:控制進(jìn)退初始化,發(fā)送FIFO優(yōu)先級(jí)。
時(shí)序寄存器CAN_BTR:用來(lái)設(shè)置分頻、Tbps、Tbs2以及Tsjw等非常重要的參數(shù),直接決定了CAN的波特率。另外還可以設(shè)置工作模式(靜默模式、環(huán)回模式)等。
發(fā)送郵箱標(biāo)識(shí)符寄存器CAN_TIxR:該寄存器用來(lái)設(shè)置標(biāo)識(shí)符(包括擴(kuò)展標(biāo)識(shí)符),另外還可以設(shè)置幀類型。
發(fā)送郵箱數(shù)據(jù)長(zhǎng)度和時(shí)間戳寄存器CAN_TDTxR:用來(lái)設(shè)置數(shù)據(jù)長(zhǎng)度。
發(fā)送郵箱低字節(jié)數(shù)據(jù)寄存器CAN_TDLxR:用來(lái)存儲(chǔ)將要發(fā)送的數(shù)據(jù),只能存儲(chǔ)低4個(gè)字節(jié)。
發(fā)送郵箱高字節(jié)數(shù)據(jù)寄存器CAN_TDHxR:用來(lái)存儲(chǔ)將要發(fā)送的高4個(gè)字節(jié)。
接收FIFO郵箱標(biāo)識(shí)符寄存器CAN_RIxR:該寄存器用來(lái)保存接收到的報(bào)文標(biāo)識(shí)符等信息,通過(guò)讀該寄存器獲取相關(guān)信息。
接收FIFO郵箱數(shù)據(jù)長(zhǎng)度和時(shí)間戳寄存器CAN_RDTxR;接收FIFO郵箱低字節(jié)數(shù)據(jù)寄存器CAN_RDLxR;接收FIFO郵箱高字節(jié)數(shù)據(jù)寄存器CAN_RDHxR,同發(fā)送。
過(guò)濾器模式寄存器CAN_FM1R:設(shè)置各濾波器組的工作模式,對(duì)28個(gè)濾波器組的工作模式,都可以通過(guò)該寄存器設(shè)置,不過(guò)該寄存器必須在濾波器處于初始化模式下才可以設(shè)置。
過(guò)濾器位寬寄存器CAN_FS1R:用于設(shè)置各濾波器組的位寬。其他同上。
上述兩個(gè)寄存器用來(lái)設(shè)置過(guò)濾器。
如FSCx=1,F(xiàn)BMx=0:那么其中第x個(gè)寄存器組就被設(shè)置為1個(gè)32位過(guò)濾器-標(biāo)識(shí)符屏蔽,此時(shí)本濾波器組可以設(shè)置成1個(gè)過(guò)濾器。(見參考手冊(cè)P432)
如FSCx=1,F(xiàn)BMx=1:那么其中第x個(gè)寄存器組就被設(shè)置為2個(gè)32位過(guò)濾器-標(biāo)識(shí)符列表,此時(shí)本濾波器組可以設(shè)置成2個(gè)過(guò)濾器。
如FSCx=0,F(xiàn)BMx=1:那么其中第x個(gè)寄存器組就被設(shè)置為2個(gè)16位過(guò)濾器-標(biāo)識(shí)符屏蔽,此時(shí)本濾波器組可以設(shè)置成2個(gè)過(guò)濾器。
如FSCx=0,F(xiàn)BMx=0:那么其中第x個(gè)寄存器組就被設(shè)置為4個(gè)16位過(guò)濾器-標(biāo)識(shí)符列表,此時(shí)本濾波器組可以設(shè)置成4個(gè)過(guò)濾器。
28個(gè)過(guò)濾器組可以被設(shè)置為遠(yuǎn)大于28個(gè)過(guò)濾器數(shù)目。
每個(gè)FIFO各自對(duì)其關(guān)聯(lián)的過(guò)濾器進(jìn)行編號(hào)。過(guò)濾器組關(guān)聯(lián)設(shè)置通過(guò)寄存器CAN_FFA1R即過(guò)濾器FIFO關(guān)聯(lián)寄存器來(lái)設(shè)置。
過(guò)濾器激活寄存器CAN_FA1R:該寄存器來(lái)控制過(guò)濾器的激活與否。1開啟0關(guān)閉。
過(guò)濾器組i的寄存器x CAN_FiRx:用來(lái)存放過(guò)濾參數(shù)。
STM32 CAN總線初始化步驟:
1、配置相關(guān)引腳的復(fù)用功能,使能CAN時(shí)鐘。
使能CAN時(shí)鐘,通過(guò)APB1ENR的第25位來(lái)設(shè)置。其次要設(shè)置CAN的相關(guān)引腳為復(fù)用輸出,設(shè)置為上拉輸入(CAN_RX),設(shè)置為復(fù)用輸出(CAN_TX),并使能PA口的時(shí)鐘。
2、設(shè)置CAN工作模式及波特率等。
先設(shè)置CAN_MCR寄存器的INRQ位,讓CAN進(jìn)入初始化模式,然后設(shè)置CAN_MCR的其他相關(guān)控制位,再通過(guò)CAN_BTR設(shè)置波特率和工作模式(正常模式/環(huán)回模式)等信息。最后設(shè)置INRQ為0,退出初始化模式。
3、設(shè)置濾波器。
設(shè)置CAN_FMR的FINIT位,讓過(guò)濾器組工作在初始化模式下,然后設(shè)置濾波器組0的工作模式以及標(biāo)識(shí)符ID和屏蔽為。最后激活濾波器。并退出濾波器初始化模式。如果用到中斷,還要配置中斷模式。
具體的:
如何初始化CAN:
1、使能相關(guān)時(shí)鐘(PORTA時(shí)鐘,CAN時(shí)鐘),初始化引腳RX和TX。
2、設(shè)置CAN_MCR,退出睡眠模式,同時(shí)設(shè)置參數(shù)?;臼撬形磺辶恪jP(guān)于睡眠模式,CAN在復(fù)位后都是進(jìn)入睡眠模式,當(dāng)然也可以設(shè)置自動(dòng)喚醒模式等。
3、請(qǐng)求CAN進(jìn)入初始化模式,對(duì)CAN_MSR的位0置1。等待進(jìn)入初始化,檢驗(yàn)MCR位0 INAK的值,當(dāng)真正變?yōu)?的時(shí)候,在進(jìn)行下一步。因?yàn)檫@個(gè)過(guò)程可能不是瞬間完成的,如果當(dāng)前有CAN活動(dòng),就會(huì)等到本次活動(dòng)結(jié)束后再進(jìn)入初始化模式,硬件對(duì)INAK位置1。
4、設(shè)置CAN_MCR的各位,位2-位7。設(shè)置位時(shí)序寄存器CAN_BTR的各位,在這里可以設(shè)置靜默模式、環(huán)回模式、波特率。
5、請(qǐng)求CAN退出初始化模式。設(shè)置MCR的位0.等待完全退出初始化模式,通過(guò)檢驗(yàn)MSR的位。
6、初始化過(guò)濾器(初始化寄存器不是在CAN初始化模式下進(jìn)行的,而是過(guò)濾器組工作到初始化模式)。設(shè)置過(guò)濾器主控寄存器CAN_FMR的位0,使過(guò)濾器組工作在初始化模式。
7、設(shè)置過(guò)濾器激活寄存器CAN_FA1R來(lái)禁用相應(yīng)的過(guò)濾器,因?yàn)橹挥袑?duì)相應(yīng)位清零或者對(duì)CAN_FME的FINIT位設(shè)置位1,才能修改相應(yīng)的過(guò)濾器寄存器CAN_FiRx。
8、設(shè)置過(guò)濾器模式CAN_FM1R(標(biāo)識(shí)符屏蔽模式or標(biāo)識(shí)符列表模式);設(shè)置過(guò)濾器位寬寄存器CAN_FS1R(1個(gè)32位的過(guò)濾器or2個(gè)16位的過(guò)濾器);設(shè)置過(guò)濾器FIFO關(guān)聯(lián)寄存器CAN_FFA1R(過(guò)濾器關(guān)聯(lián)到FIFO0還是FIFO1當(dāng)中)。
9、填寫過(guò)濾器標(biāo)識(shí)和屏蔽。通過(guò)設(shè)置寄存器CAN_FiR1和CAN_FiR2來(lái)設(shè)置標(biāo)識(shí)(ID)和屏蔽(MASK)。
10、激活過(guò)濾器,CAN_FA1R位0設(shè)置為1。
11、過(guò)濾器進(jìn)入正常工作模式,CAN_FMR位0清零
如何發(fā)送一個(gè)報(bào)文:
1、判斷三個(gè)郵箱中哪個(gè)為空(CAN_TSR的位26位27位28),哪個(gè)為空用哪個(gè)?如果沒(méi)有空郵箱,則退出本次發(fā)送過(guò)程。
2、清除發(fā)送郵箱標(biāo)識(shí)符寄存器(因?yàn)橐顚懶碌臉?biāo)識(shí)符)。
3、設(shè)置發(fā)送郵箱的標(biāo)識(shí)符寄存器CAN_TIxR。
4、設(shè)置發(fā)送郵箱的數(shù)據(jù)長(zhǎng)度和時(shí)間戳寄存器CAN_TDTxR。
5、填寫要發(fā)送的數(shù)據(jù),即設(shè)置發(fā)送郵箱高低字節(jié)數(shù)據(jù)寄存器CAN_TDHxR和CAN_TDLxR。
6、對(duì)標(biāo)識(shí)符寄存器CAN_TIxR的位0即TXRQ位置1,來(lái)請(qǐng)求發(fā)送郵箱的數(shù)據(jù)。當(dāng)數(shù)據(jù)發(fā)送完成后,硬件對(duì)其清零。
7、查詢發(fā)送狀態(tài),通過(guò)查詢發(fā)送狀態(tài)寄存器CAN_TSR?;静樵?nèi)齻€(gè)狀態(tài)參數(shù)。位0 RQCP1郵箱0(不一定是0,看使用的是哪個(gè)郵箱了)請(qǐng)求完成;位1 TXOK0郵箱0發(fā)送成功;位26發(fā)送郵箱0位為空,沒(méi)有等待發(fā)送的報(bào)文。當(dāng)這三項(xiàng)都成功后,返回發(fā)送成功。
如何接收一個(gè)報(bào)文:
1、查詢FIFO里面是否存在有效報(bào)文,查詢接收FIFO0寄存器CAN_RF0R的位1:0當(dāng)前接收FIFO中存放的報(bào)文數(shù)目。如果有數(shù)據(jù),下一步將數(shù)據(jù)讀出。
2、判斷標(biāo)識(shí)符類型,接收來(lái)的報(bào)文是采用標(biāo)準(zhǔn)標(biāo)識(shí)符還是擴(kuò)展標(biāo)識(shí)符。CAN_RIxR的位2 IDE。
3、根據(jù)不同類型的標(biāo)識(shí)符來(lái)做不同的操作。具體可查看CAN_RIxR的位31:3。擴(kuò)展標(biāo)識(shí)符低字節(jié)存在位20:3。擴(kuò)展標(biāo)識(shí)符或標(biāo)準(zhǔn)標(biāo)識(shí)符存在位31:21。擴(kuò)展標(biāo)識(shí)符39位,標(biāo)準(zhǔn)標(biāo)識(shí)符11位。
4、查詢CAN_RIxR的位1來(lái)判定是數(shù)據(jù)幀還是遠(yuǎn)程幀。
5、查詢CAN_RDTxR位3:0獲取數(shù)據(jù)幀的數(shù)據(jù)長(zhǎng)度。
6、讀取接收FIFO郵箱高低字節(jié)數(shù)據(jù)寄存器CAN_RDLxR和CAN_RDHxR。
7、釋放FIFO郵箱。CAN_RF0R的位5。
如何使CAN接收工作在中斷模式下:
1、通過(guò)寄存器CAN_IER來(lái)設(shè)置中斷使能,正常情況下使用位1,F(xiàn)MPIE0:FIFO0消息掛號(hào)中斷使能置1。
2、中斷分組
3、寫中斷處理函數(shù)(較自由)??梢酝ㄟ^(guò)設(shè)置中斷使能來(lái)屏蔽有寫中斷,如果中斷都打開的話就需要在中斷處理函數(shù)里面來(lái)進(jìn)行判斷處理。因?yàn)槊總€(gè)CAN只有4個(gè)主中斷,即發(fā)送中斷、接收FIFO0中斷、接收FIFO1中斷和SCE中斷。
評(píng)論