STM32F10xx CAN BUS相關庫文件"stm32f10x_can.c"內的庫函數解析


一、背景:
        還是繼續CAN通信,要節省開發時間,使用庫函數可大大降低開發周期,並且還能確保寄存器的配置幾
    乎是萬無一失,所以,在此就STM32F10xx的CAN操作庫函數的使用做個簡析。
        STM32有庫函數這件事,對軟件開發人員來說是極其利好的,對庫函數有褒有貶,說不好的,無非就是
    庫函數會占用一些額外Ram,並且不利於新手對於這款單片機更深層次的理解等等。我倒覺得,不應當有這
    些顧慮,首先,庫函數那都是由一些非常牛,並且對該型MCU極其了解的廠方工作人員編寫,不去說萬無一
    失,但也是絕對按照標准來的好東西;其次,開發最重要的既是時間,先利用庫函數實現快速開發,如若需
    要深層次定制或者更改,再來對其進行研究,這樣就可以節省時間去完成別人還未做過的事情,然后自己努
    力去變成一個為別人提供庫函數的人 :) ;至於新手,若需要知道如何正確使用庫函數,必然會去研究手冊
    上那些東西。所以,推薦有庫函數則優先使用庫函數。貌似跑題了 - -!  繼續,開始正文。

二、正文:
    1void CAN_DeInit(CAN_TypeDef* CANx)
       // 操作APB1外設復位寄存器。對CAN進行復位操作。
       // 在STM32F10xx中,CAN的時鍾由APB1分頻提供。
    
    2、uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)    
       // 根據CAN_InitStruct結構體(詳見以下),對CAN進行初始化操作。
       typedef struct
       {
           // CAN_Mode(Loop back mode)
           /* 0: 禁止環回模式。
            * 1:允許環回模式。
            */
           uint8_t CAN_Mode;
    
           // 以下4個參數,決定了CAN的波特率(具體如何配置,網上有計算工具)
           uint16_t CAN_Prescaler;
           uint8_t CAN_SJW;
           uint8_t CAN_BS1;
           uint8_t CAN_BS2;
    
           // TTCM(Time Triggered communication mode)
           /* 在該模式下,CAN硬件的內部定時器被激活,並且被用於產生(發送與接收郵箱的)時間戳,
            * 分別存儲在CAN_RDTxR/CAN_TDTxR寄存器中。內部定時器在每個CAN位時間(見22.7.7節)累加。
            * 內部定時器在接收和發送的幀起始位的采樣點位置被采樣,並生成時間戳。
            */
           FunctionalState CAN_TTCM;
    
           // ABOM(Automatic Bus-off managerment)
           /* 0:軟件對CAN_MCR寄存器的INRQ位置"1"隨后清"0"后,一旦硬件檢測到128次11位連續的隱形位,
            *   則退出離線狀態。
            * 1:硬件檢測到128次11位連續的隱形位,則自動退出離線狀態。
            */
           FunctionalState CAN_ABOM;
    
           // AWUM (Automatic wakeup mode)
           /* 0:由軟件清除CAN_MCR的"SLEEP"位后,喚醒睡眠模式。
            * 1:檢測到報文,由硬件自動喚醒,且自動清零"SLEEP""SLAK"
            */
           FunctionalState CAN_AWUM;
    
           // NART(No Automatic retransmission)
           /* 0:按照CAN標准,CAN硬件在發送報文失敗后會一直重新發送直至發送成功。
            * 1:CAN報文只發送一次。不管發送結果如何。
            */
           FunctionalState CAN_NART;                                         
           
           // RFLM (Receive FIFO Locked mode)
           /* 0:接收溢出后,FIFO未被鎖定,即報文會被新報文覆蓋。
            * 1:接收溢出后,FIFO被鎖定,即新報文會被丟棄。
            */
           FunctionalState CAN_RFLM;
           
           // TXFP(Transmit FIFO priority)
           /* 0:優先級由報文的標識符來決定。
            * 1:優先級由發送請求的順序來決定。
            */
           FunctionalState CAN_TXFP;
    
           // FunctionalState-----------------------------------------------------| 
       } CAN_InitTypeDef;                                                         |        
                                                                                  |    
       typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;<------------|        
       
    3void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)
       // 將所有的CAN設置均設置為初始值。
    
    4void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
       // 根據結構體CAN_FilterInitStruct(詳見如下)對CAN濾波進行初始化操作。
       typedef struct
       {
           // CANFxR1 高16位
           uint16_t CAN_FilterIdHigh;
           // CANFxR1 低16位
           uint16_t CAN_FilterIdLow;
           // CANFxR2 高16位
           uint16_t CAN_FilterMaskIdHigh;
           // CANFxR2 低16位
           uint16_t CAN_FilterMaskIdLow;
    
           // 對應哪一個過濾器
           uint8_t CAN_FilterNumber;
    
           // 對應的CAN_FilterNumber過濾器模式選擇(FM1R)
           /* 過濾器組(14組)的2個32位寄存器工作在標識符屏蔽位模式。
            * 過濾器組(14組)的2個32位寄存器工作在標識符列表模式。
            */
           uint8_t CAN_FilterMode;
    
           // 對應的CAN_FilterNumber過濾器位寬設置(CAN_FS1R)
           /* CAN_FilterScale_16bit: 兩個16位過濾器
            * CAN_FilterScale_32bit: 單個32位過濾器
            */
           uint8_t CAN_FilterScale;
    
           // 報文被過濾后,存放的哪個FIFO中。(CAN_FFA1R)
           // 每個FIFO可以存放3條報文。
           /* CAN_Filter_FIFO0: 過濾器被關聯到了FIFO0
            * CAN_Filter_FIFO1: 過濾器被關聯到了FIFO1
            */
           uint16_t CAN_FilterFIFOAssignment;
    
           // 是否使能對應的CAN_FilterNumber濾波器
           FunctionalState CAN_FilterActivation;
       } CAN_FilterInitTypeDef;
    
    5void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
        /* 調試凍結,即在調試時,CAN有兩種工作模式
         *   -->照常工作
         *   -->凍結其收發,但仍可對FIFO進行讀寫。
         * 操作寄存器為"CAN_MCR"的"DBF"位(Debug Freeze)。
         */
    
    6void CAN_SlaveStartBank(uint8_t CAN_BankNumber) 
       /* 內部對CAN過濾器主控制器(CAN_FMR)進行操作。
        * 功能為規定第二組CAN2的過濾器組
        * 由於只有互聯型產品才有CAN2,所有該函數只用在互聯型產品中。
        */
    
    7void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState)
        /* 是否使用時間觸發模式。NewState為Enable或者Disable。
         * 如果使用時間觸發模式,則時間戳值自動填充在發送的每條CAN信息的6,7字節中。
         */
    
    8、uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
       /* 該函數會自動選擇空的郵箱進行發送。返回值為郵箱號。
        * 若所有郵箱均不為空,則返回值為"CAN_TxStatus_NoMailBox"。
        * CAN發送信息函數。根據結構體TxMessage(定義如下)來發送CAN信息。
        */
       typedef struct
       {
           uint32_t StdId; // 標准幀標識符 
           uint32_t ExtId; // 擴展幀標識符
           uint8_t IDE;    // 標准幀還是擴展幀
           uint8_t RTR;    // 數據幀還是遠程幀
           uint8_t DLC;    // 數據字節長度(0~8)
           uint8_t Data[8];// 數據 
       } CanTxMsg;
        
    9、uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
       // 檢查對應郵箱號的狀態:發送成功/失敗/掛起。
       // 對應操作的寄存器為發送寄存器"CAN_TSR"
    
    10void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
        // 取消對應發送郵箱號的發送請求。
    
    11void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
        // 從FIFO0或者FIFO1接收CAN信息。並保存在結構體RxMessage中(詳見如下)。 
        // 該庫函數在讀完CAN信息后,會執行釋放FIFO的動作
        typedef struct
        {
            uint32_t StdId;  // 標准幀標識符 
            uint32_t ExtId;  // 擴展幀標識符
            uint8_t IDE;     // 標准幀還是擴展幀
            uint8_t RTR;     // 數據幀還是遠程幀
            uint8_t DLC;     // 數據字節長度(0~8)
            uint8_t Data[8]; // 數據 
            uint8_t FMI;     // 一個16位的值,表明該條信息由哪個濾波器給過濾的
        } CanRxMsg;
    
    12void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
        // 釋放接收FIFO,CAN_FIFO0 或者 CAN_FIFO1。
    
    13、uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
        // 檢測對應的FIFO內報文條數。 
        // 對應寄存器為"CAN_RF0R","CAN_RF1R"。
    
    14、uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode)
        /* 選擇CAN的工作模式。
         *   --> CAN_OperatingMode_Initialization
* --> CAN_OperatingMode_Normal
* --> CAN_OperatingMode_Sleep * 返回值為CAN_ModeStatus_Success/CAN_ModeStatus_Failed
*/ 15、uint8_t CAN_Sleep(CAN_TypeDef* CANx) /* CAN進入休眠模式。 * 返回值為CAN_Sleep_Ok/CAN_Sleep_Faild */ 16、uint8_t CAN_WakeUp(CAN_TypeDef* CANx) /* 喚醒對應的CAN。 * 返回值的值為CAN_WakeUp_Ok/CAN_WakeUp_Failed */ 17、uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx) // 讀取CAN上次錯誤的錯誤狀態。 /* CAN_ERRORCODE_NoErr 沒有錯誤 * CAN_ERRORCODE_StuffErr 位填充錯誤 * CAN_ERRORCODE_FormErr 格式錯誤 * CAN_ERRORCODE_ACKErr 確認錯誤 * CAN_ERRORCODE_BitRecessiveErr 隱性位錯誤 * CAN_ERRORCODE_BitDominantErr 顯性位錯誤 * CAN_ERRORCODE_CRCErr CRC錯誤 * CAN_ERRORCODE_SoftwareSetErr 軟件自行設置的錯誤 */ /* 注意:這個函數在CAN_IT_LEC中斷后需要立馬讀出保存, * 否則清零后,該值一並被清零。 */ 18、uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx) // 返回CAN接收錯誤寄存器的值。 19、uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx) // 返回CAN發送錯誤寄存器的值。 //------------------------------------------------------------------------------ /* * CAN_IT對應的每一位的代表一個中斷FLAG { * CAN_IT_TME : 發送郵箱空中斷 * CAN_IT_FMP0 : FIFO0消息掛號中斷 * CAN_IT_FF0 : FIFO0消息滿中斷 * CAN_IT_FOV0 : FIFO0消息溢出中斷 * CAN_IT_FMP1 : FIFO1消息掛號中斷 * CAN_IT_FF1 : FIFO1消息滿中斷 * CAN_IT_FOV1 : FIFO1消息溢出中斷 * CAN_IT_EWG : 錯誤警告中斷 * CAN_IT_EPV : 錯誤被動中斷 * CAN_IT_BOF : 離線中斷 * CAN_IT_LEC : 上次錯誤號中斷 * CAN_IT_ERR : 錯誤中斷使能 * CAN_IT_WKU : 喚醒中斷使能 * CAN_IT_SLK : 睡眠中斷使能 * } */ 20void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState) /* 使能CAN相關中斷,NewState為Enable或者Disable。 * CAN_IT為以上所有FLAG進行"或"操作以后的值。 */ 21、ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT) /* 傳入CAN_IT的具體某一位FLAG,獲取其是否處於中斷狀態,用在中斷內。 * 返回值是 SET (有中斷)/ RESET(沒有中斷) */ 22static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) /* 為"21"函數"static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t * It_Bit)"的子函數。 */ 23void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) // 清除對應中斷的標志。 //------------------------------------------------------------------------------ 24、FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG) /* 此函數乍看一下與函數"CAN_GetITStatus"的功能一致,均是檢測中斷狀態。其實不然。 * 函數"CAN_GetITStatus"是檢測當前的中斷狀態。 * 此函數是檢查中斷清零后,新的中斷狀態。 */ /* 檢測各類CAN狀態flag是否被set或者reset。 * CAN_FLAG_EWG : 錯誤警告中斷 * CAN_FLAG_EPV : 錯誤被動中斷 * CAN_FLAG_BOF : 離線中斷 * CAN_FLAG_RQCP0 : 郵箱0請求完成 * CAN_FLAG_RQCP1 : 郵箱1請求完成 * CAN_FLAG_RQCP2 : 郵箱2請求完成 * CAN_FLAG_FMP1 : FIFO1消息掛號中斷 * CAN_FLAG_FF1 : FIFO1消息滿中斷 * CAN_FLAG_FOV1 : FIFO1消息溢出中斷 * CAN_FLAG_FMP0 : FIFO0消息掛號中斷 * CAN_FLAG_FF0 : FIFO0消息滿中斷 * CAN_FLAG_FOV0 : FIFO0消息溢出中斷 * CAN_FLAG_WKU : 喚醒中斷使能 * CAN_FLAG_SLAK : 睡眠中斷使能 * CAN_FLAG_LEC : 上次錯誤號中斷 */ 25void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) // 清除各類CAN狀態flag。 至此,記錄完畢。 記錄時間:2016年9月13日 記錄地點:深圳WZ

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM