日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > SAM4E單片機之旅——19、CAN間通信

          SAM4E單片機之旅——19、CAN間通信

          作者: 時間:2017-04-19 來源:網(wǎng)絡 收藏

            協(xié)議具有良好的可靠性,在工業(yè)中應用廣泛。這次就先熟悉的基本功能。

          本文引用地址:http://yuyingmama.com.cn/article/201704/346810.htm

            開發(fā)板有兩個,每個CAN有8個信箱。這次內(nèi)容是從CAN0的信箱0發(fā)送數(shù)據(jù)到CAN1的信箱0。

            除本次使用的功能外,CAN還有遠程幀、強大的錯誤處理功能。

            一、電路

            CAN總線上的邏輯數(shù)值是用顯性電平和隱性電平表示的?!帮@性”的意思是指在同時傳輸顯性電平和隱性電平時,總線上呈現(xiàn)的是顯性電平。顯性電平表示邏輯“0”,隱性電平表示邏輯“1”。

            在使用CAN的過程中,需要使用一個CAN收發(fā)器進行電平的轉(zhuǎn)換與解釋。開發(fā)板使用的CAN收發(fā)器為SN65HVD234,其接線如下圖所示:

              

          clip_image002
          clip_image004

           

            其中CANTXx和CANRXx引腳可以復用為CAN的外設。而在使用該收發(fā)器時,需要將CANRXxEN驅(qū)動為高電平以啟用收發(fā)器的接收功能,將CANTXxRS驅(qū)動求低電平以啟用發(fā)送功能。

            在實驗的時候,需要將這兩個口(J13和J14)使用線纜連接起來。當連接完成而未通電時,可以測得CANH和CANL是短路狀態(tài)的。

            二、CAN網(wǎng)絡參數(shù)及波特率

            假設MCK為96 MHz,需要設置的CAN波特率為1000 Kbps。

            CAN的波特率的設置不是那么的直接。CAN定義了一個名為“原子時間(TQ)”的最小時間單位;然后把一個比特的傳輸過程分為若干階段(同步段、傳播時間段、相位緩沖端1、相位緩沖段2),每個階段的時間均是由TQ的數(shù)量表示。

          clip_image006

            SAM4中,時間TQ用“CAN系統(tǒng)時鐘(CSC)”表示。波特率相關(guān)的參數(shù)均通過CAN波特率寄存器(CAN_BR)設置。

            TQ(CSC)設置。組成每個位時間的TQ數(shù)量的范圍為8—25。為取整,這里將數(shù)量選擇為16。所以CAN系統(tǒng)時鐘的頻率為CAN波特率的16倍,即16 MHz。再所以需要將MCK進行6分頻。根據(jù)BRP字段的作用方法,需要將BRP字段設置為5。

            同時,可以計算出每個TQ的長度為62.5 ns。

            同步段固定為1 TQ。

            傳播時間端PROP_SEG需要根據(jù)硬件相關(guān)的信息確定,用于吸收網(wǎng)絡的物理(發(fā)送單元、總線、接收單元)延遲。該段的時間需要為總物理延遲的2倍。在芯片手冊的示例中,該延遲為190 ns。所以該段的時長需要設置為380 ns,即約6 TQ。將PROPAG字段設置為5即可達到目的。

            剩下的16-1-6=9 TQ,均用與相位緩沖段。在Atmel的CAN中,需要2 TQ確定總線的電平。因為采樣點位于相位緩沖段2的起始,所以它的長度不能少于2 TQ 。這里使兩個階段盡量等長,所以讓相位緩沖段1設置為4 TQ,段2設置為5 TQ。將PHASE1和PHASE2分別設置為3和4即可。

            再補償寬度。最小可配置為1 TQ,最多可配置為相位緩沖段1和4 TQ間的較小值。這里配置為4 TQ。將SJW段設置為3即可。

            具體設置代碼如下:

            const uint32_t can_br = CAN_BR_BRP(5)

             CAN_BR_PROPAG(5)

             CAN_BR_PHASE1(3)

             CAN_BR_PHASE2(4)

             CAN_BR_SJW(3)

             CAN_BR_SMP_ONCE;

            CAN0->CAN_BR = can_br;

            CAN1->CAN_BR = can_br;

            三、CAN初始化

            GPIO及PMC設置。注意將PE1和PE3驅(qū)動為高電平,PE0和PE2驅(qū)動為低電平。

            網(wǎng)絡參數(shù)設置。在啟用CAN之前,需要設置好網(wǎng)絡參數(shù)。

            啟用CAN。CAN使能后,需要和總線進行同步。在連續(xù)檢測到11個隱性位時,CAN進入喚醒狀態(tài),且WAKEUP位置位:

            CAN0->CAN_MR = CAN_MR_CANEN;

            CAN1->CAN_MR = CAN_MR_CANEN;

            while( ((CAN0->CAN_SR & CAN_SR_WAKEUP) == 0)

             ((CAN1->CAN_SR & CAN_SR_WAKEUP) == 0) );

            信箱設置。通過設置CAN_MMR的MOT字段即可設置信箱的類型。由于這個設置是立即生效的,所以在設置這個字段時,需要先(或同時)完成其他相關(guān)信息的設置。同時,在修改設置時,應該先關(guān)閉信箱。

            發(fā)送信箱需要先設置好的只有優(yōu)先級:

            #define TX_MB (CAN0->CAN_MB + 0)

            TX_MB->CAN_MMR = CAN_MMR_PRIOR(0)

             CAN_MMR_MOT_MB_TX;

            接收信箱需要先設置好ID相關(guān)的信息。簡單起見,這里只使用標準格式的幀,即只指定MIDvA部分,同時MIDE位指定為0(默認)。由于符合接收條件的ID設置為1個,即需要比較接收ID所有的位,所以將CAN_MAM的MIDvA字段全部置1。

            #define RX_MB (CAN1->CAN_MB + 0)

            #define CAN_COMM_ID 5

            RX_MB->CAN_MID = CAN_MID_MIDvA(CAN_COMM_ID);

            RX_MB->CAN_MAM = CAN_MAM_MIDvA(~(uint32_t)0);

            RX_MB->CAN_MMR = CAN_MMR_MOT_MB_RX;

            四、數(shù)據(jù)傳輸

            通過UART讀取一個數(shù)字:

            int num;

            scanf("%d", &num);

            通過信箱發(fā)送數(shù)據(jù)。

            假設int為4字節(jié),則通過CAN_MDL即可表示所需信息。發(fā)送時,在確定信箱可用后,需要指定好信息ID。然后向CAN_MCR寫入信息長度(用byte表示),同時寫入MTCR位以開始發(fā)送操作。最后,在發(fā)送完成后,CAN_MSR的MRDY位重新置位。

            // 等待信箱可用

            while(!(TX_MB->CAN_MSR & CAN_MSR_MRDY));

            TX_MB->CAN_MID = CAN_MID_MIDvA(CAN_COMM_ID); // ID

            TX_MB->CAN_MDL = num; // 低4字節(jié)數(shù)據(jù)

            TX_MB->CAN_MCR = CAN_MCR_MDLC(4) // 數(shù)據(jù)長度

            | CAN_MCR_MTCR; // 開始嘗試發(fā)送

            printf("-I- Sending message from TX mailbox...rn");

            // 等待發(fā)送完成

            while(!(TX_MB->CAN_MSR & CAN_MSR_MRDY));

            通過信箱接收數(shù)據(jù)。

            通過查詢CAN_MSR的MRDY位可以確定是否接收到了數(shù)據(jù),然后在CAN_MSR的MDLC字段可以確定信息長度。在完成數(shù)據(jù)接收后,需要向CAN_MCR寫入MTCR字段以完成本次接收,從而開始下一次信息接收工作。

            // 等待信息接收完成

            while(!(RX_MB->CAN_MSR & CAN_MSR_MRDY));

            // 檢查信息長度

            const int rec_len =

            (RX_MB->CAN_MSR & CAN_MSR_MDLC_Msk) >> CAN_MSR_MDLC_Pos;

            if (rec_len == 4) {

            // 讀取信息并打印

            printf("-I- Data read from RX mailbox: %d rn",

            (int)RX_MB->CAN_MDL);

            }

            // 開始下一次接收

            RX_MB->CAN_MCR = CAN_MCR_MTCR;



          關(guān)鍵詞: SAM4E CAN

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉