STM32的CAN应用指南 http://blog.sina.com.cn/s/blog_0414b7360101osq1.html

CAN基本知识:

CAN协议的特点:

1、  多主机控制。在总线空闲时,所有单元都可以发送消息,若两个以上同时开始发送消息,根据标识符来决定优先级。优先级高的先发送。

2、  系统的若软性。与总线相连的单元没有类似地址的信息。因此在总线上增加单元时,应用层程序基本不需要改变。

3、  通信速度快,通信距离远。最高1Mbps(距离小于40M),最远可达10Km(速率低于5Kbps)。

4、  具有错误检测、错误通知和错误恢复功能。所有单元都可以检测错误,检测出错误的单元会立即同时通知其他所有单元,正在发送消息的单元一旦检测出错误,会强制结束当前的发送。前置结束发送的单元会不断反复地重新发送该消息直到发送成功。

5、  故障封闭功能。CAN可以判断出错误的类型是总线上的数据错误还是持续的数据错误。由此功能,当总线上发生持续数据错误时,可以将引起此故障的单元从总线上隔离出去。

6、  连接节点多。CAN总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。单实际上受到时间延迟和电气负载的限制。降低通信速度,可连接单元增加。反之,反之。

STM32的CAN 时间特性(有关波特率):

与CAN2.0B的协议内容相比,STM32的CAN时间特性稍微有些区别。STM32把传播时间段和相位缓冲段1合并了,因此STM32的CAN一个位只有3段:同步段(SYNC_SEG)、时间段1(BS1)和时间段2(BS2)。STM的BS1段可以设置为1-16个时间单元,刚好等于传播时间段和相位缓冲段1之和。

波特率=1/正常的位时间

正常的位时间=1×tq+tbs1+tbs2

其中:tbps1=tq×(TS1[3:0]+1)

tbps2=tq×(TS2[3:0]+1)

tq=(BRP[9:0]+1)×tpclk

tq是一个时间单元

tpclk是APB时钟的时间周期

因此,我们只需要知道BS1和BS2的设置,以及APB1的时钟频率(一般为36MHz),就可以方便的计算出波特率。比如设置TS1=6,TS2=7和BRP=4,在APB1频率为36MHz的条件下,即可得到CAN通信的波特率=36000/[(7+8+1)*5]=450Kbps。

要用到的寄存器:

主控制寄存器CAN_MCR:控制进退初始化,发送FIFO优先级。

时序寄存器CAN_BTR:用来设置分频、Tbps、Tbs2以及Tsjw等非常重要的参数,直接决定了CAN的波特率。另外还可以设置工作模式(静默模式、环回模式)等。

发送邮箱标识符寄存器CAN_TIxR:该寄存器用来设置标识符(包括扩展标识符),另外还可以设置帧类型。

发送邮箱数据长度和时间戳寄存器CAN_TDTxR:用来设置数据长度。

发送邮箱低字节数据寄存器CAN_TDLxR:用来存储将要发送的数据,只能存储低4个字节。

发送邮箱高字节数据寄存器CAN_TDHxR:用来存储将要发送的高4个字节。

接收FIFO邮箱标识符寄存器CAN_RIxR:该寄存器用来保存接收到的报文标识符等信息,通过读该寄存器获取相关信息。

接收FIFO邮箱数据长度和时间戳寄存器CAN_RDTxR;接收FIFO邮箱低字节数据寄存器CAN_RDLxR;接收FIFO邮箱高字节数据寄存器CAN_RDHxR,同发送。

过滤器模式寄存器CAN_FM1R:设置各滤波器组的工作模式,对28个滤波器组的工作模式,都可以通过该寄存器设置,不过该寄存器必须在滤波器处于初始化模式下才可以设置。

过滤器位宽寄存器CAN_FS1R:用于设置各滤波器组的位宽。其他同上。

上述两个寄存器用来设置过滤器。

如FSCx=1,FBMx=0:那么其中第x个寄存器组就被设置为1个32位过滤器-标识符屏蔽,此时本滤波器组可以设置成1个过滤器。(见参考手册P432)

如FSCx=1,FBMx=1:那么其中第x个寄存器组就被设置为2个32位过滤器-标识符列表,此时本滤波器组可以设置成2个过滤器。

如FSCx=0,FBMx=1:那么其中第x个寄存器组就被设置为2个16位过滤器-标识符屏蔽,此时本滤波器组可以设置成2个过滤器。

如FSCx=0,FBMx=0:那么其中第x个寄存器组就被设置为4个16位过滤器-标识符列表,此时本滤波器组可以设置成4个过滤器。

28个过滤器组可以被设置为远大于28个过滤器数目。

每个FIFO各自对其关联的过滤器进行编号。过滤器组关联设置通过寄存器CAN_FFA1R即过滤器FIFO关联寄存器来设置。

过滤器激活寄存器CAN_FA1R:该寄存器来控制过滤器的激活与否。1开启0关闭。

过滤器组i的寄存器x CAN_FiRx:用来存放过滤参数。

STM32 CAN总线初始化步骤:

1、  配置相关引脚的复用功能,使能CAN时钟。

使能CAN时钟,通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,设置为上拉输入(CAN_RX),设置为复用输出(CAN_TX),并使能PA口的时钟。

2、  设置CAN工作模式及波特率等。

先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位,再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。最后设置INRQ为0,退出初始化模式。

3、  设置滤波器。

设置CAN_FMR的FINIT位,让过滤器组工作在初始化模式下,然后设置滤波器组0的工作模式以及标识符ID和屏蔽为。最后激活滤波器。并退出滤波器初始化模式。如果用到中断,还要配置中断模式。

具体的:

如何初始化CAN:

1、  使能相关时钟(PORTA时钟,CAN时钟),初始化引脚RX和TX。

2、  设置CAN_MCR,退出睡眠模式,同时设置参数。基本是所有位清零。关于睡眠模式,CAN在复位后都是进入睡眠模式,当然也可以设置自动唤醒模式等。

3、  请求CAN进入初始化模式,对CAN_MSR的位0置1。等待进入初始化,检验MCR位0 INAK的值,当真正变为1的时候,在进行下一步。因为这个过程可能不是瞬间完成的,如果当前有CAN活动,就会等到本次活动结束后再进入初始化模式,硬件对INAK位置1。

4、  设置CAN_MCR的各位,位2-位7。设置位时序寄存器CAN_BTR的各位,在这里可以设置静默模式、环回模式、波特率。

5、  请求CAN退出初始化模式。设置MCR的位0.等待完全退出初始化模式,通过检验MSR的位。

6、  初始化过滤器(初始化寄存器不是在CAN初始化模式下进行的,而是过滤器组工作到初始化模式)。设置过滤器主控寄存器CAN_FMR的位0,使过滤器组工作在初始化模式。

7、  设置过滤器激活寄存器CAN_FA1R来禁用相应的过滤器,因为只有对相应位清零或者对CAN_FME的FINIT位设置位1,才能修改相应的过滤器寄存器CAN_FiRx。

8、  设置过滤器模式CAN_FM1R(标识符屏蔽模式or标识符列表模式);设置过滤器位宽寄存器CAN_FS1R(1个32位的过滤器or2个16位的过滤器);设置过滤器FIFO关联寄存器CAN_FFA1R(过滤器关联到FIFO0还是FIFO1当中)。

9、  填写过滤器标识和屏蔽。通过设置寄存器CAN_FiR1和CAN_FiR2来设置标识(ID)和屏蔽(MASK)。

10、              激活过滤器,CAN_FA1R位0设置为1。

11、              过滤器进入正常工作模式,CAN_FMR位0清零

如何发送一个报文:

1、  判断三个邮箱中哪个为空(CAN_TSR的位26 位27 位28),哪个为空用哪个?如果没有空邮箱,则退出本次发送过程。

2、  清除发送邮箱标识符寄存器(因为要填写新的标识符)。

3、  设置发送邮箱的标识符寄存器CAN_TIxR。

4、  设置发送邮箱的数据长度和时间戳寄存器CAN_TDTxR。

5、  填写要发送的数据,即设置发送邮箱高低字节数据寄存器CAN_TDHxR和CAN_TDLxR。

6、  对标识符寄存器CAN_TIxR的位0即TXRQ位置1,来请求发送邮箱的数据。当数据发送完成后,硬件对其清零。

7、  查询发送状态,通过查询发送状态寄存器CAN_TSR。基本查询三个状态参数。位0 RQCP1邮箱0(不一定是0,看使用的是哪个邮箱了)请求完成;位1 TXOK0邮箱0发送成功;位26 发送邮箱0位为空,没有等待发送的报文。当这三项都成功后,返回发送成功。

如何接收一个报文:

1、  查询FIFO里面是否存在有效报文,查询接收FIFO0寄存器CAN_RF0R的位1:0 当前接收FIFO中存放的报文数目。如果有数据,下一步将数据读出。

2、  判断标识符类型,接收来的报文是采用标准标识符还是扩展标识符。CAN_RIxR的位2 IDE。

3、  根据不同类型的标识符来做不同的操作。具体可查看CAN_RIxR的位31:3。扩展标识符低字节存在位20:3。扩展标识符或标准标识符存在位31:21。扩展标识符39位,标准标识符11位。

4、  查询CAN_RIxR的位1 来判定是数据帧还是远程帧。

5、  查询CAN_RDTxR位3:0 获取数据帧的数据长度。

6、  读取接收FIFO邮箱高低字节数据寄存器CAN_RDLxR和CAN_RDHxR。

7、  释放FIFO邮箱。CAN_RF0R的位5。

如何使CAN接收工作在中断模式下:

1、  通过寄存器CAN_IER来设置中断使能,正常情况下使用位1,FMPIE0:FIFO0消息挂号中断使能置1。

2、  中断分组

3、  写中断处理函数(较自由)。可以通过设置中断使能来屏蔽有写中断,如果中断都打开的话就需要在中断处理函数里面来进行判断处理。因为每个CAN只有4个主中断,即发送中断、接收FIFO0中断、接收FIFO1中断和SCE中断。

时间: 2024-11-07 09:10:54

STM32的CAN应用指南 http://blog.sina.com.cn/s/blog_0414b7360101osq1.html的相关文章

Matlab read_grib.r4 安装新方法(转自:http://blog.sina.com.cn/s/blog_9f36648b010179s7.html)

最近,打算用Matlab处理些GRIB格式的文件,需要在Matlab中添加read_grib.m文件,其实相当于是添加一个工具箱.read_grib.m的下载见:http://www.renci.org/~bblanton/files/ReadGrib/ 但是,要read_grib.m真正起作用,需要“安装”和“编译”两步. 按照网页上的说法,所谓安装,就是把下载下来的read_grib.r4.tar文件解压,然后将解压后的文件夹路径写到“startup.m”文件中.但是,我的Matlab201

windows: Access denied for user 'root'@'localhost' .....(转自新浪:http://blog.sina.com.cn/s/blog_40aff6390100jeke.html)

WINDOWS-XP 系统 mysql-5.1.22-noinstall-win32 提示:access denied for user 'root'@'localhost' using password yes 前几天都好好的,今天开机上来提示上面的这个错误,重启 MySQL 还是不可以. 在网上搜索了好久,总算找到详细的操作方法了.为了以后不再浪费时间,把她重新整理放到 Blog 里. 注意我这里的环境是 WINDOWS-XP 系统,LINUX 系统下的操作没有验证过,情况不清楚. 1. 管

MySQL存储过程详解 mysql 存储过程(转:http://blog.sina.com.cn/s/blog_52d20fbf0100ofd5.html)

转:http://blog.sina.com.cn/s/blog_52d20fbf0100ofd5.html mysql存储过程详解 1.      存储过程简介   我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它. 一个存储过程是一个可编程的函数,它在数据库中创建并保存.它可以有SQL语句和

已发布13集网站开发技术视频:http://blog.sina.com.cn/s/blog_67d27f340102vf7l.html

已发布13集网站开发技术视频:http://blog.sina.com.cn/s/blog_67d27f340102vf7l.html

matlab添加M_map工具箱(转 http://blog.sina.com.cn/s/blog_491b86bf0100srt9.html)

之前转载过matlab画世界地图的博文.最近正好用到.首先试了matlab自带的worldmap,感觉画出来的图形不尽如人意,比较杂乱.如下图. 略查阅了些资料,请教了Liangjing,一致推荐m_map.为了达到想要的效果,这次只要不再偷懒,下载M-Map工具箱(http://www.eos.ubc.ca/~rich/map.html)并进行安装.所幸过程比较顺利,现记录如下,回头把画出的效果图再添上.其他matlab的toolbox安装,也可参考进行. ------------------

C语言register关键字—最快的关键字 ---------------转自http://blog.sina.com.cn/s/blog_6a1837e90101128k.html

register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率.注意是尽可能,不是绝对.你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧,轮也可能轮不到你. 一.皇帝身边的小太监----寄存器 不知道什么是寄存器?那见过太监没有?没有?其实我也没有.没见过不要紧,见过就麻烦大了.^_^,大家都看过古装戏,那些皇帝们要阅读奏章的时候,大臣总是先将奏章交给皇帝旁边的

c++中的srand()和rand() 转载 自:http://blog.sina.com.cn/s/blog_624c2c4001012f67.html

今天看了同事写的小程序,发现了其中出现了srand()和rand()这两个我以前没有用过的函数,当然从名字可以看出肯定能随机数有关,于是网查资料知这两个函数配合一起使用来产生随机数的,哈哈,又长知识了,现将这两个函数的使用贴过来,以备以后查看使用. 这两个帮助生成伪随机数的函数包含在标准库 中,所以首先需在头文件中包含进来. 注意:在C语言中包含在标准库中.    函数一:int   rand(void):     从srand   (seed)中指定的seed开始,返回一个[seed,   R

教你如何查看CAD文件是哪个版本的来自http://blog.sina.com.cn/s/blog_4c9fa4dd0101il1v.html

教你如何查看CAD文件是哪个版本的 http://blog.sina.com.cn/s/blog_4c9fa4dd0101il1v.html (2013-03-10 22:24:52) 转载▼ 标签: 教育 分类: AutoCAD实用技巧 在工作中会遇到打开一张图纸时出现“图形文件无效”的提示,大部都是因为用低版本软件打开了高版本的图纸.而又如何真正确认该文件是用哪个版本创建的,以下教大家一个辨别的方法.正常的DWG文件可以通过记事本或者其他文本软件打开,看开头几个字节就知道版本号了 Versi

转:C++中命名空间污染注意点 blog.sina.com.cn/s/blog_af68a2c201015pqo.html

一. 为什么需要命名空间(问题提出) 命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中 常见的同名冲突. 在 C语言中定义了3个层次的作用域,即文件(编译单元).函数和复合语句.C++又引入了类作用域,类是出现在文件内的.在不同的作用域中可以定义相同名字的变量,互不于扰,系统能够区别它们. 1.全局变量的作用域是整个程序,在同一作用域中不应有两个或多个同名的实体(enuty),包括变量.函数和类等. 例:如果在文件中定义了两个类,在这两个类中可以有同名的函数.在引用时,为了区