STM32标准帧和扩展帧的发送

STM32的CAN模块在发送标准帧和扩展帧时,通过设置TxMessage结构体的IDE字段来区分。当IDE设为CAN_Id_Standard时发送标准帧(11位ID),设为CAN_Id_Extended则发送扩展帧(29位ID)。在库函数CAN_Transmit中,根据IDE的值设置TIR寄存器,从而实现帧类型的判断和发送。
摘要由CSDN通过智能技术生成

说明

CAN2.0A是标准协议,而CAN2.0B是扩展协议(针对扩展帧)。标准帧的ID为11位,扩展帧的ID为11+18=29位。它们之间最大的区别就是帧ID变长了。

疑问

在stm32中标准帧和扩展帧是怎么发送的?它们之间是怎么判断区分的呢?

发送过程分析

can的发送数据一般设置如下:

CanTxMsg TxMessage;

TxMessage.StdId=StdId; // 保存标准帧ID

TxMessage.ExtId=ExtId; // 保存扩展帧ID

TxMessage.IDE=CAN_ID_EXT; // 判断标准帧/扩展帧标识

TxMessage.RTR=0; // 无关紧要

TxMessage.DLC=len; // 数据长度

在库函数中:

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
	...
 /* Set up the Id */
 	if (TxMessage->IDE == CAN_Id_Standard)
 	{
		 assert_param(IS_CAN_STDID(TxMessage->StdId)); 	
		 CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \	
		 TxMessage->RTR);	
	 }	
	 else
	 {	
		 assert_param(IS_CAN_EXTID(TxMessage->ExtId));		
		 CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \		
		 TxMessage->IDE | \		
		 TxMessage->RTR);	
	 }
}

从代码中可以看到是通过TxMessage->IDE == CAN_Id_Standard来判断发送标准帧呢还是扩展帧呢?

它们的定义如下:

#define CAN_Id_Standard             ((uint32_t)0x00000000)  /*!< Standard Id */

#define CAN_Id_Extended             ((uint32_t)0x00000004)  /*!< Extended Id */

所以如果想要发送标准帧TxMessage.IDE=CAN_Id_Standard;如果是想要发送扩展帧TxMessage.IDE=CAN_ID_EXT。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是一个使用STM32F1系列微控制器接收扩展的示例程序: ```c #include "stm32f10x.h" #include "stm32f10x_can.h" void CAN_Configuration(void) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; // 开启CAN时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // CAN通信时钟配置 RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); uint32_t APB1_CLK = RCC_Clocks.PCLK1_Frequency; uint32_t CAN_CLK = APB1_CLK / 4; // CAN初始化 CAN_StructInit(&CAN_InitStructure); CAN_InitStructure.CAN_TTCM = DISABLE; // 禁用时间触发通信模式 CAN_InitStructure.CAN_ABOM = DISABLE; // 禁用自动离线管理 CAN_InitStructure.CAN_AWUM = DISABLE; // 禁用自动唤醒模式 CAN_InitStructure.CAN_NART = ENABLE; // 禁用消息重传 CAN_InitStructure.CAN_RFLM = DISABLE; // 禁用FIFO锁定模式 CAN_InitStructure.CAN_TXFP = DISABLE; // 禁用发送优先级 CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // 设置为正常模式 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 同步跳跃宽度为1个时间单位 CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; // 时间段1为9个时间单位 CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq; // 时间段2为4个时间单位 CAN_InitStructure.CAN_Prescaler = CAN_CLK / (9 + 4 + 1) / 1000000; // 波特率预分频器计算 CAN_Init(CAN1, &CAN_InitStructure); // CAN过滤器配置 CAN_FilterInitStructure.CAN_FilterNumber = 0; // 过滤器编号为0 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // 使用标识符屏蔽模式 CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 使用32位过滤器模式 CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; // 过滤器标识符高16位 CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; // 过滤器标识符低16位 CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; // 过滤器屏蔽标识符高16位 CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; // 过滤器屏蔽标识符低16位 CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; // 过滤器分配到FIFO0 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; // 启用过滤器 CAN_FilterInit(&CAN_FilterInitStructure); } int main(void) { CAN_Configuration(); while (1) { if (CAN_MessagePending(CAN1, CAN_FIFO0) != 0) // 检查是否有消息在FIFO0中 { CanRxMsg RxMessage; CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); // 从FIFO0接收消息 if (RxMessage.IDE == CAN_Id_Extended) // 检查是否为扩展 { // 处理扩展数据 } } } } ``` 这个程序首先配置了CAN通信的相关参数,然后在主循环中检查是否有消息在FIFO0中,并接收扩展数据进行处理。 请注意,以上代码仅为示例,实际使用时需要根据具体的程序要求进行适当的修改和完善。同时,还需要根据硬件连接正确配置CAN引脚和中断。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值