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配置: