0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何設(shè)置CAN引腳功能?如何在中斷中獲取CAN數(shù)據(jù)?

冬至子 ? 來源:郝飛的俱俱 ? 作者:hf ? 2023-08-10 17:34 ? 次閱讀

MCU:MCU通過APB總線訪問CAN外設(shè)。② CAN外設(shè):掛載在MCU的APB總線上,實現(xiàn)基本協(xié)議CAN2.0A、擴展協(xié)議CAN2.0B、接收濾波器、發(fā)送優(yōu)先級及對CAN FD的支持等,并留出外設(shè)訪問接口給MCU,以便MCU控制。③ CAN收發(fā)器:看其收發(fā)器框圖,因僅包含CANH、CANL總線,所以TXD發(fā)出的CANH、CANL與RXD讀出的CANH、CANL是連接在一起的,因此CAN收發(fā)器TXD發(fā)送出來的總線信號會立即被轉(zhuǎn)換從RXD輸出給CAN接口(LBME環(huán)回模式使用此特性)

圖片

MCU通過APB總線訪問CAN外設(shè),通過配置相關(guān)寄存器配置CAN的運行環(huán)境,通過寫B(tài)UF及相關(guān)配置位發(fā)送CAN幀;通過輪詢某些狀態(tài)位或者中斷,讀取收到的BUF或者CAN外設(shè)目前處于的狀態(tài),并依據(jù)部分狀態(tài)作出相應(yīng)的動作;CAN收發(fā)器將CAN外設(shè)的CAN_TX高低電平信號轉(zhuǎn)換為CANH、CANL總線信號,并將接收到的CANH、CANL總線信號轉(zhuǎn)換為CAN外設(shè)的CAN_RX高低電平信號,該信號輸送給CAN外設(shè),CAN外設(shè)根據(jù)CAN接收濾波器的設(shè)置判斷是否接收該數(shù)據(jù)幀等等。

1、查看原理圖,看使用哪一個CAN接口。STB使用的引腳

圖片

#define CAN1_TX      (GPIO_PC15)  //pin 75
#define CAN1_RX      (GPIO_PC14)  //pin 74
#define CAN1_STB     (GPIO_PD5)   // pin9

2、進行初始化操作

CAN_InitHardwr();

定義兩個結(jié)構(gòu)體變量,CAN_Config和CAN_BaudrateConfig

  1. 初始化硬件接口
    GPIO_SetFunc(CAN1_TX, GPIO_FUNC_1);//設(shè)置CAN1引腳復(fù)用功能
     GPIO_SetFunc(CAN1_RX, GPIO_FUNC_1);
     GPIO_SetDir(CAN1_STB, GPIO_OUTPUT);//設(shè)置CAN1收發(fā)器控制為IO控制
     //GPIO_FUNC_1 參考數(shù)據(jù)手冊中“信號多路復(fù)用和引腳分配”,使用function 1功能
    
  2. 使能CAN收發(fā)器
    CAN1_TRASCVER_NML;//使能CAN收發(fā)器
    //#define CAN1_TRASCVER_NML   do{GPIO_ResetPinBits(CAN1_STB);}while(0)
    
  3. 設(shè)置波特率和采樣點進行配置
/*
   設(shè)置波特率為500K,采樣點為81.25%.
   tSeg1 = (S_SEG_1 + 2); tSeg2 = (S_SEG_2 + 1).
   BandRate  = (48M / (S_PRESC + 1) / ((S_SEG_1 + 2) + (S_SEG_2 + 1)))
   SamplePoint = (tSeg1 / (tSeg1 + tSeg2)).
   在已經(jīng)知道波特率與采樣點的情況下,經(jīng)過計算后:tSeg1 = 13,tSeg2 = 3.
    */
   canBandrateConfig.S_PRESC  = 5;//分頻后時鐘為8M.
   canBandrateConfig.S_SEG_1  = 11;
   canBandrateConfig.S_SEG_2  = 2;
   canBandrateConfig.S_SJW  = 2;//滿足S_SJW <= tSeg2即可.
  1. 過濾器設(shè)置:選擇哪一個過濾器、指定過濾模式、過濾的ID類型
    16個過濾器中,可隨意選擇使用哪個,并制定其過濾模式,制定其過濾ID的類型.
     如果一個過濾器只需要接收一個ID,直接可將其設(shè)置CODE模式,然后根據(jù)ID類型設(shè)置過濾類型.
     如果一個過濾器需要接收多個ID,將其設(shè)置為MASK模式,并根據(jù)這幾個ID的實際類型設(shè)置過濾ID類型,如果既有STD又有EXT,則應(yīng)選擇FILTER_IDE_STD_EXT_BOTH.
     此處加宏是為了更清楚的說明各種設(shè)置是否有效,在實際應(yīng)用中,可將各種組合放在一起使用.
     #if (RECV_FRM_KIND_SEL == ONLY_RECV_STD_FRM)
     CAN_SetFilterParam( 0, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_STD_ONLY, CAN1_RECV_DATA_ID1);//使用CODE模式只接收STD幀
     CAN_SetFilterParam( 1, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_STD_ONLY, CAN1_RECV_DATA_ID2);//使用CODE模式只接收STD幀
     #endif
     #if (RECV_FRM_KIND_SEL == ONLY_RECV_EXT_FRM)
     CAN_SetFilterParam( 0, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_EXT_ONLY, CAN1_RECV_DATA_ID11);//使用CODE模式只接收EXT幀
     CAN_SetFilterParam( 1, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_EXT_ONLY, CAN1_RECV_DATA_ID12);//使用CODE模式只接收EXT幀
     #endif
     #if (RECV_FRM_KIND_SEL == RECV_STD_EXT_BOTH_FRM)
     CAN_SetFilterParam( 0, 1, CAN_FILTER_MASK_MODE, FILTER_IDE_STD_EXT_BOTH, (CAN1_RECV_DATA_ID1 & CAN1_RECV_DATA_ID11));//使用MASK模式接收兩種幀
     CAN_SetFilterParam( 1, 1, CAN_FILTER_MASK_MODE, FILTER_IDE_STD_EXT_BOTH, (CAN1_RECV_DATA_ID2 & CAN1_RECV_DATA_ID12));//使用MASK模式接收兩種幀
     #endif
    
  2. CAN_SetFilterParam( 0, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_STD_ONLY, CAN1_RECV_DATA_ID1);//使用CODE模式只接收STD幀
* @prototype CAN_SetFilterParam(uint8_t filterNum, uint8_t filterEn, CAN_FilterMode_TypeDef filterMode, CAN_FilterMask_TypeDef filterMask, uint32_t ID)
  *
  * @param[in] filterNum:過濾器編碼,015可用.
  * @param[in] filterEn:過濾器使能狀態(tài),1使能,0禁能
  * @param[in] filterMode:CAN_FilterMode_TypeDef已定義.
  * @param[in] filterMask:參考CAN_FilterMask_TypeDef.
  * @param[in] ID
  * @return  void

參數(shù)說明:0:選用的過濾器編碼

1:1標識使能,0為禁止

CAN_FILTER_CODE_MODE:分code模式和mask模式,code只能接收一個ID,mask可以接收多個ID

FILTER_IDE_STD_ONLY:分標準幀、擴展幀、混合幀

ID:需要過濾的ID,表示這個ID可以通過,單片機可以接收到數(shù)據(jù)。

  1. 設(shè)置can配置
    canConfig.interruptEnable = TRUE;//使能中斷
     canConfig.TSSS = TRUE;//使用次發(fā)送緩沖區(qū)發(fā)送
     canConfig.canMode = CAN_MODE_NORMAL;
     canConfig.autoReset = TRUE;//CAN BUSOFF后,自動恢復(fù)
     canConfig.filterList = g_canFilterTab;//賦值過濾器設(shè)置list
    
  2. 設(shè)置回調(diào)函數(shù)CAN_SetEventCallBack(CAN1, CAN1_IRQnCallBack);
  3. /**
    * @prototype CAN1_IRQnCallBack(uint32_t event, uint32_t wparam, uint32_t lparam)
    *
    * @param[in] ...
    * @return  ...
    *
    * @brief    CAN1 module interrupt handler.
    *    CAN1中斷處理函數(shù).
    */
    int32_t CAN1_IRQnCallBack(uint32_t event, uint32_t wparam, uint32_t lparam)
    {
     if (event & CAN_EVENT_RECVMSG)
     {
      if (CAN_IsMsgInReceiveBuf((CAN_Type*)lparam))
            {
                CAN_MessageRead((CAN_Type*)lparam, &g_recvCANMsgInfo);
    
       g_recvedCANDataRdy = TRUE;
            }
     }
    
     return 1;
    }
    
  4. 調(diào)用庫函數(shù)CAN_Initialize()。

CAN_Initialize(CAN1, &canConfig, &canBandrateConfig);//程序引用

CAN_Initialize(CAN_Type *CANx, CAN_Config *config, const CAN_BaudrateConfig *baudrate)//函數(shù)原型

參數(shù)說明:

  • @param[in] CANx: CAN type pointer
  • @param[in] config: CAN config
  • @param[in] baudrate: CAN baud rate
  • @return 0: no error, 1: Initialize error
void CAN_InitHardwr(void)
{
 CAN_Config canConfig = {0};
 CAN_BaudrateConfig canBandrateConfig = {0};
 
 GPIO_SetFunc(CAN1_TX, GPIO_FUNC_1);//設(shè)置CAN1引腳復(fù)用功能
 GPIO_SetFunc(CAN1_RX, GPIO_FUNC_1);
 GPIO_SetDir(CAN1_STB, GPIO_OUTPUT);//設(shè)置CAN1收發(fā)器控制為IO控制
 CAN1_TRASCVER_NML;//使能CAN收發(fā)器
 
 /*
 設(shè)置波特率為500K,采樣點為81.25%.
 tSeg1 = (S_SEG_1 + 2); tSeg2 = (S_SEG_2 + 1).
 BandRate  = (48M / (S_PRESC + 1) / ((S_SEG_1 + 2) + (S_SEG_2 + 1)))
 SamplePoint = (tSeg1 / (tSeg1 + tSeg2)).
 在已經(jīng)知道波特率與采樣點的情況下,經(jīng)過計算后:tSeg1 = 13,tSeg2 = 3.
  */
 canBandrateConfig.S_PRESC  = 5;//分頻后時鐘為8M.
 canBandrateConfig.S_SEG_1  = 11;
 canBandrateConfig.S_SEG_2  = 2;
 canBandrateConfig.S_SJW  = 2;//滿足S_SJW <= tSeg2即可.
 
 /* 
 16個過濾器中,可隨意選擇使用哪個,并制定其過濾模式,制定其過濾ID的類型.
 如果一個過濾器只需要接收一個ID,直接可將其設(shè)置CODE模式,然后根據(jù)ID類型設(shè)置過濾類型.
 如果一個過濾器需要接收多個ID,將其設(shè)置為MASK模式,并根據(jù)這幾個ID的實際類型設(shè)置過濾ID類型,如果既有STD又有EXT,則應(yīng)選擇FILTER_IDE_STD_EXT_BOTH.
 
 此處加宏是為了更清楚的說明各種設(shè)置是否有效,在實際應(yīng)用中,可將各種組合放在一起使用.
  */
 #if (RECV_FRM_KIND_SEL == ONLY_RECV_STD_FRM)
 CAN_SetFilterParam( 0, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_STD_ONLY, CAN1_RECV_DATA_ID1);//使用CODE模式只接收STD幀
 CAN_SetFilterParam( 1, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_STD_ONLY, CAN1_RECV_DATA_ID2);//使用CODE模式只接收STD幀
 #endif
 #if (RECV_FRM_KIND_SEL == ONLY_RECV_EXT_FRM)
 CAN_SetFilterParam( 0, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_EXT_ONLY, CAN1_RECV_DATA_ID11);//使用CODE模式只接收EXT幀
 CAN_SetFilterParam( 1, 1, CAN_FILTER_CODE_MODE, FILTER_IDE_EXT_ONLY, CAN1_RECV_DATA_ID12);//使用CODE模式只接收EXT幀
 #endif
 #if (RECV_FRM_KIND_SEL == RECV_STD_EXT_BOTH_FRM)
 CAN_SetFilterParam( 0, 1, CAN_FILTER_MASK_MODE, FILTER_IDE_STD_EXT_BOTH, (CAN1_RECV_DATA_ID1 & CAN1_RECV_DATA_ID11));//使用MASK模式接收兩種幀
 CAN_SetFilterParam( 1, 1, CAN_FILTER_MASK_MODE, FILTER_IDE_STD_EXT_BOTH, (CAN1_RECV_DATA_ID2 & CAN1_RECV_DATA_ID12));//使用MASK模式接收兩種幀
 #endif
 
 canConfig.interruptEnable = TRUE;//使能中斷
 canConfig.TSSS = TRUE;//使用次發(fā)送緩沖區(qū)發(fā)送
 canConfig.canMode = CAN_MODE_NORMAL;
 canConfig.autoReset = TRUE;//CAN BUSOFF后,自動恢復(fù)
 canConfig.filterList = g_canFilterTab;//賦值過濾器設(shè)置list
 
 CAN_SetEventCallBack(CAN1, CAN1_IRQnCallBack);
 CAN_Initialize(CAN1, &canConfig, &canBandrateConfig);
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 濾波器
    +關(guān)注

    關(guān)注

    160

    文章

    7703

    瀏覽量

    177485
  • AMBA
    +關(guān)注

    關(guān)注

    0

    文章

    68

    瀏覽量

    14940
  • CAN收發(fā)器
    +關(guān)注

    關(guān)注

    2

    文章

    162

    瀏覽量

    25589
  • 串口中斷
    +關(guān)注

    關(guān)注

    0

    文章

    64

    瀏覽量

    13847
  • MCU控制器
    +關(guān)注

    關(guān)注

    0

    文章

    27

    瀏覽量

    6867
收藏 人收藏

    評論

    相關(guān)推薦

    CAN外設(shè)的接收過濾器設(shè)置

    一、背景 ????在實際應(yīng)用,CAN總線上的數(shù)據(jù),對于某些CAN節(jié)點來說,可能需要的數(shù)據(jù)并不多,希望收到的
    的頭像 發(fā)表于 08-24 09:03 ?1766次閱讀
    <b class='flag-5'>CAN</b>外設(shè)的接收過濾器<b class='flag-5'>設(shè)置</b>

    stm32 can 中斷

    FIFO0接收數(shù)據(jù)信息存入消息結(jié)構(gòu)體 if ((RxMessage.IDE == CAN_ID_STD)) //如果消息標識符的類型為標準幀模式 {for(i=0;iRF0R|=
    發(fā)表于 11-01 15:11

    請問CAN接收中斷DSP底層會怎么樣?

    請教:正常流程:CAN設(shè)置中斷接收方式,通過CAN調(diào)試助手,發(fā)送一幀數(shù)據(jù),產(chǎn)生一個CAN接收
    發(fā)表于 10-17 14:37

    基于STM32F103實現(xiàn)CAN數(shù)據(jù)收發(fā)的功能

    ?;趓t-thread,已經(jīng)有CAN的驅(qū)動框架,可以快速實現(xiàn)CAN數(shù)據(jù)的收發(fā)。這里基于STM32F103 實現(xiàn)CAN數(shù)據(jù)收發(fā)的
    發(fā)表于 08-19 07:20

    使用CAN1中斷接收數(shù)據(jù),無法接收到CAN數(shù)據(jù)是為什么?

    我是用CAN1中斷進行接收信息,在ch32v30x_it.c添加了中斷聲明void CAN1_RX1_IRQHandler(void) _
    發(fā)表于 06-24 11:21

    實現(xiàn)功能安全性冗余CAN參考設(shè)計

    描述該參考設(shè)計展示了如何在物理層實施冗余(并行)CAN 以實現(xiàn)功能安全性。其中包括兩個 SN65HVD257 CAN 收發(fā)器以及可確保兩個收發(fā)器收到相同
    發(fā)表于 09-23 07:09

    何在外設(shè)設(shè)置CAN實例啟用靈活數(shù)據(jù)速率復(fù)選框?

    我一直在使用S32SDK_S321XX_RTM_4.0.1 can_pal_s32k144示例。 在該示例,CAN 0 實例已在外設(shè)設(shè)置
    發(fā)表于 03-21 08:00

    CAN通信波特率設(shè)置

    CAN通信波特率設(shè)置 LM3S2000、LM3S5000、LM3S8000系列CPU內(nèi)部有1~3路CAN控制器,通過對CAN位定時寄存器CANBIT及
    發(fā)表于 04-06 18:00 ?24次下載

    stm32 can 無法進入中斷

    這個要改成和你的芯片對應(yīng)的值,不然就進不了can中斷。這個錯誤不會影響單片機其他功能,非常隱蔽。USE_STDPERIPH_DRIVER, STM32F10X_HD
    發(fā)表于 12-02 17:21 ?32次下載
    stm32 <b class='flag-5'>can</b> 無法進入<b class='flag-5'>中斷</b>

    STM32CubeMX生成CAN相關(guān)程序一(發(fā)送中斷與接收中斷

    目錄一、CubeMX配置1、時鐘設(shè)置2、CAN1設(shè)置1)引腳修改2)中斷使能3)波特率計算3、SYS設(shè)置
    發(fā)表于 12-04 18:21 ?24次下載
    STM32CubeMX生成<b class='flag-5'>CAN</b>相關(guān)程序一(發(fā)送<b class='flag-5'>中斷</b>與接收<b class='flag-5'>中斷</b>)

    STM32的CAN收發(fā)數(shù)據(jù)死在硬件錯誤中斷

    STM32的CAN收發(fā)數(shù)據(jù)死在硬件錯誤中斷使用uCosIII的消息隊列,當CAN接收到數(shù)據(jù),使用消息隊列給
    發(fā)表于 12-09 09:36 ?22次下載
    STM32的<b class='flag-5'>CAN</b>收發(fā)<b class='flag-5'>數(shù)據(jù)</b>死在硬件錯誤<b class='flag-5'>中斷</b>

    APM32F103RCT6_CAN_CAN無法進入中斷

    APM32F103RCT6_CAN_CAN無法進入中斷
    發(fā)表于 11-09 21:03 ?6次下載
    APM32F103RCT6_<b class='flag-5'>CAN_CAN</b>無法進入<b class='flag-5'>中斷</b>

    CAN總線學(xué)習(xí)筆記|CAN盒測試STM32的CAN中斷接收

    CAN基礎(chǔ)知識介紹文中介紹了CAN協(xié)議相關(guān)的基礎(chǔ)知識,以及STM32F4芯片的CAN控制器相關(guān)知識,下面將通過實例,利用STM32CubeMX圖形化配置工具,并配合CAN盒,來實現(xiàn)
    的頭像 發(fā)表于 01-16 17:17 ?4803次閱讀

    can總線中斷狀態(tài)什么意思呢?

    過程中斷處理機制。以下是關(guān)于CAN總線中斷狀態(tài)的詳細介紹。 CAN總線概述 1.1 CAN
    的頭像 發(fā)表于 06-16 10:21 ?1404次閱讀