各种通信协议速度分析
协议 | 最高速度(btis/s) |
---|---|
I2C | 400K |
CAN | 1M |
CAN-FD | 5M |
485 | 10M |
SPI | 36M |
CAN协议图和通信帧
CubeMX CAN配置说明
CAN通信波特率 = APB1频率 / 分频系数 /(BS1 + BS2 + 同步通信段)* 1000
= 42 / 1 / (1+1+1) * 1000
= 14,000 KHz
= 14000000 bit/s
CAN最高只有1M,支持CAN-FD的单片机可以为8M
Time Triggered Communication Mode:
时间触发模式,用于生成时间戳,可以实现分时同步功能
Automatic Bus-Off Management
自动离线管理,当节点检测到它发送错误或接收错误超过一定值时,会自动进入离线状态
Automatic Wake-Up Mode
自动唤醒功能,CAN 外设可以使用软件进入低功耗的睡眠模式,如果使能了这个自动唤醒功能,当 CAN 检测到总线活动的时候,会自动唤醒
Automatic Retransmission
报文自动重传功能,设置这个功能后,当报文发送失败时会自动重传至成功为止
Receive Fifo Locked Mode
FIFO 锁定模式,该功能用于锁定接收 FIFO。锁定后,当接收 FIFO 溢出时,会丢弃下一个接收的报文。若不锁定,则下一个接收到的报文会覆盖原报文
Transmit Fifo Priority
报文发送优先级的判定方法,ID 优先级还是报文存进邮箱的顺序来发送
Operating Mode:
CAN模式
自发自收模式配置
示例程序
如果是GD32系列单片机需要在stm32f4xx_hal_can.c文件中添加如下代码,解决初始化CAN死机问题
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
// 申明使用到的变量
uint8_t TX_data[20];
uint8_t RX_data[20];
uint32_t mailbox;
int back;
static CAN_TxHeaderTypeDef Tx_Header;
static CAN_FilterTypeDef can_filter;
// CAN接收回调
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance == CAN1)
{
CAN_RxHeaderTypeDef RxHeader;
// 当接收到数据后放到TX数组,把数据返回去
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, TX_data);
//HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RX_data);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_SET);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
// 初始化CAN1
MX_CAN1_Init();
// 启用CAN的中断通知功能
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
// 启动CAN1
HAL_CAN_Start(&hcan1);
// 设置CAN过滤器(CAN配置详解请看下一点)
can_filter.FilterActivation = CAN_FILTER_ENABLE;
can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
can_filter.FilterIdHigh = 0x0000;
can_filter.FilterIdLow = 0x0000;
can_filter.FilterMaskIdHigh = 0x0000;
can_filter.FilterMaskIdLow = 0x0000;
can_filter.FilterBank = 0;
can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;
can_filter.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan1, &can_filter);
// 初始数据
TX_data[0] = 0x01;
TX_data[1] = 0x02;
TX_data[2] = 0x03;
TX_data[3] = 0x01;
TX_data[4] = 0x02;
TX_data[5] = 0x03;
TX_data[6] = 0x01;
TX_data[7] = 0x02;
while (1)
{
// 设置CAN发送信息
Tx_Header.StdId=0x12345678;
Tx_Header.ExtId=0;
Tx_Header.IDE=CAN_ID_STD;
Tx_Header.RTR=CAN_RTR_DATA;
Tx_Header.DLC=8;
// 发送数据
back = HAL_CAN_AddTxMessage(&hcan1, &Tx_Header, TX_data, &mailbox);
if(back == HAL_OK)
{
// 发送成功亮灯
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET);
}
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(1000);
}
}
https://download.csdn.net/download/hmxm6/89341938