CAN HAL 配置遇到的問題記錄:
(1)CAN在調用之前,進行了自測試. (非中斷模式),如果改爲中斷模式,只能正常接收數據一次。
(2)濾波器的設置:
參考:STM32之CAN —CAN ID過濾器分析
再談STM32的CAN過濾器-bxCAN的過濾器的4種工作模式以及使用方法總結
stm32之CAN發送、接收詳解
(3)
bsp_CAN.C
/* 包含頭文件 ----------------------------------------------------------------*/
#include "CAN/bsp_CAN.h"
/* 私有類型定義 --------------------------------------------------------------*/
/* 私有宏定義 ----------------------------------------------------------------*/
/* 私有變量 ------------------------------------------------------------------*/
CAN_HandleTypeDef hCAN;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
static void can_NVIC_Config(void);
extern CanRxMsgTypeDef TestRxMessage;
extern uint8_t Can_test_flag;
extern uint32_t BoardID;
static void can_Init(uint32_t CAN_MODE )
{
CAN_FilterConfTypeDef sFilterConfig;
/*CAN單元初始化*/
hCAN.Instance = CANx; /* CAN外設 */
hCAN.pTxMsg = &TxMessage;
hCAN.pRxMsg = &RxMessage;
hCAN.Init.Prescaler = 2;
hCAN.Init.Mode = CAN_MODE; /* 工作模式 */
hCAN.Init.SJW = CAN_SJW_1TQ; /* BTR-SJW 重新同步跳躍寬度 2個時間單元 */
hCAN.Init.BS1 = CAN_BS1_12TQ; /* BTR-TS1 時間段1 佔用了6個時間單元 */
hCAN.Init.BS2 = CAN_BS2_8TQ; /* BTR-TS1 時間段2 佔用了8個時間單元 */
hCAN.Init.TTCM = DISABLE; /* MCR-TTCM 關閉時間觸發通信模式使能 */
hCAN.Init.ABOM = DISABLE; /* MCR-ABOM 自動離線管理 */
hCAN.Init.AWUM = DISABLE; /* MCR-AWUM 使用自動喚醒模式 */
hCAN.Init.NART = DISABLE; /* MCR-NART 禁止報文自動重傳 DISABLE-自動重傳 */
hCAN.Init.RFLM = DISABLE; /* MCR-RFLM 接收FIFO 鎖定模式 DISABLE-溢出時新報文會覆蓋原有報文 */
hCAN.Init.TXFP = DISABLE; /* MCR-TXFP 發送FIFO優先級 DISABLE-優先級取決於報文標示符 */
HAL_CAN_Init(&hCAN);
/*CAN過濾器初始化*/
sFilterConfig.FilterNumber = 0; /* 過濾器組0 */
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; /* 工作在標識符屏蔽位模式 */
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; /* 過濾器位寬爲單個32位。*/
/* 使能報文標示符過濾器按照標示符的內容進行比對過濾,擴展ID不是如下的就拋棄掉,是的話,會存入FIFO0。 */
sFilterConfig.FilterIdHigh = ( BoardID<<5)&0xFFFF; /* 要過濾的ID高位 */
sFilterConfig.FilterIdLow = 0|CAN_ID_STD; /* 要過濾的ID低位 */
sFilterConfig.FilterMaskIdHigh = 0xFF80; /* 過濾器高16位每位必須匹配 */
sFilterConfig.FilterMaskIdLow = 0x0004; /* 過濾器低16位每位必須匹配 */
sFilterConfig.FilterFIFOAssignment = CAN_FIFO0; /* 過濾器被關聯到FIFO 0 */
sFilterConfig.FilterActivation = ENABLE; /* 使能過濾器 */
sFilterConfig.BankNumber = 14;
HAL_CAN_ConfigFilter(&hCAN, &sFilterConfig);
}
uint8_t CAN_LoopBack_Test (void)
{
uint16_t i=0;
HAL_StatusTypeDef Status;
/* 填充發送參數, 也可以再每次發送的時候填 */
hCAN.pTxMsg->StdId = BoardID;
hCAN.pTxMsg->RTR = CAN_RTR_DATA;
hCAN.pTxMsg->IDE = CAN_ID_STD;
hCAN.pTxMsg->DLC = 8;
hCAN.pTxMsg->Data[0]=0x00;
hCAN.pTxMsg->Data[1]=0x01;
hCAN.pTxMsg->Data[2]=0x02;
hCAN.pTxMsg->Data[3]=0x03;
hCAN.pTxMsg->Data[4]=0x04;
hCAN.pTxMsg->Data[5]=0x05;
hCAN.pTxMsg->Data[6]=0x06;
hCAN.pTxMsg->Data[7]=0x07;
do{
Status=HAL_CAN_Transmit(&hCAN,10);
} while( Status == HAL_BUSY);
if(Status != HAL_OK ) return 0;
do{
Status=HAL_CAN_Receive(&hCAN,CAN_FIFO0,100);
}while( Status == HAL_BUSY);
if(Status != HAL_OK ) return 0;
if (hCAN.pTxMsg->StdId !=hCAN.pRxMsg->StdId ){return 0; };
if (hCAN.pTxMsg->RTR !=hCAN.pRxMsg->RTR ){return 0; };
if (hCAN.pTxMsg->IDE !=hCAN.pRxMsg->IDE ){return 0; };
if (hCAN.pTxMsg->DLC !=hCAN.pRxMsg->DLC ){return 0; };
if (hCAN.pTxMsg->Data[0] !=hCAN.pRxMsg->Data[0] ){return 0; };
if (hCAN.pTxMsg->Data[1] !=hCAN.pRxMsg->Data[1] ){return 0; };
if (hCAN.pTxMsg->Data[2] !=hCAN.pRxMsg->Data[2] ){return 0; };
if (hCAN.pTxMsg->Data[3] !=hCAN.pRxMsg->Data[3] ){return 0; };
if (hCAN.pTxMsg->Data[4] !=hCAN.pRxMsg->Data[4] ){return 0; };
if (hCAN.pTxMsg->Data[5] !=hCAN.pRxMsg->Data[5] ){return 0; };
if (hCAN.pTxMsg->Data[6] !=hCAN.pRxMsg->Data[6] ){return 0; };
if (hCAN.pTxMsg->Data[7] !=hCAN.pRxMsg->Data[7] ){return 0; };
return 1;
}
/* 擴展變量 ------------------------------------------------------------------*/
/* 私有函數原形 --------------------------------------------------------------*/
/* 函數體 --------------------------------------------------------------------*/
/**
* 函數功能: CAN外設配置
* 輸入參數: 無
* 返 回 值: 無
* 說 明: 無
*/
void MX_CAN_Init(void)
{
printf("-> CAN Loopback test ! \r\n");
can_Init(CAN_MODE_SILENT_LOOPBACK ); //默認迴環模式
while( CAN_LoopBack_Test() ==0 )
{
printf("-> CAN Loopback test err ! \r\n");
};
printf(" -> Test OK ! \r\n");
can_Init(CAN_MODE_NORMAL );
can_NVIC_Config();
}
/*
*********************************************************************************************************
* 函 數 名: can_NVIC_Config
* 功能說明: 配置CAN中斷
* 形 參:無
* 返 回 值: 無
*********************************************************************************************************
*/
static void can_NVIC_Config(void)
{
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(CANx_RX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CANx_RX_IRQn);
}
/**
* 函數功能: 外設初始化
* 輸入參數: 無
* 返 回 值: 無
* 說 明: 無
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hcan->Instance==CANx)
{
/* Peripheral clock enable */
CANx_CLK_ENABLE();
CANx_GPIO_CLK_ENABLE();
/**CAN GPIO Configuration
PB8 ------> CAN_RX
PB9 ------> CAN_TX
*/
GPIO_InitStruct.Pin = CANx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate=GPIO_AF9_CAN1;
HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CANx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate=GPIO_AF9_CAN1;
HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);
}
}
/**
* 函數功能: CAN外設反初始化
* 輸入參數: 無
* 返 回 值: 無
* 說 明: 無
*/
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
{
if(hcan->Instance==CANx)
{
CANx_FORCE_RESET();
CANx_RELEASE_RESET();
/**CAN GPIO Configuration
PB8 ------> CAN_RX
PB9 ------> CAN_TX
*/
HAL_GPIO_DeInit(CANx_TX_GPIO_PORT, CANx_TX_PIN);
HAL_GPIO_DeInit(CANx_RX_GPIO_PORT, CANx_RX_PIN);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(CANx_RX_IRQn);
}
}
bsp_CAN.h
#ifndef __BSP_CAN_H__
#define __BSP_CAN_H__
/* 包含頭文件 ----------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include <stdio.h>
/* 類型定義 ------------------------------------------------------------------*/
/* 宏定義 --------------------------------------------------------------------*/
#define CANx CAN1
#define CANx_CLK_ENABLE() __HAL_RCC_CAN1_CLK_ENABLE()
#define CANx_FORCE_RESET() __HAL_RCC_CAN1_FORCE_RESET()
#define CANx_RELEASE_RESET() __HAL_RCC_CAN1_RELEASE_RESET()
#define CANx_GPIO_CLK_ENABLE() {__HAL_RCC_GPIOB_CLK_ENABLE();}
#define CANx_TX_GPIO_PORT GPIOB
#define CANx_TX_PIN GPIO_PIN_9
#define CANx_RX_GPIO_PORT GPIOB
#define CANx_RX_PIN GPIO_PIN_8
#define CANx_RX_IRQn CAN1_RX0_IRQn
/* 擴展變量 ------------------------------------------------------------------*/
extern CAN_HandleTypeDef hCAN;
/* 函數聲明 ------------------------------------------------------------------*/
void MX_CAN_Init(void);
#endif /* __BSP_CAN_H__ */