目录
1:Cube初始化设置
配置对应引脚:配置CAN1的波特率为500kbps。CAN2配置同CAN1。
勾选接收中断函数。
2:配置过滤器
过滤器配置为不过滤。在CAN.c中的
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
中间添加过滤器初始函数。
void CAN1_Filter_Init(CAN_HandleTypeDef* canHandle)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 1;//过滤器0 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
sFilterConfig.FilterIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器掩码低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(canHandle,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(canHandle) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(canHandle,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接收中断
{
Error_Handler();
}
}
void CAN2_Filter_Init(CAN_HandleTypeDef* canHandle)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 13; //过滤器13 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO1;//采用FIFO1
sFilterConfig.FilterIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器掩码低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(canHandle,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(canHandle) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(canHandle,CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)//开启接收中断
{
Error_Handler();
}
}
STM32F105芯片复位后默认的0-13号过滤寄存器可以定向到CAN1的 FIFO1或者FIFO0,14-17号定向到CAN2的FIFO1或者FIFO0
过滤器配置时CAN1和CAN2的过滤器序号需要注意,我不太懂。下面这个是我当时看的一个博客。
STM32F105双CAN双FIFO通讯心得体会_xiaoyaofriend的专栏-CSDN博客
3:重写接收接收中断函数
main.c中 添加接收中断函数,只为了验证,随便抄了点(忘了出处),后续修改。
/* USER CODE BEGIN 4 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
uint8_t aRxData[8], i;
//(STID+EXTID+IDE+RTR
Can_Rx.StdId = 0x0Ff;
Can_Rx.ExtId = 0x0Ff;
Can_Rx.IDE = CAN_ID_EXT;//CAN_ID_STD 标准帧 CAN_ID_EXT 扩展帧
Can_Rx.RTR = CAN_RTR_DATA;
Can_Rx.DLC = 8;
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &Can_Rx, aRxData) == HAL_OK)
{
printf("1Get Rx Message Success");
HAL_CAN_AddTxMessage(&hcan1,&Can_Tx,tdata,&pTxMailbox);
//HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);
}
}
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
uint8_t aRxData[8], i;
//(STID+EXTID+IDE+RTR
Can_Rx.StdId = 0x0Ff;
Can_Rx.ExtId = 0x0Ff;
Can_Rx.IDE = CAN_ID_EXT;//CAN_ID_STD 标准帧 CAN_ID_EXT 扩展帧
Can_Rx.RTR = CAN_RTR_DATA;
Can_Rx.DLC = 8;
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &Can_Rx, aRxData) == HAL_OK)
{
printf("2Get Rx Message Success");
HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);
}
}
/* USER CODE END 4 */
4:通信测试
发送测试
主函数前添加变量定义。
/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef Can_Tx;
CAN_RxHeaderTypeDef Can_Rx;
uint8_t tdata[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
uint32_t pTxMailbox = 0;
/* USER CODE END PV */
初始化
/* USER CODE BEGIN 2 */
CAN1_Filter_Init(&hcan1);
CAN2_Filter_Init(&hcan2);
Can_Tx.StdId = 0x123;
Can_Tx.ExtId = 0x123;
Can_Tx.IDE = CAN_ID_EXT;
Can_Tx.RTR = 0;
Can_Tx.DLC = 8;
/* USER CODE END 2 */
在主函数while中添加发送函数。
/* USER CODE BEGIN 3 */
HAL_Delay(1000);
HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
HAL_CAN_AddTxMessage(&hcan1,&Can_Tx,tdata,&pTxMailbox);
HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);
接收测试
过滤器配置是个技术活。看了好几个博客才看明白点。索性不配了。
CAN通信不能使用问题
发现一个天坑,我用的这个芯片是GB32F105RC的芯片,今天想重新写个程序发现CAN通信不能用了,检查了所有配置代码都没有问题。然后使用以前的程序CAN通信正常。
检查无数遍后,在一个小伙伴的协助下和以前的程序进行了对比。查了一下cubeMx的库,发现版本有点小差别。改回去后就正常了。之前人们说GB32的芯片和STM32的一样,现在想来还是有点区别的,手头没有STM32的同款芯片,没办法测试,但我想Cube库版本发行的时候应该是都进行过测试,大概率还是芯片差异的问题。
STM32Cube FW_F1 V1.8.3(可用)
- Patch release to fix GPIO/I2C issues.
STM32Cube FW_F1 V1.8.4(不可用)
- Patch release to fix know defects and enhacements implementation.