【通讯协议备忘录】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);
	}
}
相关推荐
单片机仿真设计5 小时前
【proteus仿真】基于 STM32 的林区环境监控系统设计
stm32·单片机·proteus
笨笨饿7 小时前
#138_解决Codex要五次回复的问题
linux·stm32·单片机·嵌入式硬件·mcu·物联网·嵌入式实时数据库
云泽8088 小时前
STM32 USART 详解(七):超时设置、非阻塞发送与 ReadLine 实现
stm32·单片机·嵌入式硬件
一条破秋裤9 小时前
24_MPU6050结构参数与寄存器基础
stm32·嵌入式硬件·学习
..Dauntless..11 小时前
【stm32】GPIO(下篇)——统一编址、源码理解和输入模式
stm32·单片机·嵌入式硬件
云边有个稻草人12 小时前
Tera Term 鸿蒙 PC 适配全记录:用 ArkUI 与 Native C++ 重建多协议终端工作流
c++·stm32·harmonyos
wuyk55512 小时前
从零吃透 MQTT 通信|第 10 章 阿里云 / 腾讯云 MQTT 设备完整对接实战,三元组、签名、设备上云调试
c语言·开发语言·stm32·学习·阿里云·云计算·腾讯云
youcans_13 小时前
【嵌入式软件AI编程】08. 第一个STM32工程
stm32·单片机·ai编程·嵌入式软件·claude code
zhangzhangkeji14 小时前
stm32 ,3-2:led 闪烁、流水灯、蜂鸣器
stm32·arm
Brilliantwxx14 小时前
【STM32】 I2C协议和设备主从( 图解 + 面试题 )
stm32·单片机·嵌入式硬件·架构