STM32CAN外设使用

测试单片机是STM32F427ZGT6,CAN外设的主频是45MHz
STM32CAN外设使用_第1张图片

Can外设配置

STM32CAN外设使用_第2张图片

  • TTCM(Time triggered communication mode)时间触发模式,用于生成时间戳,可以实现分时同步功能
  • ABOM(Automatic bus-off management) 自动离线管理,当节点检测到它发送错误或接收错误超过一定值时,会自动进入离线状态
  • AWUM(Automatic bus-off management),自动唤醒功能,CAN 外设可以使用软件进入低功耗的睡眠模式,如果使能了这个自动唤醒功能,当 CAN 检测到总线活动的时候,会自动唤醒
  • NART(No automatic retransmission)报文自动重传功能,设置这个功能后,当报文发送失败时会自动重传至成功为止
  • RFLM(Receive FIFO locked mode)FIFO 锁定模式,该功能用于锁定接收 FIFO。锁定后,当接收 FIFO 溢出时,会丢弃下一个接收的报文。若不锁定,则下一个接收到的报文会覆盖原报文
  • TXFP(Transmit FIFO priority)报文发送优先级的判定方法,ID 优先级还是报文存进邮箱的顺序来发送

使能接收中断

STM32CAN外设使用_第3张图片

CAN外设使用步骤:
1. 配置CAN总线设备(以上2步,配置分频,配置QS1,QS2)
2. 在主程序内打开CAN设备,
3. 配置过滤器
4. 使能中断
5. 实现中断回调函数

CAN_RxHeaderTypeDef rxheadr;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
	if(hcan==&hcan1)
	 	HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rxheadr, rx_can_data);
	else
		HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &rxheadr, rx_can_data);
}



static void LEDTaskFunction( void * param)
{
	CAN_TxHeaderTypeDef header={
		.StdId = 1,
		.ExtId=0,
		.IDE = CAN_ID_STD,
		.RTR = CAN_RTR_DATA,
		.DLC=8
		};

	xsem = xSemaphoreCreateBinary();
	if(xsem!=NULL)
	{
		hb_printf("create sem binary ok\r\n");
	}

	CAN_FilterTypeDef  sFilterConfig;

	sFilterConfig.FilterBank = 0;                       //过滤器编号可选0-27
	sFilterConfig.FilterMode =  CAN_FILTERMODE_IDLIST;  //设为列表模式 ,还可以设置为掩码模式   
	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;  //过滤器使用32位模式 
	//使用标准帧,接收id是1;
	uint32_t id1=1;
	uint32_t tmp = (id1<<21)|CAN_ID_STD|CAN_RTR_DATA;//需要构造一个ID	

	sFilterConfig.FilterIdHigh = (tmp&0xffff0000)>>16;   //基本ID放入到STID中  
	sFilterConfig.FilterIdLow  = tmp&0xffff; 
	//使用标准帧,接收id是1;
	uint32_t id2=2;
	tmp = (id2<<21)|CAN_ID_STD|CAN_RTR_DATA;	//需要构造一个ID	
	sFilterConfig.FilterMaskIdHigh =(tmp&0xffff0000)>>16; 
	sFilterConfig.FilterMaskIdLow  =tmp&0xffff; 



	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0	;    //接收到的报文放入到FIFO0中 

	sFilterConfig.FilterActivation = ENABLE;  	//使能过滤器
	sFilterConfig.SlaveStartFilterBank  = 0; 
	//配置过滤器
	HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
	HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);

	//打开CAN设备
	HAL_CAN_Start(&hcan1);
	HAL_CAN_Start(&hcan2);
	//就是打开中断
	HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING);

数据发送的方法

  1. 配置好cubemx参数主要是波特率
  2. 打开CAN外设
  3. 构建一个发送结构体
  4. 使用发送
CAN_TxHeaderTypeDef header={
		.StdId = 1,//id
		.ExtId=0,//扩展id
		.IDE = CAN_ID_STD,//标准帧结构
		.RTR = CAN_RTR_DATA,//数据帧
		.DLC=8//数据的长度
		};
HAL_CAN_Start(&hcan1);
HAL_CAN_AddTxMessage(&hcan1, &header, "12345678", (uint32_t *) CAN_TX_MAILBOX0);

数据过滤器的设置方式

每组筛选器包含 2 个 32 位的寄存器,分别为 CAN_FxR1 和 CAN_FxR2,它们用来存储要筛选的 ID 或掩码
下面以32位筛选器标准帧为例:
CAN_FxR1[31-22]位是标准数据帧的id设置位合计11bit
CAN_FxR1[1] 是设置遥控帧还是数据帧
CAN_FxR1[2] 是设置标准帧还是扩展ID帧,此处设置为标准帧

示例代码设置标识符模式的标注帧 的ID 设置方法(32位列表模式)

	//使用标准帧,接收id是1;
	uint32_t id1=1;//设置筛选的id
	uint32_t tmp = (id1<<21)|CAN_ID_STD|CAN_RTR_DATA;// 1.先移动21位,把id设置到指定的bit,添加真的RTR和IDE
	sFilterConfig.FilterIdHigh = (tmp&0xffff0000)>>16;   //  将寄存器的高16bit放置到CAN_FxR1[31-16] ,sFilterConfig.FilterIdHigh仅仅低16位数据有效
	sFilterConfig.FilterIdLow  = tmp&0xffff;  //  将寄存器的高16bit放置到CAN_FxR1[15-0] ,sFilterConfig.FilterIdLow仅仅低16位数据有效
	
	//使用标准帧,接收id是2;
	uint32_t id2=2;
	tmp = (id2<<21)|CAN_ID_STD|CAN_RTR_DATA;		
	sFilterConfig.FilterMaskIdHigh =(tmp&0xffff0000)>>16; //将寄存器的高16bit放置到CAN_FxR2[31-16] ,sFilterConfig.FilterMaskIdHigh仅仅低16位数据有效
	sFilterConfig.FilterMaskIdLow  =tmp&0xffff; //将寄存器的高16bit放置到CAN_FxR2[15-0] ,sFilterConfig.FilterMaskIdLow仅仅低16位数据有效

示例2: 仅仅接收ID是奇数的数据(32位掩码模式)

STM32CAN外设使用_第4张图片

接收所有数据

STM32CAN外设使用_第5张图片

4种过滤模式的详细描述图

STM32CAN外设使用_第6张图片

你可能感兴趣的:(STM32,stm32,Can)