STM32
直播中

王健

8年用户 1021经验值
私信 关注
[问答]

基于CubeMX HAL库的CAN该如何去配置呢

基于CubeMX HAL库的CAN该如何去配置呢?使用时有哪些注意事项?

回帖(1)

袁声瑜

2021-10-22 10:53:02
  STM32F042 基于CubeMX HAL库CAN的配置
  首先说说使用时候的两个坑。
  (1)要使能Swap PA9/10 –》PA11/12,这个时候PA11和PA12引脚才能出现。
  
  (2)我第一步用的是回环模式。
  大致是这样的。
  While
  {
  SendCanMessage();
  }
  Can_interrupt
  {
  HAL_CAN_Receive_IT(hcan,CAN_FIFO0);
  }
  却发现只能中断一次不能返回了。
  原因,配置好CAN后状态为HAL_CAN_STATE_READY。
  设置为接收,状态为HAL_CAN_STATE_BUSY_RX0。
  接收到数据一般会在继续设置为接收。这样一直可以接收。
  发送时状态为:HAL_CAN_STATE_BUSY_TX。发送结束变为HAL_CAN_STATE_READY。
  那么我们想想,回环模式下的状态。
  HAL_CAN_STATE_READY。à设置为接收状态为HAL_CAN_STATE_BUSY_RX0
  发送数据 此次被中断,那么完成接收操作时候状态变成了(HAL_CAN_STATE_BUSY_TX)
  中断跳回来,发送完成状态变为HAL_CAN_STATE_READY。
  再次发数据的时候问题来了,这个时候已经不是接收状态了!
  
  也就是说中断里面收到数据再重新设置为接受状态这个操作被忽略了
  配置图:
  (1)配置IO
  
  (2)配置时钟
  
  (3)配置CAN 500K
  
  
  
  
  程序:
  #include “main.h”
  #include “stm32f0xx_hal.h”
  CAN_HandleTypeDef hcan;
  CAN_FilterConfTypeDef sFilterConfig;
  static CanTxMsgTypeDef TxMessage;
  static CanRxMsgTypeDef RxMessage;
  void SystemClock_Config(void);
  static void MX_GPIO_Init(void);
  static void MX_CAN_Init(void);
  void Configure_Filter(void)
  {
  sFilterConfig.FilterNumber = 0; //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//滤波器位宽为单个32位
  sFilterConfig.FilterIdHigh =(((unsigned int)0x1314《《3)&0xFFFF0000)》》16; //要过滤的ID高位
  sFilterConfig.FilterIdLow = (((unsigned int)0x1314《《3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;//要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh = 0xffff;
  sFilterConfig.FilterMaskIdLow = 0xffff;
  sFilterConfig.FilterFIFOAssignment =CAN_FILTER_FIFO0;//过滤器被关联到FIFO0;
  sFilterConfig.FilterActivation = ENABLE;//使能过滤器
  //sFilterConfig.BankNumber = 14;
  HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
  }
  void SendData(void)
  {
  /* USER CODE BEGIN 2 */
  hcan.pTxMsg = &TxMessage;
  hcan.pRxMsg = &RxMessage;
  hcan.pTxMsg-》StdId = 0;//0x1314;
  hcan.pTxMsg-》ExtId= 0x1314;
  hcan.pTxMsg-》RTR = CAN_RTR_DATA;
  hcan.pTxMsg-》IDE = CAN_ID_EXT;
  hcan.pTxMsg-》DLC = 8;
  hcan.pTxMsg-》Data[0] = ‘C’;
  hcan.pTxMsg-》Data[1] = ‘A’;
  hcan.pTxMsg-》Data[2] = ‘N’;
  hcan.pTxMsg-》Data[3] = ‘ ’;
  hcan.pTxMsg-》Data[4] = ‘T’;
  hcan.pTxMsg-》Data[5] = ‘e’;
  hcan.pTxMsg-》Data[6] = ‘s’;
  hcan.pTxMsg-》Data[7] = ‘t’;
  if(HAL_CAN_Transmit(&hcan, 100) != HAL_OK)
  {
  }
  }
  void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  {
  HAL_CAN_Receive_IT(hcan,CAN_FIFO0);//开启中断接收
  }
  int main(void)
  {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_CAN_Init();
  Configure_Filter();
  HAL_CAN_Receive_IT(&hcan,CAN_FIFO0);
  SendData();
  while (1)
  {
  HAL_Delay(1000);
  HAL_CAN_Receive_IT(&hcan,CAN_FIFO0);//这个重新设置为接收,算是仅仅供测试使用,为bug;
  SendData();
  }
  }
  其中滤波器需要配置,不然无法中断。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分