STM32 F4 CAN HAL 配置

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__ */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章