PIC16位單片機CAN(4)CAN發(fā)送報文詳解
CAN的幀格式太多了不再說明??梢宰约壕W(wǎng)上下載看看幀結構。這里只說一點,最長的幀是擴展數(shù)據(jù)幀。計算如下:
1sof + 29id + 1ide + 1rtr + 1srr + 2r + 4dlc + 8*8data+ 16crc + 2ack + 7eof =128bit
1:由于選用的單片機有一個增強型CAN也就是ECAN因此我們必須使用DMA了,原因看下圖:
數(shù)據(jù)手冊有這么一句話:ECAN 報文緩沖區(qū)位于器件 RAM 中。它們不是 ECAN SFR。用戶應用程序必須直接寫入為 ECAN報文緩沖區(qū)配置的器件 RAM 區(qū)。緩沖區(qū)的位置和大小由用戶應用程序定義。
因此我們必須看看DMA是怎么回事了。在眾多的DMA配置中莫過于“存儲器地址初始化”最讓人糾結了。這東西還的可能看編譯器的指令。。。。東西太多實在是不能一一列舉了。我們只看看DMA緩沖區(qū)位置和大小的配置吧,下面的聲明寫在main函數(shù)之前就行。其中的語句都是什么意思這得看編譯器了。這里的大概意思就是設置緩沖區(qū)的大小和對其方式!
__eds__ ECAN1MSGBUF ecan1msgBuf __attribute__((eds,aligned(ECAN1_MSG_BUF_LENGTH*16)));
其中ECAN1MSGBUF是自己定義的類型 是unsigned int [32][8] 也就是32個緩沖區(qū),每個緩沖區(qū)大小是8字。
我們根據(jù)寄存器設置把緩沖區(qū)0(大小是8個字)設置為發(fā)送緩沖區(qū),那么就是ecan1msgBuf[0][0]到ecan1msgBuf[0][7]就是發(fā)送緩沖區(qū)了。把請求發(fā)送的標志位至1就可以發(fā)送了。
下面的代碼是在DMA配置中寫的,作用就是設置DMA緩沖區(qū)的位置。
DMA0STAL = __builtin_edsoffset(ecan1msgBuf);
DMA0STAH = 0x0000;
2:DMA還有很多設置,比較簡單就不再說了。下面看看CAN的一些注意事項:
CAN的數(shù)據(jù)幀分為標準格式和擴展格式,雖然我們發(fā)送的是標準格式,但是我們還是得寫上EID。什么意思呢?看看下面的代碼
ecan1msgBuf[buf][0] = word0; //SID<10:0>+RTR+IDE 11+1+1=13位
ecan1msgBuf[buf][1] = word1;//EID<17:6>
ecan1msgBuf[buf][2] = ((ecan1msgBuf[buf][2] & 0xFFF0) + dataLength) ;//EID<5:0>+RTR+RB1+RB0+DLC 6+1+1+1+4
無論是不是擴展格式都必須發(fā)送上面的值 3個字 只是數(shù)據(jù)不同而已。如果是標準格式那么
ecan1msgBuf[buf][0]就是SID<10:0>+RTR(0)+IDE(0) 如FFFC SID是0b1111 1111 111
ecan1msgBuf[buf][1]就是EID<17:6> 0b0000 0000 0000
ecan1msgBuf[buf][2]就是EID<5:0>0b0000 00 +RTR 0b0+RB1 0b0+RB0 0b0+DLC 0b1000(數(shù)據(jù)長度8字節(jié))
ecan1msgBuf[buf][3] = data1;//真正的數(shù)據(jù)段data1=0x1111 16位
ecan1msgBuf[buf][4] = data2;//data2=0x2222 16位
ecan1msgBuf[buf][5] = data3;//data3=0x3333 16位
ecan1msgBuf[buf][6] = data4;//data4=0x4444 16位 共64位 8個字節(jié)!?。?!CAN的數(shù)據(jù)段最多8字節(jié)
代碼太多就不上傳了,寄存器的配置也不難。不知道的可以看看官方的例程。例程可以再單片機的說明頁下載也可以在代碼示例中找相近的單片機示例代碼。
示例代碼下載頁面鏈接:http://www.microchip.com/TechDoc.aspx?type=CodeExamples
評論