1、CAN总线的初始化
void can_init(void)
{
      CAN_InitTypeDef        CAN_InitStructure;
      CAN_FilterInitTypeDef  CAN_FilterInitStructure;
      /* CAN register init */
      CAN_DeInit();
      CAN_StructInit(&CAN_InitStructure);
    
      /* CAN cell init */
      CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
      CAN_InitStructure.CAN_ABOM=DISABLE;
      CAN_InitStructure.CAN_AWUM=DISABLE;
      CAN_InitStructure.CAN_NART=DISABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失) 
      CAN_InitStructure.CAN_RFLM=DISABLE;
      CAN_InitStructure.CAN_TXFP=DISABLE;
      CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
      //CAN_Mode_LoopBack
      //CAN_Mode_Normal
      CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
      CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
      CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
      CAN_InitStructure.CAN_Prescaler=2;
      CAN_Init(&CAN_InitStructure);
#ifdef can_id_filter
       /* CAN filter init */
      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=slave_id<<5;//过滤器标识符
      CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;//过滤器屏蔽标识符
      CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc;
      CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;//选择FIFO0
      CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
      CAN_FilterInit(&CAN_FilterInitStructure);//进入初始化函数
#else
      /* CAN filter init */
      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;//过滤器标识符
      CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符
      CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
      CAN_ITConfig(CAN_IT_FMP0, ENABLE);//使能指定的can中断
}
 
 
void CAN_DeInit(void)
{
  /* Enable CAN reset state */
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, ENABLE);
  /* Release CAN from reset state */
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, DISABLE);
}
2、发送程序
unsigned char CAN_PushMessage(CAN_MSG  *pTransmitBuf )
{
  u8 TransmitMailbox=0;
  CanTxMsg TxMessage;
  if(pTransmitBuf -> LEN > 8)
  {
       return  1;
  }
  /* transmit */
  TxMessage.StdId=pTransmitBuf ->StdId;//用来设定标准标识符(0-0x7ff,11位)
  TxMessage.ExtId=pTransmitBuf ->ExtId;
  TxMessage.RTR=  pTransmitBuf ->RTR;//设置RTR位为数据帧
  TxMessage.IDE=  pTransmitBuf ->IDE;//标识符扩展位,为标准帧
  TxMessage.DLC=  pTransmitBuf ->LEN;//设置数据长度
  //根据DLC字段的值,将有效数据拷贝到发送数据寄存器
  memcpy(TxMessage.Data, pTransmitBuf ->BUF,pTransmitBuf ->LEN);
  TransmitMailbox = CAN_Transmit(&TxMessage);
 // TxMessage.Data[1]=(data & 0xff00)>>8;
  return 1;
}
3、中断接收程序
void USB_LP_CAN_RX0_IRQHandler(void)
{
  //清空can接收缓存
  CanRxMsg RxMessage;
  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;//CAN过滤主控制寄存器
  memset( &RxMessage.Data[0],0,8);
  //can总线接收数据函数
  CAN_Receive(CAN_FIFO0, &RxMessage);
  //将接收到的数据写于modbus的寄存器1
  //modbus_regester[1]=(RxMessage.Data[0]<<8)|(RxMessage.Data[1]);
 // if((RxMessage.StdId==slave_id) && (RxMessage.ExtId==0x00) && (RxMessage.IDE==CAN_ID_STD))
  {
    //将can接收标志位置1,表示从卡应经接收到一个can报文
    flag_can_recv=0;
    memcpy(can_rx_data,&RxMessage.Data,RxMessage.DLC);
      flag_can_recv=1;
  }
}
4、can总线的id过滤

对扩展数据帧过滤:

CAN_FilterInitStructure.CAN_FilterNumber   = 0; 
CAN_FilterInitStructure.CAN_FilterMode     = CAN_FilterMode_IdMask; 
CAN_FilterInitStructure.CAN_FilterScale    = CAN_FilterScale_32bit; 
CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)CAN_ID<<3)&0xFFFF0000)>>16; 
CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; 
CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF; 
CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF; 

对标准数据帧过滤:

CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)CAN_ID0<<21)&0xFFFF0000)>>16; 
CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF; 
CAN_FilterInitStructure.CAN_FilterMaskIdHigh   = 0xFFFF; 
CAN_FilterInitStructure.CAN_FilterMaskIdLow    = 0xFFFF;

假如要对标准远程帧进行过滤,那么:

只需要将

CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF; 改成:

CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xFFFF;

5、can总线的帧格式

数据帧格式:

远程帧格式:

6、can总线的逻辑电平

can总线的物理连接有两根线:CANH和CANL,以差分的形式输出。

(有的时候有地线,作为屏蔽线使用)

can总线的高电平 3.5v,表示逻辑0

can总线的低电平 1.5v,表示逻辑1

7、CAN总线的波特率计算

can时钟是RCC_APB1PeriphClock,要注意CAN时钟频率 
CAN波特率 = RCC_APB1PeriphClock/CAN_SJW CAN_BS1 CAN_BS2/CAN_Prescaler; 
如果CAN时钟为8M, CAN_SJW = 1,CAN_BS1 = 8,CAN_BS2 = 7,CAN_Prescaler = 2 
那么波特率就是=8M/(1 8 7)/2=250K 

8、can总线的仲裁机制

根据仲裁来判断优先级:

(1) 若在同一时刻,标准格式的报文与扩展格式的报文同时抢占总线,且它们的基础ID相同,则发标准格式的报文节点就会PK成功。这是因为扩展格式在基本ID后,紧接着是SRR位,与IDE位,且这两位都是隐性位。而在标准格式中,这两位分别对应的位为RTR与r1,其中RTR既可以为隐性位,也可以为显性位,,但是r1必须为显性位。由仲裁规则可以此时标准帧必定胜出。

(2)  同理,如果在同一时刻,具有相同格式,且具有相同ID的数据帧与远程帧争夺总线控制权,那么数据帧必定胜出。因为RTR显性表示数据帧,隐性表示远程帧。


stm32的can总线的配置如下:
      CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
      CAN_InitStructure.CAN_ABOM=DISABLE;
      CAN_InitStructure.CAN_AWUM=DISABLE;
      CAN_InitStructure.CAN_NART=DISABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失) 
      CAN_InitStructure.CAN_RFLM=DISABLE;
      CAN_InitStructure.CAN_TXFP=DISABLE;
      CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
      //CAN_Mode_LoopBack
      //CAN_Mode_Normal
      CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
      CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
      CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
      CAN_InitStructure.CAN_Prescaler=2;

      CAN_Init(&CAN_InitStructure);
       /* CAN filter init */
      CAN_FilterInitStructure.CAN_FilterNumber=0;//选择过滤器0
      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器被设置为标识符屏蔽模式
      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出过滤器位宽为32位
 
下面根据设置的参数不同来决定can总线can总线的配置情况:
1、对扩展数据帧进行过滤:(只接收扩展数据帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
(注:标准帧数据帧、标准远程帧和扩展远程帧均被过滤)
2、对扩展远程帧过滤:(只接收扩展远程帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
3、对标准远程帧过滤:(只接收标准远程帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
4、对标准数据帧过滤:(只接收标准数据帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
5、对扩展帧进行过滤:(扩展帧不会被过滤掉)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFC;
6、对标准帧进行过滤:(标准帧不会被过滤掉)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFC;
注:slave_id为要过滤的id号。

基于stm32的can总线彻底研究的更多相关文章

  1. stm32之can总线过滤器研究

    stm32的can总线的配置如下:       CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式      CAN_InitStructure.CAN_A ...

  2. 【转】STM32 FSMC总线深入研究

    原文:http://group.chinaaet.com/116/48112 由于CPU与FPGA通信的需要,以及对8080总线的熟悉,首选采用了STM32的FSMC总线,作为片间通信接口.FSMC能 ...

  3. 基于STM32的uCGUI移植和优化

    基于STM32的uCGUI移植和优化 首先在开始这个说明之前,要简要说明下具体的环境: 编译工具:MDK4.20 开发板:安富莱v2版开发板 调试器:JLink  v8盗版 移植篇 相信大家有移植经验 ...

  4. 温湿度监测系统设计:基于 STM32 的温湿度变送器的设计与实现

    前言:这个是2018年上半年完成的,这里只贴出硬件设计部分,软件设计部分可以看上位机说明书. 设计总说明 随着科学技术的不断发展,高集成度.高精度.高可靠性的一体化温湿度变送器开始 得到广泛的应用.同 ...

  5. STM32的FSMC总线驱动ili9341,掉电重启无法正常显示的问题

    问题描述 通过STM32的FSMC总线驱动ili9341,程序调试和刚下载的时候,显示完全正常.可是就在我掉电关机,重新启动的时候就完全跑飞了.这令我非常疑惑.以下是我的FSMC总线配置程序, sta ...

  6. 基于STM32的uCOS-II移植详解

    百度:基于STM32的uCOS-II移植详解 源:基于STM32的uCOS-II移植详解

  7. 基于STM32的USB枚举过程学习笔记

    源:基于STM32的USB枚举过程学习笔记 基于STM32的USB枚举过程学习笔记(一) 基于STM32的USB枚举过程学习笔记(二) 基于STM32的USB枚举过程学习笔记(三) 基于STM32的U ...

  8. ARM开发(2)基于STM32的蜂鸣器

    基于STM32的蜂鸣器 一 蜂鸣器原理:  1.1 本实验实现1个蜂鸣器间隔1S鸣叫.  1.2 实验思路:根据电路图原理,给蜂鸣器相关引脚赋予高低电平,实现电路的导通,使蜂鸣器实现鸣叫或不鸣.  1 ...

  9. 微服务实战(三):落地微服务架构到直销系统(构建基于RabbitMq的消息总线)

    从前面文章可以看出,消息总线是EDA(事件驱动架构)与微服务架构的核心部件,没有消息总线,就无法很好的实现微服务之间的解耦与通讯.通常我们可以利用现有成熟的消息代理产品或云平台提供的消息服务来构建自己 ...

随机推荐

  1. React-Native 之 Modal介绍与使用

    前言 遗漏的常用组件,刚发现官方有提供,这边也来介绍一下. 如本文有错或理解偏差欢迎联系我,会尽快改正更新! 如有什么问题,也可直接通过邮箱 277511806@qq.com 联系我. 本章涉及资源下 ...

  2. 03_Linux文件和目录

    一.Linux目录结构 /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录.所有的东西都是从这里开始.当你在终端里输入"/home",你其实是在告诉电脑,先从/( ...

  3. Go笔记-流程控制

    [if] if 是用于测试某个条件的语句,如果该条件(逻辑型或布尔型)成立,则会执行大括号内的代码,第一个大括号必须和if 或者else同行,否则非法 // 方式1 if condition { // ...

  4. RChain的Casper共识算法

    RChain的Casper共识算法是基于Vlad Zamfir的correct-by-construction共识协议和CTO Greg Meredith和其他RChain成员讨论而来的.他们还为Ca ...

  5. HDU 4372 Count the Buildings [第一类斯特林数]

    有n(<=2000)栋楼排成一排,高度恰好是1至n且两两不同.现在从左侧看能看到f栋,从右边看能看到b栋,问有多少种可能方案. T组数据, (T<=100000) 自己只想出了用DP搞 发 ...

  6. iconfont 怎么在项目中使用图标库

    iconfont是很多设计以及前后端人员编写页面时经常用到的网站,阿里不仅为我们提供了免费的图标库,并且有一套完整的图标库体系.很多初学者只知道从图标库中下载图标放入项目中,但在实际项目应用中,过多的 ...

  7. linear-grident的属性和使用以及对颜色后面参数(百分比)的理解

    linear-grident的属性和使用   css3新增Gradient属性,用来增加渐变的效果,渐变分为线性渐变 linear-grident 和 径向渐变 radial-grident,这篇文章 ...

  8. 企业级docker仓库Harbor部署

    1.安装环境下载离线安装包地址https://github.com/vmware/harbor/releases/yum install -y dockerpip install -i https:/ ...

  9. 一个客户端一键安装环境和服务的shell脚本

    #!/bin/bash basepath=$(cd `dirname $0`; pwd)SHELL_DIR="${basepath}/shell"PACKAGE_DIR=" ...

  10. laravel框架基础知识点

    一.数据库:DB    1.db查    DB::table('msg')->where('id','>',$id)->get()       查询单行    DB::table(' ...