STM32_CAN通信

 

目录

 

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标准,物理层特征如下

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数如下

 

一个位的构成: 

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控制器框图

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

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

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

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

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

6:STM32_CAN发送,接受流程

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

7:STM32CAN通信位时序

 

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中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章