can1--can初探
updating
http://download.csdn.net/detail/songqqnew/4399668
http://download.csdn.net/detail/songqqnew/4399670
http://download.csdn.net/detail/songqqnew/4399684
mcp2515寄存器一覽
幾個寄存器名稱及地址
TXBnCTRL——發送緩沖器n 控制寄存器(地址:30h, 40h, 50h)
TXBnSIDH——發送緩沖器n 標準標識符高位(地址:31h, 41h, 51h)
TXBnSIDL——發送緩沖器n 標準標識符低位(地址:32h, 42h, 52h)
TXBnEID8——發送緩沖器n 擴展標識符高位(地址:33h, 43h, 53h)
TXBnEID0——發送緩沖器n 擴展標識符低位(地址:34h, 44h, 54h)
TXBnDLC——發送緩沖器n 數據長度碼(地址:35h, 45h, 55h)
TXBnDm——發送緩沖器n 數據字節m(地址:36h - 3Dh, 46h - 4Dh, 56h - 5Dh)
RXBnCTRL——接收緩沖器n 控制寄存器(地址:60h,70h)
RXBnSIDH——接收緩沖器n 標準標識符高位(地址:61h, 71h)
RXBnSIDL——接收緩沖器n 標準標識符低位(地址:62h, 72h)
RXBnEID8——接收緩沖器n 擴展標識符高位(地址:63h, 73h)
RXBnEID0——接收緩沖器n 擴展標識符低位(地址:64h, 74h)
RXBnDLC——接收緩沖器n 數據長度碼(地址:65h, 75h)
RXBnDM——接收緩沖器n 數據字段字節M(地址:66h - 6Dh, 76h - 7Dh)
spi接口操作mcp2515使用的命令
can物理信號
can信號使用差分電壓傳送,兩條信號線被稱為CAN_H和CAN_L。靜態時均是2.5v左右,此時狀態表示為邏輯“1”,也可以叫做隱性。用CAN_H比CAN_L高表示邏輯“0”,稱為顯性,此時通常電壓值為CAN_H=3.5V和CAN_L=1.5V。
1.標準幀結構--refer to mcp2515說明書
CAN 標準數據幀如圖所示。與其他所有幀一樣,幀以起始幀(SOF)位開始, SOF 為顯性狀態,允許所有節點的硬同步。SOF之后是仲裁字段,由12個位組成,分別為11個標識位和一個遠程發送請求(Remote Transmission?Request,RTR)位。RTR 位用于區分報文是數據幀(RTR 位為顯性狀態)還是遠程幀(RTR 位為隱性狀態)。仲裁字段之后是控制字段,由6 個位組成??刂谱侄蔚牡谝晃粸闃俗R擴展(Identifier Extension,IDE)位,該位應是顯性狀態來指定標準幀。標識擴展位的下一位為零保留位(RB0),CAN 協議將其定義為顯性位??刂谱侄蔚钠溆? 位為數據長度碼(Data Length Code,DLC),用來指定報文中包含的數據字節數(0 到8 字節)。控制字段之后為數據字段,包含要發送的任何數據字節。數據字段長度由上述DLC 定義(0 到8 字節)。數據字段之后為循環冗余校驗(CRC)字段,用來檢測報文傳輸錯誤。CRC 字段包含一個15 位的CRC 序列,之后是隱性的CRC 定界位。最后一個字段是確認字段(ACK),由2 個位組成。在確認時隙(ACK Slot)位執行期間,發送節點發出一個隱性位。任何收到無錯誤幀的節點會發回一個顯性位(無論該節點是否配置為接受該報文與否)來確認幀收到無誤。確認字段以隱性確認定界符結束,該定界符可能不允許被改寫為顯性位。
標準幀和mcp2515的寄存器對應關系一覽:詳見mcp2515手冊
對于接受操作:
對于發送操作:
2.擴展幀結構
在擴展CAN 數據幀中(如圖2-2 所示),緊隨SOF 位的是32 位的仲裁字段。仲裁字段的前11 位為29 位標識符的最高有效位(Most Significant bit,MSb)(基本lD) 。緊隨這11 位的是替代遠程請求(Substitute?Remote Request, SRR)位,定義為隱性狀態。SRR位之后是lDE 位,該位為隱性狀態時表示這是擴展的CAN 幀。應該注意的是,如果發送完擴展幀標識符的前11 位后,總線仲裁無果,而此時其中一個等待仲裁的節點發出標準CAN 數據幀(11 位標識符),那么,由于節點發出了顯性lDE 位而使標準CAN 幀贏得總線仲裁。另外,擴展CAN 幀的SRR 位應為隱性,以允許正在發送標準CAN 遠程幀的節點發出顯性RTR 位。SRR和lDE位之后是標識符的其余18位(擴展lD)及一
個遠程發送請求位。為使標準幀和擴展幀都能在共享網絡上發送,應將29位擴展報文標識符拆成高11 位和低18 位兩部分。拆分后可確保lDE 位在標準數據幀和擴展數據幀中的位置保持一致。仲裁字段之后是6 位控制字段。控制字段前兩位為保留位,必須定義為顯性位。其余4 位為DLC,用來指定報文中包含的數據字節數。擴展數據幀的其他部分(數據字段、CRC 字段、確認字段、幀結尾和間斷)與標準數據幀的結構相同(見第2.1 節“標準數據幀”)。
擴展幀和mcp2515的寄存器對應關系一覽:詳見mcp2515手冊
對于接受操作:接收時,若得到IDE位為1,表示接收到的是擴展幀。
對于發送操作:發送時,置IDE位為1,表示發送的是擴展幀。
can的無地址編碼與485的有地址編碼
比如485的modbus幀
發出:01 03 00 00 00 03 05 CB ?? ? ? ? ? ? ? ? //01站地址,03功能號,00 00 起始地址,00 03要讀的數據個數
接收:01 03 06 00 00 00 01 00 02 F1 74??? //01站地址,03功能號,06返回的字節數,00 00 00 01 00 02 對應6個字節3個數
(03讀取保持寄存器,保持寄存器為可讀可寫,http://blog.csdn.net/songqqnew/article/details/6938039)
主機發出的幀中的第一個字節是目的地址即01。
所有的設備都可以收到這個幀,只有地址是01的設備才需要響應這個幀,響應幀的第一個字節規定必須是本機地址即01.
而can的幀
/** Controller Area Network Identifier structure** bit 0-28 : CAN identifier (11/29 bit)* bit 29 : error frame flag (0 = data frame, 1 = error frame)* bit 30 : remote transmission request flag (1 = rtr frame)* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)*/ typedef __u32 canid_t;/*** struct can_frame - basic CAN frame structure* @can_id: the CAN ID of the frame and CAN_*_FLAG flags, see above.* @can_dlc: the data length field of the CAN frame* @data: the CAN frame payload.*/ struct can_frame {canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */__u8 can_dlc; /* data length code: 0 .. 8 */__u8 data[8] __attribute__((aligned(8))); };
主機向總線發出如下幀,幀的內容是hello,并設置標示符為123,這樣總線上123號站應當對此幀有反應。
由于都可以作為主機而主動向總線發數據,所以就沒必要向modbus那樣非得要主機發命令讓從機干嘛從機才可以干嘛。
比如1號站有可用數據了,那么他直接將數據發送can總線,希望得到哪個站的處理就設置標示符為哪個站比如為123。在硬件層和驅動層,can總線上的所有非123號站也會收到站1發來的數據。但只有123號站應該對其處理--在應用層可以設置是只將驅動接收到的指定can標示符的can_frame上報給應用層,如下
??? struct can_filter rfilter;//過濾 ?
??? rfilter.can_id?? = 0x123;//選擇監聽can_frame中標示符是0x123的can幀,不過濾則監聽所有。
??? rfilter.can_mask = CAN_SFF_MASK; ?
??? setsockopt(m_can, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));?
站123處理完了之后,根據需要要么回復一下(要不不回復),回復的時候也會使用相同的幀結構,回復的時候身份就變成了主機??磥韈an總線上流動的數據都是某個站主動發出的。而modbus總線上僅可以有一個主機,通信必須采用一問一答的形式,由于主機問的問題有好幾種,所以從機針對每個問題回復的modbus幀也些差別。不像can的幀,僅有一種(僅討論標注幀),每幀最大限制為8個字節。
DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[1]=24//TXBnSIDH--? DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[2]=60//TXBnSIDL--? DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[3]=1//TXBnEID8--? DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[4]=23//TXBnEID0--? DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[5]=5//TXBnDLC DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[6]=68//TXBnD0 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[7]=65//TXBnD1 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[8]=6c//TXBnD2 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[9]=6c//TXBnD3 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[10]=6f//TXBnD4 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[11]=0//TXBnD5 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[12]=0//TXBnD6 DBG(drivers/net/can/mcp251x.c, mcp251x_hw_tx(), 482): buf[13]=0//TXBnD7
can的多主與485的單主
Can總線本身就是為多主系統設計的,可以在一根總線上有多個主站。而485本身只能是單主的,只能通過其他的辦法(如令牌)來變成一個多主系統。這是由硬件特點決定的。485總線上如果有兩個節點同時都發送了信號,總線狀態無法不確定的,即發送的報文可能已經被破壞了,為了解決這個問題,在某一時刻只能有一個站點主動發起通訊,其他站點都可看成從站。而Can的對比的主要優點在于可以實現非破壞仲裁,為此在硬件上進行了特殊設計,從總線可以看成是一個線與的結構,如果兩個或以上節點發送信號電平不一致,總線電平顯示為顯性,這意味著至少有一個站點的報文沒有被破壞。為了仲裁節點在發送信號的同時還在監測總線,如果發送和檢測不一致則認為本節點發送報文已經被破壞。節點會自動退出發送狀態等待發送結束以后開始下一次發送。而報文始終正確的站點最終取得總線控制權。
有一個問題哦,can是多主的總線,spi是單主的總線,那么6410的spi和mcp2515連起來之后怎么就變成了多主了呢?以圖說明
每個6410下只掛一個mcp2515。
6410的cs引腳配置為輸出,用于選中從機。
當6410.1有數據要發送時,6410.1作為spi主機向mcp2515.1發送數據,然后mcp2515.1作為主機,向總線發送數據。
當mcp2515.2從can總線上接收到數據時,它會向6410.2產生一個中斷,此時6410.2會作為spi主機從mcp2515.2中主動讀到數據。
看來是多虧了那根中斷線,使得6410都可以作為spi主機主動從與之相連的mcp2515讀數據。
can的錯誤檢測
轉載于:https://www.cnblogs.com/-song/archive/2012/05/10/3331873.html
總結
以上是生活随笔為你收集整理的can1--can初探的全部內容,希望文章能夠幫你解決所遇到的問題。