STM32 HAL CAN通讯 实操

1、简介

相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机可以无脑操作。

2、STM32CubeMX配置

2.1 SYS配置

2.2 RCC配置

2.3 时钟树配置 

填写方框最下方HCLK最大系数后点击回车,即可自动进行时钟配置。

STM32HAL库提供了一些函数和宏定义,用于配置和操作CAN总线。下面是一些基本的步骤: 1. 启用CAN时钟:在使用CAN之前,需要先启用CAN时钟。可以使用“__HAL_RCC_CANx_CLK_ENABLE()”函数启用CAN时钟,其中“x”是使用的CAN端口号。 2. 配置CAN总线:使用“hcan.Init”结构体配置CAN总线。可以设置CAN的工作模式、传输速率、过滤器等参数。然后使用“HAL_CAN_Init()”函数初始化CAN总线。 3. 配置CAN消息:使用“CanTxMsg”和“CanRxMsg”结构体配置CAN消息。可以设置CAN消息的ID、长度、数据等参数。 4. 发送CAN消息:使用“HAL_CAN_Transmit()”函数发送CAN消息。需要提供CAN总线句柄和CAN消息结构体。 5. 接收CAN消息:使用“HAL_CAN_Receive()”函数接收CAN消息。需要提供CAN总线句柄和CAN消息结构体。 下面是一个简单的示例代码,演示了如何使用STM32HAL库进行CAN通讯: ```c #include "stm32f1xx_hal.h" #include "main.h" CAN_HandleTypeDef hcan; void SystemClock_Config(void); int main(void) { HAL_Init(); SystemClock_Config(); __HAL_RCC_CAN1_CLK_ENABLE(); hcan.Instance = CAN1; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.AutoBusOff = ENABLE; hcan.Init.AutoRetransmission = ENABLE; hcan.Init.AutoWakeUp = DISABLE; hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.TransmitFifoPriority = DISABLE; hcan.Init.Prescaler = 4; hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_13TQ; hcan.Init.TimeSeg2 = CAN_BS2_2TQ; HAL_CAN_Init(&hcan); CAN_TxHeaderTypeDef txHeader; txHeader.StdId = 0x123; txHeader.RTR = CAN_RTR_DATA; txHeader.IDE = CAN_ID_STD; txHeader.DLC = 8; uint8_t txData[8] = {0, 1, 2, 3, 4, 5, 6, 7}; uint32_t txMailbox; HAL_CAN_AddTxMessage(&hcan, &txHeader, txData, &txMailbox); CAN_RxHeaderTypeDef rxHeader; uint8_t rxData[8]; HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxData); while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } ``` 这个示例代码初始化了CAN1总线,并发送了一个长度为8个字节的CAN消息。在主循环中,程序将会一直阻塞,等待接收到CAN消息。需要注意的是,这只是一个简单的示例,实际应用中需要根据具体的需求进行修改和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值