1.准备工作
准备一个stm32f103c8t6核心板,TTL转USB用于串口通信。
原理说明
回环测试就是MCU板子内部实现,不需要接外部CAN收发器(TJA1050)
2.CUBMAX配置工程
搜索并选定芯片stm32f103c8t6
配置时钟
调试工具sw
时钟树配置
配置工程名字等信息
最后配置CAN总线设置:分屏系数为9,时间配置5,2,1
配置CAN总线发送模式 选择Loopback
配置接收中断:
点击生成代码
3.编写CAN收发代码
在main.c定义CAN接收和发送消息变量
static CAN_TxHeaderTypeDef TxMessage;
static CAN_RxHeaderTypeDef RxMessage;
配置过滤器函数:(没有进行任何的过滤)
static void CANFilter_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
printf("ConfigFilter is Failed\n");
Error_Handler();
}
printf("ConfigFilter is success\n");
}
使能CAN中断接收函数
if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK){
printf("CAN_IT_RX_FIFO0_MSG_PENDING Fail\r\n");
Error_Handler();
}
printf("CAN_IT_RX_FIFO0_MSG_PENDING success\r\n");
使能CAN总线
if(HAL_CAN_Start(&hcan) !=HAL_OK){
printf("CAN start Fail\r\n");
Error_Handler();
}
printf("CAN start success\r\n");
全部放在while循环之前begin 和end之间
CAN发送代码
void CAN1_Send_Test(void)
{
uint32_t CAN_TX_BOX=0;
uint8_t data[8] ={0x01,0x02,0x03,0x04};
TxMessage.IDE= CAN_ID_STD;
TxMessage.StdId = 0x2222;
TxMessage.RTR =CAN_RTR_DATA;
TxMessage.TransmitGlobalTime = DISABLE;
TxMessage.DLC = 4;
if (HAL_CAN_AddTxMessage(&hcan,&TxMessage, data,&CAN_TX_BOX) != HAL_OK){
printf("CAN send test data fail! \r\n");
Error_Handler();
}
}
放在while循环里面,2s发送一次
CAN接收代码
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
uint8_t data[8];
HAL_StatusTypeDef status;
if (hcan->Instance == NULL){
return;
}
status = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMessage, data);
if (status == HAL_OK) {
printf("---> Data Received!\n");
printf("RxMessage.StdId is 0x%08X\n", RxMessage.StdId);
printf("data[0] is 0x%02X\n", data[0]);
printf("data[1] is 0x%02X\n", data[1]);
printf("data[2] is 0x%02X\n", data[2]);
printf("data[3] is 0x%02X\n", data[3]);
printf("<---\n");
} else {
printf("Failed to get CAN message, status: 0x%08X\n", status);
}
}
最后运行测试!
测试结果
最后说一下遇到的问题
1.发送一直卡死在HAL_CAN_AddTxMessage函数 解决:
CAN发送卡死,HAL_CAN_AddTxMessage函数一直进入硬件错误中断问题-CSDN博客
2.CAN接收回调函数接收不了
主要是在发送函数HAL_CAN_AddTxMessage后面不能使用printf,要是使用的话,延迟一下在打印
不然CAN后调函数调用不了。