CAN实验:STM32+HAL+CubeMX
1 步骤:
1.1 配置
/* USER CODE BEGIN 1 */ CAN_TxHeaderTypeDef hCAN2_TxHeader; //CAN1发送消息 CAN_RxHeaderTypeDef hCAN2_RxHeader; //CAN1接收消息 CAN_FilterTypeDef hCAN2_Filter; //CAN1滤波器 /******************************************************************************* * Function Name : vApp_CAN_TxHeader_Init * Description : 初始化发送帧头句柄 * Input : pHeader 发送帧头指针 StdId 标识符 ExtId 扩展标识符 IDE 0:标准帧 1:拓展帧 RTR 0:数据帧 1:远程帧 DLC 数据长度 * Output : None * Return : None ****************************************************************************** */ void vApp_CAN_TxHeader_Init(CAN_TxHeaderTypeDef * pHeader, uint32_t StdId, uint32_t ExtId, uint32_t IDE, uint32_t RTR, uint32_t DLC) { pHeader->StdId = StdId; //11位 标准标识符 pHeader->ExtId = ExtId; //29位 扩展标识符 pHeader->IDE = IDE; //1位 0:标准帧 1:拓展帧 pHeader->RTR = RTR; //1位 0:数据帧 1:远程帧 pHeader->DLC = DLC; //4位 发送的数据的长度 pHeader->TransmitGlobalTime = ENABLE; } /******************************************************************************* * Function Name : vApp_CAN_Filter_Init * Description : 初始化滤波器 * Input : pFilter 滤波器句柄,初始化全部值 IdHigh, IdLow, MaskIdHigh, MaskIdLow, FIFOAssignment, Bank, Mode, Scale, Activation, SlaveStartFilterBank * Output : None * Return : None ****************************************************************************** */ void vApp_CAN_Filter_Init(CAN_FilterTypeDef * pFilter, uint32_t IdHigh, uint32_t IdLow, uint32_t MaskIdHigh, uint32_t MaskIdLow, uint32_t FIFOAssignment, uint32_t Bank, uint32_t Mode, uint32_t Scale, uint32_t Activation, uint32_t SlaveStartFilterBank) { pFilter->FilterIdHigh = 0; pFilter->FilterIdLow = 0; pFilter->FilterMaskIdHigh = 0; pFilter->FilterMaskIdLow = 0; pFilter->FilterFIFOAssignment = CAN_FILTER_FIFO0; pFilter->FilterBank = 0; pFilter->FilterMode = CAN_FILTERMODE_IDMASK; pFilter->FilterScale = CAN_FILTERSCALE_32BIT; pFilter->FilterActivation = ENABLE; pFilter->SlaveStartFilterBank = 0; } /******************************************************************************* * Function Name : vApp_CAN_Configuration * Description : CAN初始化配置,配置发送帧头,配置滤波器 * Input : (...) * Output : None * Return : None ****************************************************************************** */ void vApp_CAN_Configuration(CAN_TxHeaderTypeDef * pTxHeader, CAN_FilterTypeDef * pFilter, uint32_t StdId, uint32_t ExtId, uint32_t IDE, uint32_t RTR, uint32_t DLC, uint32_t IdHigh, uint32_t IdLow, uint32_t MaskIdHigh, uint32_t MaskIdLow, uint32_t FIFOAssignment, uint32_t Bank, uint32_t Mode, uint32_t Scale, uint32_t Activation, uint32_t SlaveStartFilterBank) { /*-1- 初始化TxHeader句柄 ----------------------------------------*/ vApp_CAN_TxHeader_Init(pTxHeader, StdId, ExtId, IDE, RTR, DLC); /*-2- 初始化滤波器句柄 ------------------------------------------*/ vApp_CAN_Filter_Init(pFilter, IdHigh, IdLow, MaskIdHigh, MaskIdLow, FIFOAssignment, Bank, Mode, Scale, Activation, SlaveStartFilterBank); HAL_CAN_ConfigFilter(&hcan2, pFilter); /*-3- 启动CAN ---------------------------------------------------*/ while(HAL_CAN_Start(&hcan2) != HAL_OK ) { printf("\nCAN_Start Failed!!"); HAL_Delay(100); } printf("\nCAN_Start Success!!"); /*-4- 使能中断通知 ----------------------------------------------*/ HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING); } /******************************************************************************** Function Name : vApp_User_CAN_Configuration* Description : 初始化CAN(用户修改)* Input : None* Output : None* Return : None ****************************************************************************** */ void vApp_User_CAN_Configuration(void) { /*----------------- CAN初始化配置 --------------------------*/ vApp_CAN_Configuration(&hCAN2_TxHeader, &hCAN2_Filter, /* TxHeader 句柄配置 */ /* StdId ExtId IDE RTR DLC */ 0x12, 0, CAN_ID_STD, CAN_RTR_DATA, 8, /* Filter 句柄配置 */ /* IdHigh(验证码) IdLow MaskIdHigh(掩码) MaskIdLow FIFOAssignment Bank Mode Scale Activation SlaveStartFilterBank */ 0, 0, 0, 0, CAN_FILTER_FIFO0, 0, CAN_FILTERMODE_IDMASK, CAN_FILTERSCALE_32BIT, ENABLE, 0); } /******************************************************************************* * Function Name : vApp_CAN_TxMessage * Description : 邮箱发送数据 * Input : hcan pTxHeader 发送帧头 aData 数据段 DLC 数据段长度 * Output : None * Return : None ****************************************************************************** */ void vApp_CAN_TxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef * pTxHeader, uint8_t aData[], uint8_t DLC) { uint32_t Tx_MailBox; /*-1- 配置数据段长度 ----------------------------------------*/ pTxHeader->DLC = DLC; /*-2- 发送aData ---------------------------------------------*/ while(HAL_CAN_AddTxMessage(hcan, pTxHeader, aData, &Tx_MailBox) != HAL_OK) { printf("TxMsg Failed!!"); HAL_Delay(100); } printf("\nSend Tx Message Success!!Tx_Mail:%d", Tx_MailBox); } /******************************************************************************** Function Name : vApp_User_CAN1_TxMessage* Description : 使用CAN1发送数据* Input : None* Output : None* Return : None ****************************************************************************** */ void vApp_User_CAN2_TxMessage(uint8_t aTxData[], uint8_t DLC) { vApp_CAN_TxMessage(&hcan2, &hCAN2_TxHeader, aTxData, DLC); } /******************************************************************************* * Function Name : HAL_CAN_RxFifo0MsgPendingCallback * Description : 消息接收回调函数 * Input : hcan * Output : None * Return : None ****************************************************************************** */ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { uint8_t aRxData[8], i; if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &hCAN2_RxHeader, aRxData) == HAL_OK) { printf("\nGet Rx Message Success!!\nData:"); for(i=0; i<8; i++) printf("%d", aRxData[i]); } }
1.2 main函数
int main(void) { /* USER CODE BEGIN 1 */ uint8_t TxData[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_CAN2_Init(); /* USER CODE BEGIN 2 */ vApp_User_CAN_Configuration(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ vApp_User_CAN2_TxMessage(TxData, 8); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
2 使用CubeMX配置: