1、引言
最近在学习CAN通信相关内容,使用的主控芯片为STM32L431,片内集成有CAN外设,按照官方的demo示例工程可以很方便进行CAN外设初始化、数据通信,但主控MCU只集成了一个can外设,需要有另一个can节点才能建立起can通信。有没有一种方法可以自发自收呢?使用将can工作模式设为回环模式就可以实现,在回环模式下可以进行一些基本的can数据传输实验。
2、工程创建
2.1 cubemx设置
cubemx工程配置如下,勾选can外设以及设置can工作时钟,time seg1/2参数,将can通信速率设定为500Kbit/s
同时使能can发送、接收中断
2.2 程序设计
can工作在回环模式,因此can_tx、can_rx不需要外接任何电路,该模式下内部已经将这两根传输线相连。使用Keil打开cubemx工程,需要设置的内容有can滤波器参数,接收中断回调的数据处理逻辑
找到can外设源文件,在用户代码区域1增加如下内容,以下滤波器设置是接收端对所有的can id数据全部接收
/* USER CODE BEGIN 1 */ //过滤器配置 /* USER CODE BEGIN 1 */ void Configure_Filter(void) { CAN_FilterTypeDef sFilterConfig; sFilterConfig.FilterIdHigh=0X0000; //32位ID sFilterConfig.FilterIdLow=0X0000; sFilterConfig.FilterMaskIdHigh=0X0000; //32位MASK sFilterConfig.FilterMaskIdLow=0X0000; sFilterConfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;//过滤器0关联到FIFO0 sFilterConfig.FilterBank=1; //过滤器0 sFilterConfig.FilterMode=CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale=CAN_FILTERSCALE_32BIT; sFilterConfig.FilterActivation=ENABLE; //激活滤波器0 sFilterConfig.SlaveStartFilterBank=14; if(HAL_CAN_ConfigFilter(&hcan1,&sFilterConfig)!=HAL_OK) { Error_Handler(); } } ///CAN接收中断回调函数 void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle) { /* Get RX message */ if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO0, &RxHeader, rxbuf) != HAL_OK) { /* Reception Error */ Error_Handler(); } RTT_printf("RX_Data:\n");//如果配置有串口,可以使用printf代替RTT_printf for(uint8_t i=0;i<8;i++){ RTT_printf("0x%02x ",rxbuf[i]); } RTT_printf("\n\n"); } /* USER CODE END 1 */
在用户变量区域声明必要的变量
/* USER CODE BEGIN 0 */ CAN_TxHeaderTypeDef TxMessage; CAN_RxHeaderTypeDef RxHeader; uint8_t rxbuf[8]; /* USER CODE END 0 */
main.c编写数据发送逻辑
/* USER CODE BEGIN 1 */ CAN_TxHeaderTypeDef Can_Tx; static uint8_t txdata[8] = {0x03,0x11,0x03,0x42,0x77,0x0a,0x07,0x08}; uint32_t pTxMailbox = 0; Can_Tx.StdId = 0x122; Can_Tx.IDE = 0; Can_Tx.RTR = 0; Can_Tx.DLC = 8; /* USER CODE END 1 */
每隔500ms发送一次数据,can接收数据完成后输出数据至RTT viewer
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_CAN_AddTxMessage(&hcan1,&Can_Tx,txdata,&pTxMailbox);//发送消息 HAL_Delay(500); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
三、实验结果
接收数据与txdata一致
txdata[8] = {0x03,0x11,0x03,0x42,0x77,0x0a,0x07,0x08}