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 個位組成。控制字段的第一位為標識擴展(Identifier Extension,IDE)位,該位應是顯性狀態來指定標準幀。標識擴展位的下一位為零保留位(RB0),CAN 協議將其定義為顯性位。控制字段的其余4 位為數據長度碼(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 位控制字段??刂谱侄吻皟晌粸楸A粑?#xff0c;必須定義為顯性位。其余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初探的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        