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