STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置

参考资料:

https://blog.csdn.net/qq_32605451/article/details/88690863

使用芯片:STM32F407ZGT6
cube软件版本:5.60
软件包版本为:STM32CubeF4 Firmware Package V1.25.0 / 12-February-2020

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第1张图片

can mode 选择master模式

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第2张图片

系统时钟配置

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第3张图片

can 参数设置

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第4张图片

 

can NVIC设置选择 CAN1 RX0 interrupts 模式(跟can过滤器配置相关)

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第5张图片

在project manager中 code generator选项勾选单独生成外设初 c / h 文件 这样工程文件结构更加清晰

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第6张图片

最后点击 code generator 生成代码即可

在can.c 文件中配置can滤波器

void CAN1_Config(void)
{
	CAN_FilterTypeDef CAN_FilterType;
	
	CAN_FilterType.FilterBank = 0;
	CAN_FilterType.FilterIdHigh = 0x0000;
	CAN_FilterType.FilterIdLow = 0x0000;
	CAN_FilterType.FilterMaskIdHigh = 0x0000;
	CAN_FilterType.FilterMaskIdLow = 0x0000;
	CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO0;
	CAN_FilterType.FilterMode = CAN_FILTERMODE_IDMASK;
	CAN_FilterType.FilterScale = CAN_FILTERSCALE_32BIT;
	CAN_FilterType.FilterActivation = ENABLE;
	CAN_FilterType.SlaveStartFilterBank = 14;
	if(HAL_CAN_ConfigFilter(&hcan1,&CAN_FilterType) != HAL_OK)
	{
		Error_Handler();
	}
	if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
	{
		Error_Handler();
	}
	if(HAL_CAN_Start(&hcan1)!=HAL_OK)
	{
		Error_Handler();
	}
}

can发送函数

uint8_t Can_TxMessage(uint8_t ide,uint32_t id,uint8_t len,uint8_t *data)
{	
	uint32_t TxMailbox;		
	CAN_TxHeaderTypeDef CAN_TxHeader;
	HAL_StatusTypeDef   HAL_RetVal; 
	uint16_t i=0;
	
		if(ide == 0)
	{
		CAN_TxHeader.IDE = CAN_ID_STD;	//标准帧
		CAN_TxHeader.StdId = id;
	}
	else 
	{
		CAN_TxHeader.IDE = CAN_ID_EXT;	//扩展帧
		CAN_TxHeader.ExtId = id;
	}

	CAN_TxHeader.DLC = len;
	CAN_TxHeader.RTR = CAN_RTR_DATA;//数据帧,CAN_RTR_REMOTE遥控帧
	CAN_TxHeader.TransmitGlobalTime = DISABLE;
		
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0)
	{
		i++;
		if(i>0xfffe)
			return 1;
	}
	HAL_Delay(2000);
	HAL_RetVal = HAL_CAN_AddTxMessage(&hcan1,&CAN_TxHeader,data,&TxMailbox);	
	if(HAL_RetVal != HAL_OK)
		return 1;
	return 0;
}

can接受中断回调函数(我直接上了can分析仪,屏蔽了串口打印)

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	CAN_RxHeaderTypeDef CAN_RxHeader;
	HAL_StatusTypeDef HAL_Retval;
	uint8_t CanRxBuff[8];
	uint8_t Data_Len=0;
	uint32_t ID=0;
	uint8_t i;
	HAL_Retval = HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&CAN_RxHeader,CanRxBuff);
	if(HAL_Retval == HAL_OK)
	{
		Data_Len = CAN_RxHeader.DLC;
		if(CAN_RxHeader.IDE)
			ID = CAN_RxHeader.ExtId;
		else
			ID = CAN_RxHeader.StdId;
//		printf("id:%x\r\n",ID);
//		printf("Data_Len:%d\r\n",Data_Len);
//		for(i=0;i<8;i++)
//			printf("Rx_Data[%d]=%x\r\n",i,Rx_Data[i]);	
	}
}

主函数循环中调用can发送函数

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

		
		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET);
		HAL_Delay(1000);
		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);
		HAL_Delay(1000);		
		
		Can_TxMessage(0,0X222,8,CanTxBuff);


  }
  /* USER CODE END 3 */
}

然后烧写程序在can调试器监控界面中就看到了can数据

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第7张图片

一开始配置后调试怎么都无法进入can接收中断

后来找到原因是can波特率配置有问题

一开始can时钟配置的是32M

波特率参数配置如图

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第8张图片

波特率计算方法:
BaudRate=APB1CLK/分频系数/(1+BS1+BS2).
刚开始配置:32M/16/(1+2+1)=500k.

CAN工作模式:Normal

看正点原子的开发指南中说可以任意配置

STMCubeMX5.60版本CAN使用loopback模式自测------问题记录之时钟配置_第9张图片

不知道为什么这样是不对的 tBS1 tBS2不是随意配置组合的,具体随后在深入追究(未完待续)

 

2020年3月15日 13:06:22更新

在其他地方找到质料 tBS1、tBS2、tSJW有设置原则

总体配置保持:

tBS1>=tBs2, tBS2>=1个CAN时钟周期,tBS2>=2tSJW

怕麻烦的记住3、2、1就行了

tBS1 = 3  Time

tBS2 = 2 Time

tSJW = 1 Time

大部分的波特率都可以使用(5k用642,400k和800k用531)

你可能感兴趣的:(STM32)