STM32 HAL库开发(五)- CAN通信

CAN通信介绍

开启CAN配置

首先开启HSE时钟,外接的8M的晶振。
在这里插入图片描述
打开时钟树,将PCLK1的频率设置为36MHz。
在这里插入图片描述
开启CAN通信,并设置波特率,我这里设置的是250K。
CAN波特率 = APB1_PCLK1/分频/(tq1 + tq2 + ss)
其他频率可以参考其他大佬的设置
波特率配置表
在这里插入图片描述
开启接收中断,这里根据需求选择RX0,我们只用FIFO0
在这里插入图片描述
这里测试,我们选择回环模式。
在这里插入图片描述

CAN过滤器

注意:不配置过滤器就无法接收数据。
掩码模式和列表模式需要提前了解,这里就不详细介绍了。
这里FilterScale选32位,就是FilterId高低一起作用。选16位,就是FilterIdHigh/FilterIdLow单独作用。FilterMaskId在列表模式与FilterId作用一致。
掩码遇1按位比较,列表就是白名单。

typedef struct
{
  uint32_t FilterIdHigh;          //CAN_FiR1寄存器的高16位
  uint32_t FilterIdLow;           //CAN_FiR1寄存器的低16位
  uint32_t FilterMaskIdHigh;      //CAN_FiR2寄存器的高16位
  uint32_t FilterMaskIdLow;       //CAN_FiR2寄存器的低16位
  uint32_t FilterFIFOAssignment;  //通过筛选器的报文存在FIFO0还是FIFO1中
  uint32_t FilterBank;            //此次配置用的是哪个筛选器。用单CAN的取值为0-13
  uint32_t FilterMode;            //掩码模式或列表模式
  uint32_t FilterScale;           //32位或16位
  uint32_t FilterActivation;      //使能或失能
  uint32_t SlaveStartFilterBank;  //CAN1和CAN2一起用的时候,为CAN2分配筛选器的个数
} CAN_FilterTypeDef;

这里我选的列表模式,毕竟总线上没有太多设备,我也就是固定收某几个设备的信息。

代码部分

typedef struct // 定义发送数据结构体
{
	uint8_t conn : 1; // 按位定义
	uint8_t estop : 1;
	uint8_t alarm : 1;
	uint8_t reset : 1;
	uint8_t other:4;
	uint8_t other2[7];
} SendDataStruct;

CAN_TxHeaderTypeDef can_Tx;
CAN_RxHeaderTypeDef can_Rx;
uint8_t sendBuf[8] = {0};
uint8_t recvBuf[8] = {0};
uint32_t box;
CAN_FilterTypeDef can_Filter = {0};
char aRxBuffer[100];
int aRxBufferIndex = 0;
uint8_t canSendData[8] = {0};
uint16_t CanFilterListSTID1 = 0x126;

// CAN接收中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
  HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can_Rx, recvBuf);
  HAL_UART_Transmit( &huart1 , (uint8_t *)&recvBuf, sizeof(recvBuf), 0xFFFF);
}

// 串口接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart1)
  {
    if(aRxBufferIndex >= 100) {
    	aRxBufferIndex = 0;
    }
    aRxBufferIndex ++;
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer[aRxBufferIndex], 1);
  }
}

	HAL_CAN_Start(&hcan); // CAN启动
	
	can_Tx.StdId = 0x108; // can发送消息头
	can_Tx.ExtId = 0;
	can_Tx.IDE = CAN_ID_STD;
	can_Tx.RTR = CAN_RTR_DATA;
	can_Tx.DLC = 8; // 数据长度
	can_Tx.TransmitGlobalTime = DISABLE;
	
	can_Filter.FilterIdHigh = (CanFilterListSTID1<<5)|(0x00<<4);; // can过滤器配置
	can_Filter.FilterIdLow = 0;
	can_Filter.FilterMaskIdHigh = 0;
	can_Filter.FilterMaskIdLow = 0;
	can_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	can_Filter.FilterBank = 0;
	can_Filter.FilterMode = CAN_FILTERMODE_IDLIST; // 列表模式,白名单
	can_Filter.FilterScale = CAN_FILTERSCALE_16BIT; // 16位
	can_Filter.FilterActivation = CAN_FILTER_ENABLE;
	HAL_CAN_ConfigFilter(&hcan, &can_Filter);
	
	HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // 开启can中断接收

  while (1)
  {
		can_Tx.StdId = CanFilterListSTID1;
		SendDataStruct sendData = {0};
		sendData.estop = 1;
		HAL_CAN_AddTxMessage(&hcan, &can_Tx, &sendData, &box);
		HAL_Delay(1000);
		
  }
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值