
前言+ [2 \* J; @$ v/ I, o 学习了 STM8 的 CAN 总线的 IdMask 模式。在 CAN 协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时-根据标识符的值决定软件是否需要该报文;如果需要,就拷贝到 RAM 里;如果不需要,报文就被丢弃且无需软件的干预。为满足这一需求,beCAN 为应用程序提供了个可配置的、位宽可变的 6 个(0-5)过滤器组,用于只接收那些软件需要的报文。硬件过滤的做法节省了 CPU 开销,否则就必须由软件进行过滤,从而占用一定的 CPU 资源。 一、IdMask 模式* I0 j- D; a- s) d 首先,需要明白 IdMask 的作用: 举个例子吧,过滤器长度为 32 位,模式为屏蔽模式,假如我要发送的标示符为 0x1314;那过滤器设置如下 1、过滤器完全无效 接收到的标示符全部通过 0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 01005 |. j* A) X3 @! z3 L R CAN_Filter xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx CAN_FilterMask 0000 0000 0000 0000 0000 0000 0000 0000! Z e1 U3 B; } 因为 CAN_FilterMask 屏蔽寄存器所有位都是 0 ,对应标识符全为“不关心”,也就是接收到数据的 ID(标识符)不用与CAN_Filter 寄存器的任何一位进行匹配。' X! t: \* z$ `. `* P9 g 2、过滤器完全有效 接收到的标识符要跟据 CAN_FilterMask 寄存器指定需要匹配的位进行与 CAN_Filter 比较 * N4 D4 a4 P/ j, c* e8 S 部分匹配 0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100 CAN_Filter xxxx xxxx xxxx xxxx xxxx xxx1 xxxx xxxx) s- ]2 M6 |5 Z' N- | CAN_FilterMask 0000 0000 0000 0000 0000 0001 0000 0000 CAN_FilterMask 寄存器指定接收到的标示符要与第 8 位进行匹配,其他位不管。也就是说接收到的标示符第 8 位必须为 1,否则报文就会被丢弃。& K9 a% K/ B" B a1 S. C 2 |: O& o: E; W, {* z- ` 全部匹配 0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100 CAN_Filter 0000 0000 0000 0000 0000 0011 0001 0100; w; r3 x' B8 O1 S+ V# v2 h CAN_FilterMask 1111 1111 1111 1111 1111 1111 1111 1111 这种情况最为严格,接收到的标示符必须每一位都得与过滤器中的标示符的每一位进行匹配,有一位不对报文就会被丢弃。 (这个标示符匹配的工作是 CAN 模块内部硬件自动完成的) , W/ T" n7 O! F3 {, j 1 q: c) n! L5 J" v 二、IdMask 库代码" Y* Q5 d0 A2 y) _+ |# r+ h, X: r 本程序中,使用的软件代码是: 软件: \STM8S_StdPeriph_Lib\Project\STM8S_StdPeriph_Examples\CAN\CAN_Networking 路径下面的代码,5 j9 D+ N% y; @4 Q 硬件 STM8/128 EVAL 板子,上面的 MCU 位 STM8S208MBT6B ; 程序里面打开了接收的中断:, x, ?8 q3 i+ i( ~6 r( j; C7 n ) {/ o/ j: a7 Z/ A ![]() # \5 D9 j4 X5 B9 [; |' u 所以为了能够更有效的操作实践这一功能,我使用了: 3 N3 [8 f G7 F5 @4 t9 Y ![]() 如上图的,CAN 总线的分析仪器 USB-CAN200 ;以及它的上位机: 在这里需要说明一点, ' n" N+ z: @) ~ ![]() 将 R0+与 R0-相短接,则内部的 120 欧姆的电阻会被接入总线,不需要画蛇添足,在 R0+与 R0-之间自己再找一个 120 欧姆的电阻外部接上!!!! ![]() 1 @, p/ j6 t6 b4 e$ d' E 在接收中断里面已经有现成的对标准桢结构;所以设置好,Idfliter 或者 Idmask 就可以;4 I1 r& S) p9 v; L3 Q8 t8 Y8 c ![]() 也就是上面的 这一段函数; 按照刚才的理解, 如果我的扩展 id 是 0x12345678 ;想只接收 0x12xxxxxx 的标识符号,那么是否填入 CAN_FilterID1 = 0x12 ; CAN_FilterIDMask = 0xFF 就可以了呢? 本以为是这样,结果通过上位机发出去之后,led 板上的符号并没有变化;说明并没有接收到; 这是为什么呢?3 J$ t: f" |, v+ [# t8 n+ p/ }2 {9 s' [ " h8 D: j$ h K+ D 三、分析( ~. x4 J3 i1 K; l+ q, ^ 8 q& s1 \' x, `7 A- ?0 J% i1 l ![]() 所以对于扩展的 ID 号码它有 29 位,但是程序中设计的过滤器位 32 位,所以:: A8 v2 ~+ p; v' o3 {5 P 如果假设扩展 id 为 0x12345678 (0001,0010,0011,0100,0101,0110,0111,1000) - q) D% _1 q. g) c% ~4 B. k ![]() 所以扩展 id 的顺序填入如上图所示意,这儿假设的: RTR 位我们设置为 0 表示数据帧,IDE 位设置为 1 表示扩展 ID,因为我们的 ID 是 29 位的,所以 RTR = 0; IDE = 1;& p7 t5 k! @& J9 o- N 再来看我们参考手册中,定义的 : ![]() . d6 X1 P7 D- m- {3 m& |, `4 s+ K 将上面数据中的标示符号位再填入到 figure 的表过滤器中: " P0 p, p# `7 n7 \% o% O ![]() 所以可以看到颜色的顺序已经被打乱了,8 S1 s+ q( b: i# T( i( K, M* u 如果要关心到具体的某一个比特位置;如果要过滤让它只接收 0x12xxxxxx 的表示符号; 这时候要根据它实际在 identify 中的位置去修改 idmask ; 前八个比特,对应的就是黄色和绿色的部分,' D* r: q2 _$ T/ a: H6 z 所以其他的颜色,可以都填 0 表示不需要关心,则这里填入:1 1 1 1 ,1 x x x,我们这里 填入 0xF8 ; 即:
同理,对于下面的配置是只接收标准 id= 0x321(0011,0010,0001)的 ID(也是 32 位过滤器),' ~8 G1 R. H" B5 L: i 因为也是数据帧,所以 RTR = 0,标准的 id,所以 IDE = 0 ;所以填入到: ![]()
如下图,测试通过; ![]() ; Z( X: l0 p) V3 b 四、附录8 H$ S, F. Y* I' e 在 CAN 规范中并未定义代表逻辑电平的物理状态(例如电压),iCAN 网络使用符合 ISO11898-2 标准的电平信号,典型地,CAN 总线为“隐性”(逻辑 1)时,CAN_H 和 CAN_L 的电平为 2.5V(电位差为 0V);CAN 总线为“显性”(逻辑 0)时,CAN_H 和 CAN_L 的电平分别是 3.5V 和 1.5V(电位差为 2.5V).- |; K* E9 B1 `2 z 识别符& v/ e! Z! J4 A! H' l 识别符—标准格式 识别符的长度为 11 位,相当于扩展格式的基本 ID(Base ID)。这些位按 ID-28 到 ID-18 的顺序发送。最低位是 ID-18。7 个最高位(ID-28 - ID-22)必须不能全是“隐性”。5 o+ i" D$ O1 O Y8 s) Q; H3 \. W& p! N 识别符—扩展格式! y1 \6 s$ k k* v6 y( X6 } 和标准格式形成对比,扩展格式由 29 位组成。其格式包含两个部分:11 位基本 ID、18 位扩展 ID。 基本 ID:基本 ID 包括 11 位。它按 ID-28 到 ID-18 的顺序发送。它相当于标准识别符的格式。基本 ID 定义扩展帧的基本优先权。 扩展 ID:扩展 ID 包括 18 位。它按 ID-17 到 ID-0 顺序发送。 标准帧里,识别符其后是 RTR 位。4 k( N# t w ] RTR 位(标准格式以及扩展格式)+ X; {' A) s! Y) R2 `4 y1 ~2 c( H7 M RTR 的全称为“远程发送请求位(Remote Transmission Request BIT)”。 RTR 位在数据帧里必须为“显性”,而在远程帧里必须为“隐性” 扩展格式里,基本 ID 首先发送,其次是 IDE 位和 SRR 位。扩展 ID 的发送位与 SRR 位之后。 SRR 位(扩展格式)( A* D& P" W3 A/ D3 l SRR 的全称是“替代远程请求位(Substitute Remote Request BIT)”。5 d+ A" V s0 Y, M* Y SRR 是一隐性位。它在扩展格式的标准帧 RTR 位位置,因此代替标准帧的 RTR 位。因此,标准帧与扩展帧的冲突是通过标准帧优先于扩展帧这一途径得以解决的,扩展帧的基本 ID(参见以下的“扩展识别符”)如同标准帧的识别符。 IDE 位(扩展格式); n/ g+ |$ n5 P8 x- D IDE 的全称是“识别符扩展位(Identifier Extension Bit)” ; t! f0 j+ B; B# Q! w) t. T: u( I IDE 位属于: - 扩展格式的仲裁场% @0 z, N# o$ q5 N! T) K4 J - 标准格式的控制场 标准格式里的 IDE 位为“显性(逻辑 0)”,而扩展格式里的 IDE 位为“隐性”。! k& S$ c X* c2 ]; Y2 k 1 u$ r# b% F+ H) Q 在标识符列表模式下,屏蔽寄存器当作标识符寄存器用。因此,使用 2 个标识符来代替上面的标识符加屏蔽位的方式。接收报文标识的每一位都必须跟过滤器标识符相同。; X I* h2 c; H- l5 u 设置过滤器 0 只接收 ID 为 0x1828A0EF 和 0x1828A0EE 的数据帧。(工作在标识符列表模式), ~+ l' B' N; o& K6 }1 c6 P; w 首先我们把这两个 ID 写成二进制:) `2 Y' t/ e( A4 [# m 0x1828A0EF: 0001 1000 0010 1000 1010 0000 1110 1111 0x1828A0EE: 0001 1000 0010 1000 1010 0000 1110 1110 然后我们将 0x1828A0EF 二进制的格数据组成如上图 mapping 所示的格式/ K% y# P7 M2 t1 d Cna_fxr1:1100 0001 0xc1) R6 Q% v; O) ~8 n7 T. s Cna_fxr2:0100 1001 0x49 //这里有个 RTR 位我们设置为 0 表示数据帧,IDE 位设置为 1 表示扩展 ID," J/ Q5 Q) w' @3 i. ]4 S Cna_fxr3:0100 0001 0x41 Cna_fxr4:1101 1110 0xDE 这时我们工作在标识符列表模式,identifier/Mask 的寄存器相当于 identifier 使用。 再将 0x1828A0EE 二进制的格数据组成如上图 mapping 所示的格式 Cna_fxr5:1100 0001 0xc1; y3 v, f! p4 M; R Cna_fxr6:0100 1001 0x49 //这里有个 RTR 位我们设置为零表示数据帧,IDE 设置为 1 表示扩展 ID0 C% z, S& |# } Cna_fxr7:0100 0001 0x41 Cna_fxr8:1101 1100 0xDC 以下是用库函数配置的程序小片段:. n$ A' V, @# a6 v3 S* {( b CAN_FilterNumber =CAN_FilterNumber_0; //注意这是的模式是跟 IdMask 例不一样的
相信看到这是你对这两种工作模式有一定的了解了吧!。 好了,例子就说完了,8 位 16 位的位宽是相似的,和上面的分析是一样的;。0 ]. c- o' B- r8 r0 @$ ? & I, J4 D& d! Y+ Q |
STM8自学笔记(推荐STM8很好的入门电子书)
基于STM8的DALI (数字可寻址调光协议)
分享STM8 风驰光盘的资料,是完整的(包括原理图+例程+PDF注释)
《无刷直流电机控制应用 基于STM8S系列单片机》
STM8S库函数中文参考 小软件
【资料分享】STM8L的智能手持血糖监测设备的源码
基于STM8S207工程模板
【培训资料】STM8系列PPT培训资料
STM8S 直流电机例程及相关资料
无刷直流电机控制应用+基于STM8S系列单片机---电子书