欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32_CAN通信

程序员文章站 2024-02-23 21:06:34
...

 

目录

 

1:CAN简介

2:CAN通信帧种类介绍

3:CAN位时序

4:STM32_CAN

5:bx_CAN控制器框图

6:STM32_CAN发送,接受流程

7:STM32CAN通信位时序

8:STM32CAN代码实现


1:CAN简介

CAN是Controller Area Network,是一种串行的通信协议,有两标准:ISO11898、ISO11519-2,其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准,而ISO11519-2是针对通信速率为123Kbps以下的低速通信标准

CAN有很多优点,比如多主控制,速度快,距离远,具有错误检测,恢复,连接节点多等功能。所以CAN协议特别适合工业过程监控设备的互联

讲下ISO11898标准,物理层特征如下

STM32_CAN通信

CAN控制器根据CAN_L和CAN_H上的点位差来判断总线电平,总线电平分为显性电平和隐形电平,二者必居其一,发送方通过使总线电平发生变化,将消息发送给接收方。

  • 显性电平对应逻辑:0 CAN_H和CAN_L之差为2V左右
  • 隐形电平对应逻辑:1 CAN_H和CAN_L之差为0V

要注意的是,显性电平比隐形电平强,显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平,而隐形电平则具有包容的意味,只要所有单元都输出隐形电平,总线上才为隐形电平,

另外,在CAN总线的起止端都有一个120Ω的终端电阻,来做阻抗匹配,以减少回波反射

2:CAN通信帧种类介绍

CAN通信是以以下5钟类型的帧进行的

数据帧、遥控帧、错误帧、过载帧、间隔帧

其中数据帧和遥控帧有标准格式和扩张格式两种,标准格式有11个位标识符(ID),扩展格式有29个位ID

介绍哈数据帧

  1. 帧起始:表示数据帧开始的段
  2. 仲裁段:表示该帧优先级的段
  3. 控制端:表示数据的字节数及保留位的段
  4. 数据段:数据的内容,一帧可发送0~8·个字节的数据
  5. CRC段:检查帧的传输错误的段
  6. ACK段:表示确认正常接受的段
  7. 帧结束:表示数据帧结束的段

3:CAN位时序

位时序:在CAN 通信中,一个位分为4段,这每个段又由Time Quantum(简称Tq)的最小时间单位构成,这个就是位时序

有如下四个段:

  • 同步段(SS)
  • 传播时间段(PTS)
  • 相位缓冲段1(PBS1)
  • 相位缓冲段2(PBS2)

位时间=1/波特率,因此,知道位时间,我们就可以知道波特率

1 位由多少个Tq 构成、每个段又由多少个Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。

位时序各段的作用和Tq数如下

 

STM32_CAN通信

一个位的构成: 

STM32_CAN通信

4:STM32_CAN

eg:STM32F407ZGT6

前面只是对CAN通信做一个基本的描述,在STM32上,自带了基本扩展CAN外设,称bxCAN,

  • CAN1:主bxCAN,用于管理bxCAN与512字节SRAM存储器之间的通信。
  • CAN2:从bxCAN,无法直接访问SRAM存储器,但两个bxCAN单元共享512字节SRAM存储器
  • 波特率最高达1Mbps
  • 支持时间触发通信
  • 具有3个发送邮箱
  • 具有3级深度的2个接受FIFO
  • 可变的筛选器组(也称过滤器组,最多28个)

bxCAN有三种主要的工作模式:初始化、正常、睡眠,还有测试模式和调试模式,具体看数据手册

5:bx_CAN控制器框图

STM32_CAN通信

筛选器组,可以设置你需要的数据,不需要的就不接受,就是为降低CPU处理CAN通信的开销

STM32 CAN控制器每个筛选器组由2个32位寄存器组成,根据位宽不同,每个筛选器组可提供1个32位的筛选器或2个16位的筛选器

筛选器可配置为:屏蔽位模式、标识符列表模式 

通过CAN_FM1R(筛选器模式寄存器)和CAN_FS1R(筛选器尺度寄存器)可配置筛选器的位宽和模式

  • 为了过滤出一组标识符,应该设置筛选器组工作在屏蔽位模式
  • 为了过滤出一个标识符,应该设置过滤器工作在标识符列表模式
  • 应用程序不用的筛选器组,应该保持在禁用状态(通过CAN_FA1R设置)。
  • 通过CAN_FFA1R的设置,可以将筛选器组关联到FIFO0/FIFO1
  • 筛选器组中的每个筛选器,都被编号为(即:筛选器编号)从0开始,到某个最大数值-取决于筛选器组的模式和位宽的设置。

6:STM32_CAN发送,接受流程

STM32_CAN通信

STM32_CAN通信 报文FIFO具有锁定功能(由CAN_MCR,RFLM位控制),锁定后,新数据将丢失,不锁定则新数据将替代老数据

7:STM32CAN通信位时序

STM32_CAN通信

 STM32_CAN通信

8:STM32CAN代码实现

1:初始化 

  	//CAN单元设置
   	CAN_InitStructure.CAN_TTCM=DISABLE;	//非时间触发通信模式   
  	CAN_InitStructure.CAN_ABOM=DISABLE;	//软件自动离线管理	  
  	CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  	CAN_InitStructure.CAN_NART=ENABLE;	//禁止报文自动传送 
  	CAN_InitStructure.CAN_RFLM=DISABLE;	//报文不锁定,新的覆盖旧的  
  	CAN_InitStructure.CAN_TXFP=DISABLE;	//优先级由报文标识符决定 
  	CAN_InitStructure.CAN_Mode= mode;	//模式设置 
  	CAN_InitStructure.CAN_SJW=tsjw;	    
//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=tbs1;     //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=tbs2;     //Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=brp;  //分频系数(Fdiv)为brp+1	
  	CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1 
    
		//配置过滤器
 	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;               //32位ID
  	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;           //32位MASK
  	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
   	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
  	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;              //**过滤器0
  	CAN_FilterInit(&CAN_FilterInitStructure);                         //滤波器初始化

相应引脚配置位复用推挽输出加上拉模式

  1. CAN_TTCM:操作CAN_MCR主控制寄存器的位7
  2. CAN_ABOM:操作CAN_MCR主控制寄存器的位6
  3. CAN_AWU:M操作CAN_MCR主控制寄存器的位5
  4. CAN_NART:操作CAN_MCR主控制寄存器的位4
  5. CAN_RFLM:操作CAN_MCR主控制寄存器的位3
  6. CAN_TXFP:操作CAN_MCR主控制寄存器的位2
  7. CAN_Mode:操作CAN_BTR位时序寄存器的位31,30
  8. CAN_SJW:操作CAN_BTR位时序寄存器的位25,24
  9. CAN_BS1:操作CAN_BTR位时序寄存器的位19~16
  10. CAN_BS2:操作CAN_BTR位时序寄存器的位22~20
  11. CAN_Prescaler:操作CAN_BTR位时序寄存器的位9~0

配置过滤器

  1. CAN_FilterNumber:操作CAN_FA1R筛选器**寄存器的位27:0
  2. CAN_FilterMode:操作CAN_FM1R筛选器模式寄存器的位27:0
  3. CAN_FilterScale:操作CAN_FS1R筛选器尺度寄存器的位27:0和CAN_FiRx筛选器组i寄存器
  4. CAN_FilterIdHighCAN_FilterIdLowCAN_FilterMaskIdHighCAN_FilterMaskIdLow都是配合操作CAN_FiRx筛选器组i寄存器
  5. CAN_FilterFIFOAssignment:操作CAN_FFA1R筛选器FIFO分配寄存器的位27:0
  6. CAN_FilterActivation:操作CAN_FA1R筛选器**寄存器的位27:0

2:发送数据

u8 CAN1_Send_Msg(u8* msg,u8 len)
{	
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;	  // 标准标识符为0
  TxMessage.ExtId=0x12;	  // 设置扩展标示符(29位)
  TxMessage.IDE=0;		  // 使用扩展标识符
  TxMessage.RTR=0;		  // 消息类型为数据帧,一帧8位
  TxMessage.DLC=len;							 // 发送两帧信息
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];				 // 第一帧信息          
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//等待发送结束
  if(i>=0XFFF)return 1;
  return 0;		

}
  1. StdIdIDERTR  :在IDE的基础上,决定在CAN_TIxR发送邮箱标识符寄存器上标识符类型和帧类型
  2. ExtIdIDERTR:在IDE的基础上,决定在CAN_TIxR发送邮箱标识符寄存器上标识符类型和帧类型
  3. len:操作CAN_TDTxR邮箱数据长度控制和时间戳寄存器的位3:0
  4. Data:操作CAN_TDL\HxR邮箱数据低\高寄存器
  5. 最后查询CAN_TSR发送状态寄存器,等待发送结束

 3:接受数据

u8 CAN1_Receive_Msg(u8 *buf)
{		   		   
 	u32 i;
	CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;		//没有接收到数据,直接退出 
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据	
    for(i=0;i<RxMessage.DLC;i++)
    buf[i]=RxMessage.Data[i];  
	return RxMessage.DLC;	
}
  1. 先查询CAN_RF0R接受FIFI 0寄存器的位1:0
  2. 然后去读取CAN_RDL\HxR接受FIFO邮箱数据低\高位寄存器的数据存放在RxMessage.Data中