【通讯协议备忘录】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);
	}
}
相关推荐
单片机仿真设计4 小时前
【proteus仿真】基于 STM32 的智能垃圾桶设计(仿真图+程序)
c语言·stm32·stm32单片机·proteus·毕设·仿真
智闲电子设计5 小时前
STM32 SD 卡 + FatFS 实战:掉电丢数据?f_sync 和簇对齐写救你
stm32·单片机·嵌入式硬件
ヾChen6 小时前
ESP32 OTA 踩坑实录
stm32·单片机·嵌入式硬件·物联网·学习
雨田言炎8 小时前
STM32专题之内部FLASH详解
笔记·stm32·单片机
LCG元10 小时前
STM32 DAC+DMA+定时器触发生成任意波形:数据对齐陷阱、输出缓冲器选型与频率精度实测
stm32·单片机·嵌入式硬件
小柯博客12 小时前
01 · 点亮 STM32MP25 的硬件视频编解码:VPU 与那些“安静“的坑
c语言·笔记·stm32·单片机·嵌入式硬件·嵌入式·视频编解码
zcmodeltech1 天前
钢铁冶金沙盘模型控制系统设计与实现:高炉-连铸-热轧多工序联动方案
分布式·stm32·单片机·嵌入式硬件·交互
笨笨饿1 天前
#110_SCH3000 平台图传系统配置指南:从 DVP 摄像头到 UVC/WiFi 双通道传输
c语言·stm32·单片机·嵌入式硬件·物联网·vim
捷瑞电子工坊1 天前
FreeRTOS事件组:多任务同步的利器
stm32·嵌入式·freertos·实时操作系统·标准外设库·事件组·任务同步
笨笨饿1 天前
#109_BK7258 蓝牙 A2DP 音频数据通路深度解析
python·stm32·单片机·mcu·物联网·编辑器·音视频