【通讯协议备忘录】stm32的CAN外设
发布人:shili8
发布时间:2024-12-25 23:16
阅读次数:0
**STM32 CAN 外设通讯协议备忘录**
**1. 前言**
CAN(Controller Area Network)是一种广泛用于汽车电子系统中的串行通信总线。它提供了一个高效的、低成本的通信方式,适合于在汽车电子系统中传输数据。STM32系列微控制器都内置有CAN外设,可以支持CAN协议的实现。
**2. CAN 总线概述**
CAN是一种多主机、半双工的总线。它使用一个总线来连接所有设备,每个设备都有自己的ID(识别码),用于区分数据包来源。CAN总线支持多种传输速率,最高可达1Mbps。
**3. CAN 外设特性**
STM32系列微控制器上的CAN外设具有以下特性:
* 支持CAN2.0A和CAN2.0B协议* 支持11-bit和29-bitID* 支持多种传输速率,最高可达1Mbps* 支持自动重发功能(在数据包发送过程中,如果接收到错误的数据包,则会自动重发)
* 支持过滤功能(可以根据ID过滤掉不需要的数据包)
**4. CAN 外设寄存器**
CAN外设使用一组寄存器来控制和配置总线。以下是这些寄存器的描述:
| 寄存器名 | 位数 | 描述 |
| --- | --- | --- |
| CR1 |32位 | CAN控制寄存器1,用于设置总线模式、传输速率等参数 |
| CR2 |32位 | CAN控制寄存器2,用于设置自动重发功能和过滤功能等参数 |
| SR1 |32位 | CAN状态寄存器1,用于读取总线状态信息 |
| SR2 |32位 | CAN状态寄存器2,用于读取总线状态信息 |
**5. CAN 外设配置**
以下是如何配置CAN外设的示例代码:
c#include "stm32f10x.h" void CAN_Config(void) { // 设置总线模式为标准模式 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_0; // CAN_TX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线模式为扩展模式 GPIO_InitStruct.Pin = GPIO_PIN_1; // CAN_RX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线传输速率为1Mbps CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =0x0000; // ID低位 sFilterInit.FilterMaskIdHigh =0x0000; // ID掩码高位 sFilterInit.FilterMaskIdLow =0x0000; // ID掩码低位 HAL_CAN_ConfigFilter(&hcan, &sFilterInit); // 设置总线模式为标准模式 CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =0x0000; // ID低位 sFilterInit.FilterMaskIdHigh =0x0000; // ID掩码高位 sFilterInit.FilterMaskIdLow =0x0000; // ID掩码低位 HAL_CAN_ConfigFilter(&hcan, &sFilterInit); }
**6. CAN 外设发送**
以下是如何使用CAN外设发送数据的示例代码:
c#include "stm32f10x.h" void CAN_Send(void) { // 设置总线模式为标准模式 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_0; // CAN_TX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线模式为扩展模式 GPIO_InitStruct.Pin = GPIO_PIN_1; // CAN_RX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线传输速率为1Mbps CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =0x0000; // ID低位 sFilterInit.FilterMaskIdHigh =0x0000; // ID掩码高位 sFilterInit.FilterMaskIdLow =0x0000; // ID掩码低位 HAL_CAN_ConfigFilter(&hcan, &sFilterInit); // 设置总线模式为标准模式 CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =0x0000; // ID低位 sFilterInit.FilterMaskIdHigh =0x0000; // ID掩码高位 sFilterInit.FilterMaskIdLow =0x0000; // ID掩码低位 HAL_CAN_ConfigFilter(&hcan, &sFilterInit); // 发送数据包 uint32_t data[8]; data[0] =0x12345678; data[1] =0x90123456; data[2] =0x78901234; data[3] =0x56789012; data[4] =0x34567890; data[5] =0x12345678; data[6] =0x90123456; data[7] =0x78901234; HAL_CAN_Transmit(&hcan, data,8,100); }
**7. CAN 外设接收**
以下是如何使用CAN外设接收数据的示例代码:
c#include "stm32f10x.h" void CAN_Receive(void) { // 设置总线模式为标准模式 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_0; // CAN_TX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线模式为扩展模式 GPIO_InitStruct.Pin = GPIO_PIN_1; // CAN_RX GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_CAN; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置总线传输速率为1Mbps CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =0x0000; // ID低位 sFilterInit.FilterMaskIdHigh =0x0000; // ID掩码高位 sFilterInit.FilterMaskIdLow =0x0000; // ID掩码低位 HAL_CAN_ConfigFilter(&hcan, &sFilterInit); // 设置总线模式为标准模式 CAN_FilterInitTypeDef sFilterInit; sFilterInit.FilterMode = CAN_FILTERMODE_IDMASK; sFilterInit.FilterScale = CAN_FILTERSCALE_6BIT; sFilterInit.FilterIdHigh =0x0000; // ID高位 sFilterInit.FilterIdLow =