【通讯协议备忘录】stm32的CAN外设

文章目录

帧结构

  • CAN的报文结构:

测试模式(静默/换回/环回静默):

  • 静默模式:
  • 环回模式:

  • 环回静默模式:

环回测试配置

  • 选好对应GPIO即可,APB1 36 Mhz, 500kbps:

过滤器的使用

  • 不配置过滤器亦可使用
  • 根据不同位长模式,每个过滤器组,32位模式可以配置一个屏蔽掩码或两个白名单列表,16位模式翻倍
  • 标准帧和扩展帧的ID长度分别为11比特和29比特,通过移位操作对齐其对应的高低位

测试参考用例

过滤器的初始化

  • cube不能配置过滤器,需要手动配置,直接添加到生成代码的自定义区即可
  • 初始化后需要手动打开CAN外设
  • 单机测试使用了环回模式
c 复制代码
static void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 4;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_9TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_8TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */
  //接收所有
	CAN_FilterTypeDef can_filterconfig;
	can_filterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
	can_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
	can_filterconfig.FilterIdHigh = 0;
	can_filterconfig.FilterIdLow = 0;
	can_filterconfig.FilterMaskIdHigh = 0;
	can_filterconfig.FilterMaskIdLow = 0;
	can_filterconfig.FilterBank = 0;
	can_filterconfig.FilterFIFOAssignment = CAN_FilterFIFO0;
	can_filterconfig.FilterActivation = CAN_FILTER_ENABLE;
	can_filterconfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&hcan, &can_filterconfig);
	
	HAL_CAN_Start(&hcan);
  /* USER CODE END CAN_Init 2 */
}

发送和接收

c 复制代码
uint8_t can_send_message(CAN_TxHeaderTypeDef TxHeader,uint32_t std_id, uint8_t aData[],uint16_t lengh)
{
  uint32_t TxMailBox = CAN_TX_MAILBOX0;
  uint8_t FreeTxMailBoxNum = 0;
 
  TxHeader.StdId = std_id; 			//id由IDE决定类型
  TxHeader.ExtId = 0; 				
  TxHeader.DLC = lengh;  			//数据长度
  TxHeader.IDE = CAN_ID_STD;   		//标准帧/扩展帧
  TxHeader.RTR = CAN_RTR_DATA; 		//数据帧
  TxHeader.TransmitGlobalTime = DISABLE;
 
  while(0 == FreeTxMailBoxNum)
  {
   FreeTxMailBoxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
  }
 
  if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, aData, &TxMailBox) != HAL_OK)
  {
    /* Transmission request Error */
    Error_Handler();
  }
 return 1;
}

uint8_t can_receive_message(uint8_t *buf)
{
	if(HAL_CAN_GetRxFifoFillLevel(&hcan,CAN_RX_FIFO0) == 0)
		return 0;
	
	HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &canRxType, buf);
	return canRxType.DLC;
}

中断

四个中断源分别对应cube的四个选项:

手动中断开启函数:

c 复制代码
	HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);

中断回调函数:

c 复制代码
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if(hcan->Instance == CAN1)
	{
		HAL_CAN_GetRxMessage(&hcan, CAN_FILTER_FIFO0,&canRxType,canRxbuf);
	}
}
相关推荐
星辰pid9 小时前
STM32实现四自由度机械臂(SG90舵机)多功能控制(软件篇freertos)
stm32·单片机·嵌入式硬件·机械臂
小殷学长16 小时前
【单片机毕业设计17-基于stm32c8t6的智能倒车监测系统】
stm32·单片机·课程设计
花落已飘19 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘19 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔19 小时前
STM32低功耗模式全面指南
css·stm32·css3
牵牛老人21 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
和风化雨1 天前
stm32的三种开发方式
stm32·单片机·嵌入式硬件
竹照煜_ysn1 天前
STM32
stm32·单片机·嵌入式硬件
金色光环1 天前
【Modbus学习笔记】stm32实现Modbus
笔记·stm32·学习
Ronin-Lotus1 天前
嵌入式硬件与应用篇---寄存器GPIO控制
stm32·单片机·嵌入式硬件·微处理器原理与应用