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发送、接收中断
![1735916235297555.png }{`8BR559`2]MQLQL3V0_}I.png](http://uphotos.eepw.com.cn/1709346044/pics/1735916235297555.png)
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}
![1735918204207904.png T3{E52)`O]HDT8ZQ5)4$DPD.png](http://uphotos.eepw.com.cn/1709346044/pics/1735918204207904.png)
我要赚赏金
