CAN协议基础知识
) j. t) t8 }3 _) G( |I2C.SPI总线多用于短距离传输,协议简单,数据量少,主要用于IC之间的通讯,而 CAN 总线则不同,CAN(Controller Area Network) 总线定义了更为优秀的物理层、数据链路层,并且拥有种类丰富、简繁不一的上层协议。与I2C、SPI有时钟信号的同步通讯方式不同,CAN通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。
; ^% u8 l% \( s5 m
, ]' y/ L7 B0 `CAN物理层的形式主要分为闭环总线及开环总线网络两种,一个适合于高速通讯,一个适合于远距离通讯。CAN闭环通讯网络是一种遵循ISO11898标准的高速、短距离网络,它的总线最大长度为40m,通信速度最高为1Mbps,总线的两端各要求有一个* H4 b% w5 s- M z5 A
8 B1 ]. K6 `/ |9 {“120欧”的电阻来做阻抗匹配,以减少回波反射。3 b4 v, s- F; C) ?
% \6 y3 ?8 t8 w( O; }: K( O
" v8 w2 y g& ]9 J* b0 W* J. Q9 u闭环总线网络( P% M0 \. F- _2 \8 E
, D# f: @. Z7 {. ~; [6 E
2 L: G) E% s) B' \3 O/ z! J% ]/ _- n. i7 z! e
CAN开环总线网络是遵循ISO11519-2标准的低速、远距离网络,它的最大传输距离为1km,最高通讯速率为125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻。( ~ ?/ {% U0 O; H f
: P6 V: X! b4 B9 z4 G/ ^8 M( {3 H% l3 i( h s' h" |# i& d
开环总线网络& w- P8 G$ l1 x, {7 l5 ?0 O
- x+ ]. f4 _5 p& |6 S! m
) v2 k4 B% S" b2 A6 {: F8 ^, O6 I& i3 H+ r& f9 e" e
CAN总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于CAN通讯协议不对节点进行地址编码,而是对数据内容进行编码,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。
( z0 Y0 n2 T4 a' ~' D( d+ X4 \; z, M0 F
CAN通讯节点由一个CAN控制器及CAN收发器组成,控制器与收发器之间通过CAN_Tx及CAN_Rx信号线相连,收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。其中CAN_Tx及CAN_Rx使用普通的类似TTL逻辑信号,而CAN_High及CAN_Low是一对差分信号线,使用比较特别的差分信号。当CAN节点需要发送数据时,控制器把要发送的二进制编码通过CAN_Tx线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线CAN_High和CAN_Low线输出到CAN总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的CAN_High及CAN_Low信号转化成普通的逻辑电平信号,通过CAN_Rx输出到控制器中。5 b) L8 [% b( w9 v8 z# p. S
2 Q! T& B- {+ L( Q8 W1 h) A) r l9 v- N3 J6 M5 C: l
差分信号
4 Y7 C: Q4 `8 Y; I: Z. ~) d. R
4 @5 B! d: E% W* Y G差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0和逻辑1。4 j9 ]; |" V! E, M
! P; r7 Y, l5 ]$ S6 _
相对于单信号线传输的方式,使用差分信号传输具有如下优点:( _& w& }6 k; L" M! n
$ b# h/ }; L" F( h9 `7 E: A* 抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关心两个信号的差值,所以外界的共模噪声可以被完全抵消。
; V' S9 |* H) C) k* 能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。$ G5 w. Y$ ^. F* p) G+ i% h
* 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。
3 L( D. c5 X0 }0 e/ n% T+ l* 由于差分信号线具有这些优点,所以在USB协议、485协议、以太网协议及CAN协议的物理层中,都使用了差分信号传输。0 B+ h' L: e) ]
9 @2 m$ z( H" C; b' r
CAN协议中的差分信号4 J, w: U9 v' L5 ]
5 C6 O. i7 e5 v; O1 a. F0 ?8 cCAN协议中对它使用的CAN_High及CAN_Low表示的差分信号做了规定。以高速CAN协议为例,当表示逻辑1时(隐性电平),CAN_High和CAN_Low线上的电压均为2.5v,即它们的电压差V H -V L =0V;而表示逻辑0时(显性电平),CAN_High的电平为3.5V,CAN_Low线的电平为1.5V,即它们的电压差为V H -V L =2V。+ a. \3 T' ^3 d2 E$ A! Y/ }
& W/ K d/ {+ j, B5 e
! g6 [3 l: M, |% Z9 ~
! T6 A* m2 k- D$ T% U! J3 _+ O
( D1 u, J+ ]- e: D
CAN 总线的特点
' z0 R& j4 j( p+ r H; W5 C! M- k5 _" I* d: e& b' n. @
CAN 总线网络是一种真正的多主机网络,在总线处于空闲状态时,任何一个节点单元都可以申请成为主机,向总线发送消息。其原则是:最先访问总线的节点单元可以获得总线的控制权;多个节点单元同时尝试获取总线的控制权时,将发生仲裁事件,具有高优先级的节点单元将获得总线控制权。
. E2 R0 g% s& ~& ^* [/ |
+ v! n- P. s; X" `, \CAN 协议中,所有的消息都以固定的数据格式打包发送。两个以上的节点单元同时发送信息时,根据节点标识符(常称为 ID,亦打包在固定的数据格式中)决定各自优先级关系,所以 ID 并非表示数据发送的目的地址,而是代表着各个节点访问总线的优先级。如此看来,CAN 总线并无类似其他总线“地址”的概念,在总线上增加节点单元时,连接在总线的其他节点单元的软硬件都不需要改变。 C3 Q j% w- @* L
. o/ Q" A: j# S8 `) {8 j1 E
CAN 总线的通信速率和总线长度有关,在总线长度小于 40m 的场合中,数据传输速率可以达到 1Mbps,而即便总线长度上升至 1000m,数据的传输速率仍可达到 50Kbps,无论在速率还是传输距离都明显优于常见的 RS232、RS485 和 I2C 总线。
`, S* Q0 F* |1 N2 s* V
; S O# O0 }! C" l0 \% G对于总线错误,CAN 总线有错误检测功能、错误通知功能、错误恢复功能三种应对措施,分别应对于下面三点表述:所有的单元节点都可以自动检测总线上的错误;检测出错误的节点单元会立刻将错误通知给其他节点单元;若正在发送消息的单元检测到当前总线发生错误,则立刻强制取消当前发送,并不断反复发送此消息至成功为止。1 T' W0 C5 J& ~/ F
, i1 C, d' `0 J' NCAN 总线上的每个节点都可以通过判断得出,当前总线上的错误是暂时的错误(如瞬间的强干扰)还是持续的错误(如总线断裂)。当总线上发生持续错误时,引起故障的节点单元会自动脱离总线。
5 o' c \$ H1 Q% A$ o' R$ k# c0 o+ \
( L- m' q6 {& J/ xCAN 总线上的节点数量在理论上没有上限,但在实际上受到总线上的时间延时及电气负载的限制。降低最大通信速率,可以增加节点单元的连接数;反之,减少节点单元的连接数,则最大通信速率可以提高。
! t. v8 x! z+ S7 K; X8 e
3 b) @. C2 x$ I5 v/ E) SCAN总线的数据通信是以数据帧的格式进行的,而数据帧又是由位场组成的,其中每一个位又被划分为四段.即SS(SYNC SEG),PTS(PROP SEG--传播时间段),PBS1(PHASE SEG1--相位缓冲段1),PBS2(PHASE SEG1--相位缓冲段2).
' Q- G6 f( N" v4 g8 U# z7 o0 C! i
% D. T/ V% w; J+ j5 a2 _数据帧的结构图:
4 Z7 T' j2 q/ J- V( D
) {) H4 K U1 z+ H7 f
4 `/ K: ^4 ?" }$ V- O, H& u5 y& j# u; W6 d& F
图中D表示显性电平,R表示隐形电平.
* B# J; O, _' w* W3 [" V* x4 n6 ^) G6 i! G( e9 w
ID:高位在前,低位在后。
6 z* q, L1 L) b- y$ r" Y) y5 ~4 K: i% b
基本ID,禁止高7位都为隐性,即不能:ID=1111111XXXX。
6 N& D9 w, Y$ R/ H
5 Q. m' _2 B9 D+ CRTR,远程请求位。0,数据帧;1, 远程帧;
8 i6 x! E0 N/ A& h
" h! @8 }' V6 B# R- ySRR,替代远程请求位。设置为1(隐性电平);
8 r: u2 Q% H- `4 h0 E" Z/ H$ N# I
IDE,标识符选择位。0,标准标识符;1,扩展标识符;
% ^0 ]& p4 j! U& z# J
: u% X l5 w8 Z! x2 cr0,r1:保留位。必须以显现电平发送,但是接收可以是隐性电平。
1 n) M8 n: p9 ^0 l) `8 R ^0 A' {4 c% C' C9 }4 X
DLC:数据长度码。0~8,表示发送/接收的数据长度(字节)。
6 i7 {# r( J% K7 F- U T% X/ w7 n2 p
IDE,标识符选择位。0,标准标识符;1,扩展标识符;0 E* k& C3 `% E$ [# l# d
2 Q# A& G5 {# L' O
% V; J# k+ O: n5 Z9 j4 X. h
$ Y6 L: o$ }: j. ^9 R0 l位时序分解' J' e2 S$ S# B9 J$ i1 T( O3 P
' ~ C( Y: u' s) V为了实现位同步,CAN协议把每一个数据位的时序分解成SS段、PTS段、PBS1段、PBS2段,这四段的长度加起来即为一个CAN数据位的长度。分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq组成。
' p1 G, E' I$ C9 Q
3 }6 v1 v' i7 \1 }
H( x0 A9 @% ]: ]- x2 \$ G* s2 g. W: p
1 n3 S6 z4 Z/ `! n7 M' S4 C
7 `* X' s2 X0 z ^, o) r% [* T
STM32中的CAN接口
4 i7 h+ v" ` M2 [3 `7 B! V, T# \
. Q, y- e7 N! Q8 f8 Z7 {STM32的芯片中具有bxCAN控制器 (Basic Extended CAN),它支持CAN协议2.0A和2.0B标准。该CAN控制器支持最高的通讯速率为1Mb/s;可以自动地接收和发送CAN报文,支持使用标准ID和扩展ID的报文;外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有2个3级深度的接收FIFO,可使用过滤功能只接收或不接收某些ID号的报文;可配置成自动重发;不支持使用DMA进行数据收发。
& Z6 {4 c% G2 p' \
/ ~" ], R3 w5 M, R
% X: t7 \/ `2 D
@) T- \4 N) D1. CAN控制内核+ q" Z( \* B4 M& C" o I
2. CAN发送邮箱
6 ~* D9 O u* a( L5 b3. CAN接收FIFO/ {. l( m |3 [
4. 验收筛选器
5 z( Q1 `0 y. _2 Q! n7 c, V! |; Y
STM32有两组CAN控制器,其中CAN1是主设备,框图中的“存储访问控制器”是由CAN1控制的,CAN2无法直接访问存储区域,所以使用CAN2的时候必须使能CAN1外设的时钟。
% y+ D. p' m0 C4 ~2 c1 S# S0 i* j. i9 `5 ]$ {# H% Z$ o
STM32至少配备一个bxCAN(basic extend can )控制器,支持2.0A和2.0B协议,最高数据传输速率可达1M bps,支持11位标准帧格式和29位扩展帧格式的接收和发送,具备三个发送邮箱和两个接收FIFO,此wa此外还有三级可编程滤波器,STM32的bxCAN非常适应CAN总线网络y网络应用发展需求,其主要主要特征如下 :
$ R2 \" _1 |* S* ~: {
9 ]+ d2 Y \4 W w* 支持CAN协议2.0A和2.0B主动模式5 v5 d2 Y0 L* E
* 波特率最高可达1Mbps4 t3 q' L5 f Q2 E
* 支持时间触发通讯功能
( j+ ?: ]7 C9 y% C/ k* ]: a. ]
: K) h! F* ]- y+ Y2 o$ D数据发送特性:具备三个发送邮箱;发送报文的优先级可以通过软件配置,可记录发送时间的时间戳。
?$ n. u9 K! w; M: J& e3 W$ J9 Q
& ]5 W1 a- U. |& G; S$ J数据接收特性:具备三级深度和两个接收FIFO;具备可变的过滤器组,具备可编程标识符列表,可配置FIFO溢出处理方式,记录接收时间的时间戳
) `4 l6 x8 I) B, g4 x9 c1 H/ ?
1 Y+ G ?' B7 k7 m报文管理:中断可屏蔽;邮箱单独占有一块地址空间,便于提高软件效率。6 X$ @* |* W1 x6 u3 e2 b
) m; U, Q; l6 e$ d6 g# U* ?
本文的实验设计将利用STM32 的bxCAN控制器的环回工作模式,实现bxCAN控制器的自收发过程,并使用串口设备跟踪监视数据收发情况。6 V% o/ `. v( H7 `4 O
+ i* s8 v Q G& v
程序流程如下图
4 d2 X/ o, p& X' V5 ?. c6 }+ j9 Z
! B' P7 r( K8 ^# q
# q: Q/ h2 |; S8 F6 K6 c) l2 s
8 o7 |0 r0 `/ I# ]" q- T5 V( ^本程序设计主要围绕bxCAN控制器的初始化初始化配置展开,其要点罗列如下:
. v7 C" b* O; K9 o* O# u7 u I! d' P2 a l _" e- N
1. 初始化RCC寄存器,配置PLL输出72MHZ时钟,APB1总线频率为36MHZ,分别打开CAN,GPIO和USART1的设备时钟。
7 t/ J* l2 M* K' s0 Y E2. 设置CAN的Tx引脚(即PA12)为复用推挽模式,并设置Rx引脚(即PA1)为上拉输入模式,其中三个重要的参数如下配置:
# c2 T4 Z8 j0 A% l3 ]% G% P+ b6 Q" L- CAN_InitStructure.CAN_SJW配置为CAN_SJW_1tq;1 p) L7 R9 G0 I' X$ ]
- CAN_InitStructure.CAN_BS1配置为CAN_BS1_8tq;2 \( z7 I4 ?. Z8 c# w
- CAN_InitStructure.CAN_BS2配置为CAN_BS2_7tq;
复制代码 ! `6 B) B8 r6 l
3. 最后分频数配置为5,配置接受接受缓冲区标识符为0x00AA0000,配置过滤器为32位屏蔽位模式,过滤器屏蔽标识符为0x00FF0000.+ m# Z0 @( [# O4 r0 X* Q# d
4. 初始化USART设备% o2 X# P9 I1 Y
5. 使用扩展帧shu帧数据格式,ID为0xAA,数据长度长度为8! y6 g1 V& ?7 h+ D; V
7 y* H: j+ h5 p C
# I# S( W# k( H3 L# R) c
STM32的CAN控制器设计的重点集中在CAN寄存器组的初始化过程中,而CAN初始化的重点在于波特率的设置,过滤器的设置和位时序的设置,以下作详细叙述。
! P S6 C7 ^1 c1 |- r3 P, o8 Z# \% J
(1)CAN波特率的计算
8 Y: i G% w7 b: w, W
- z" _+ g, y- S/ f2 M5 R' `# k计算波特率是任何一种总线的zhon重要内容之一,CAN总线也不例外.从STM32微控制器的官方参考手册里可以查找到关于CAN波特率的计算公式如下." @0 V7 x# v" i' k
5 c6 ~0 S( b+ Y6 O" ]" d3 K- r
通过配置位时序寄存器CAN_BTR的TS1[3:0]及TS2[2:0]寄存器位设定BS1及BS2段的长度后,就可以确定每个CAN数据位的时间:. X z' p) ~ v* \4 A" t p9 b3 u. c
. c2 e3 Y* R" ]& T8 {; L/ ]+ S$ a
BS1段时间:
: |! C. `% i: s5 H, R6 A1 a6 e# w8 ?
T S1 =Tq x (TS1[3:0] + 1),
5 M* O" `9 G1 `, O( o# V3 ?9 R# R5 f# x n) P' v4 F
BS2段时间:+ O7 j: [! l2 @$ T, p% {. \
7 g6 d1 h. ^2 E* o! h( a
T S2 = Tq x (TS2[2:0] + 1),
% t5 J3 z+ p5 w! c! b4 I% D! S
! d Z( J+ x! F+ g2 x f6 \" Z w一个数据位的时间:9 o* k1 U) W. O4 f( d
6 B: C# g; R: Z' n' o5 i
T 1bit =1Tq+T S1 +T S2 =1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)= N Tq* i0 ~* t3 v5 w- L
5 K4 H7 D+ Y6 a, y% U1 l其中单个时间片的长度Tq与CAN外设的所挂载的时钟总线及分频器配置有关,CAN1和CAN2外设都是挂载在APB1总线上的,而位时序寄存器CAN_BTR中的BRP[9:0]寄存器位可以设置CAN外设时钟的分频值 ,所以:& ?( C |9 f/ e: |$ P0 g
4 q5 V! {4 j7 T5 u
Tq = (BRP[9:0]+1) x T PCLK
: `2 z( M; |" ?( i3 A
! D F. X1 I4 l3 V0 K% `其中的PCLK指APB1时钟,默认值为36MHz。% z1 m; a0 x) R# ]
: s% N' ?% p; { a2 ^* i最终可以计算出CAN通讯的波特率:
( a, Q- C) ]1 v* p& Q" [2 Y e' V) R$ a
BaudRate = 1/N Tq
# K0 W5 t `: p( C4 n
; ^& { e* y9 K& o T程序设计要点中强调的三个重要参数,其实是can总线物理层中所要求的位时序。共三个阶段,分别为SJW,BS1和BS2阶段,这三个阶段的时间长度都是以长度为tq的时间单元为单位的。这样可以逐步计算出CAN总线的波特率。因此要点提示中所要求的参数,实际上将CAN的波特率设置为450kdps。: o" B. i; N8 d- V( E
$ Y$ D+ p4 }/ E8 Y8 o% P R# y! b- K( {" g% X0 d2 N# Z
过滤器的设置' J: q3 y! U) k8 j- J3 j
! c h2 k4 ~8 \3 q% j. \/ T+ R" Q8 ?0 ?can总线没有所谓地址的概念。总线上的每个报文都可以被各个节点接收。这是一种典型的广播式网络。在实际应用中。某个节点往往只希望接收到特定类型的数据, 这就要借助过滤器来实现。顾名思义,过滤器的作用就是把节点不希望接收到的数据过滤掉。只将希望接收到的数据给予通行。6 Q D9 m& p2 T6 s8 l
8 o! ~, O/ [ I5 w- s7 }stm32的CAN控制器,提供14个过滤器。可以设置为屏蔽模式和列表模式对can总线上的报文进行过滤。当节点希望接收到一种报文时。可以用屏蔽位模式对can总线上的报文进行过滤。反之,当节点希望接受到单一类型报文时。则应该配置为列表模式。本机程序中使用了32位的屏蔽位模式。) k, w" F; ^: ^% D' |
& p8 R+ b- \7 H: g, s
下面仅对这种模式进行解析。can控制器的每个过滤器都具备一个寄存器。称为屏蔽寄存器。其中标识符寄存器的每一位都有屏蔽寄存器的每一位所对应。事实上,这也对应着can数据。事实上,这也对应着看标准数据帧中的标识符段。
3 \, N8 H+ l) P( ^' O1 W* B7 ]1 c+ q4 E2 F; G
如下图所示。8 Q. @- g: R* Q3 x
0 l) o* }/ b% a$ D% U
8 @. M, ]0 m0 z0 Q- Q p1 j
0 p6 ~4 E/ `% X1 r2 Z6 t" E. ]此处重点在于屏蔽寄存器的作用。通过查阅stm32微控制器参考文档可以知道。当过滤器工作在屏蔽模式下时。屏蔽寄存器被置为1的每一位都要求can接收到的数据帧标识符段必须和对应的接收缓冲区标识位相同。否则予以滤除。以本程序为例。要点中要求将节点接收缓冲标识符配置为0x00AA0000。过滤器屏蔽标识符为0x00FF0000。' L2 b" \- h2 o* J8 s6 y R# X
b, q* M# ~' z该节点接收到的数据帧的标识符段的位[23:16],必须和接收缓冲区标识符中的[23:16]匹配。否则予以滤除。但若满足了这一条件而即便如下的位不匹配。则该数据帧仍不会被滤除。正如本程序而言。即can接口仅仅接收标识符段的位[23:16]为0xAA的数据帧.: \; S; Y4 j4 K8 M
: o# @+ v2 B' R( y根据can总线物理层的要求。can总线的波特率和传输距离成反比关系。传输距离变化时,要根据位时序来调整can总线的波特率。
7 N O- {) p$ g& B
' o* [& U0 I1 {
9 v. X% i% p/ A) B) l+ K% k4 l3 J7 k3 j+ {( l) a- y
程序代码如下:
: g, i. ^3 L! n6 S$ m- void RCC_Config(void)) q5 M8 T8 e' e2 j2 r( X; X
- {1 S6 w W Z4 X% g. L( {3 T \
- ! A6 {' E, v- C7 T
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE)4 _, L# Z8 V0 o* e2 W
- ! C* x1 w" U; m' c8 \
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE). H% e* H, }* [( T; z+ a
- 4 c' z+ P! h3 w" G+ g
- }
4 g7 g! x3 k6 t. U. {- K% B* Z7 Q! e - void GPIO_for_can_and_uart_Config(void)
( |) v: T' O0 w - {& T) y% [* t/ G# ^" S2 B8 h0 s- D& j
- /*定义一个GPIO_InitTypeDef类型的结构体*/
4 U% F a. |/ X7 F0 K% I - GPIO_InitTypeDef GPIO_InitStructure;
' _3 p8 i3 R5 l$ i -
3 [7 L4 ^4 u6 d, n9 e
# J1 v! O3 M8 m( H+ @- /*设置can的RX--pa.11引脚*/
! C* a% o( O( n- O8 l; g- U - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
: [2 V/ b( O! a) R& @ - ! y. [; J8 h5 B! q) S; s
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
0 W* K( G9 e3 T; N
9 ?/ D& Z) E: b$ J- GPIO_Init(GPIOA, &GPIO_InitStructure);
: |" ^- |; U5 f7 L z( K - 8 v, h0 G( m5 u$ F! B, M4 [
- /*设置can的TX--pa.12引脚*/
! J( q1 n3 N* a7 J9 | - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
! z4 c4 a6 [/ S5 x/ v' V - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
, A! S: h4 _9 Y/ X - GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;# n) l3 w. |4 X) l6 W
- GPIO_Init(GPIOA, &GPIO_InitStructure);6 H! P' H7 C/ i, j
- /*设置usart1 的RX 脚 -PA.10为父浮空输入脚*/0 {4 M" X! ?$ i p
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+ _# V0 E/ M# S, k - ! E* T% V: C& @' |$ @/ |3 v
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
5 ] J0 A' p& a! O/ L; _ - & U7 _- W9 P) ?7 ^8 u. n
- GPIO_Init(GPIOA, &GPIO_InitStructure);
8 j1 n9 O) `5 u* G - - n6 y# h" X" I
- - u. \2 J6 d" D/ y2 J
- 8 n' W. ^; }+ M& h$ r( E; ?' J
# W9 k: h1 M! M Y' V2 w. F- }2 s5 e: P5 \! o$ s9 ? q0 p
-
0 S$ Z; P) C, @& \6 U( D - void Can_Config(void)* K" x/ t- t, |3 F$ j( D
- {
. Q- H* u" W& k9 { - CAN_InitTypeDef CAN_InitStructure;
, M: b h! Z9 r! Z" L) H7 ^ - CAN_FilterInitTypeDef CAN_FilterInitStructure;' H' C3 g" b" h. }% q
-
; u1 }8 ?( V2 L- H0 _4 s7 n$ Z6 D - CAN_DeInit(CAN1);( S& V7 z' a5 j
-
5 s& U- o K# f3 ?# X% K - CAN_StructInit(&CAN_InitStructure);9 _( l# p9 x k. V2 R d% h
- CAN_InitStructure.CAN_TTCM=DISABLE;
* D8 w' s6 z% G4 r$ i1 ~0 y7 B1 W - CAN_InitStructure.CAN_ABOM=DISABLE;
1 h S& {1 {$ Y c/ L9 s - CAN_InitStructure.CAN_AWUM=DISABLE;
0 ]4 H( b# Q [9 k6 i" L - CAN_InitStructure.CAN_NART=DISABLE;
- \9 E% W4 h( Q% I. P6 ]8 c - CAN_InitStructure.CAN_RFIM=DISABLE;$ k9 O4 C3 q& I: r8 `* o+ i& a+ w5 E
- CAN_InitStructure.CAN_TXFP=DISABLE;) H$ G) h6 \! E' f) T3 b- x* q; X% \4 y
-
$ r( `( H9 K; v4 o - CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
: w0 _. |6 P' ]! k8 o1 o5 i7 @9 \ - CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;2 U$ ]1 G- c! H
- CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;5 c( W5 L c+ h9 n# ^) l% o3 {6 z, l( d
- CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
# A* c& V9 N* t7 L9 ^3 A -
5 g0 N: H" S8 h7 w - CAN_InitStructure.CAN_Prescaler=5;* h0 p/ }' _; Z7 @/ W
- CAN_Init(CAN1,&CAN_InitStructure);1 R3 x" F) J- ]8 P% j
-
@ z# b& c% s; j - CAN_FilterInitStructure.CAN_FilterNumber=0;
7 r" V# X. j" e2 z4 S; Q - CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
* |, a7 S& z) G/ e0 ~1 i - CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;3 u- n3 t2 q6 h% Z9 ^8 M. }
- CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3;
3 l' s+ l, d c, O+ z. d$ Q/ I5 U1 k - CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;* Z1 Z" Y3 i. M D9 s, S
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00FF<<3;4 ?. B( O" R% e# i+ t5 W% d$ v8 i
- CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
; H h# ]7 L) H( R: t - CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
% \* D- i) `( U8 A* W2 o L - CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
0 v5 i! f* m3 v - CAN_FilterInit(&CAN_FilterInitStructure);
6 N5 h4 V8 T( j& H - ( e6 _. a- N$ I/ A8 m" v
- }
8 m" x# g7 E/ e1 B, m) Q -
+ C1 ^6 v$ O( u X$ K+ d0 { - void main(void)
& }; O8 |1 ~9 T) b# G - {
' F6 k6 e& ~) W6 S - u8 TransmitMailbox=0;4 G" ~2 F( r2 {& v9 \
- CanTxMsg TxMessage;
# U5 i. x( P$ m# B+ @9 V - CanRxMsg RxMessage;" c/ I1 T4 _& Z2 z
- RCC_Config();
$ v$ q5 `- {2 }+ x X - GPIO_for_can_and_uart_Config();
. \6 b$ e, u1 Z: }2 O4 S1 w - USART_Config();
! k, V3 b( r- [' E2 p7 g - Can_Config();
4 n* T+ K f7 p! S -
5 b: [/ p8 g- x+ `, d4 ]# q - TxMessage.ExtId=0x00aa0000;
) }) N7 c' H" c8 v/ | - TxMessage.RTR=CAN_RTR_Data; {" [* Y& D- _' i8 j
- TxMessage.IDE=CAN_ID_EXT;0 X2 ~) M6 k$ t& ^& E
- TxMessage.DLC=8;' g3 y3 t/ i; c. i, q
- TxMessage.Data[0]=0x00; O$ O5 m+ _+ I* b
- TxMessage.Data[1]=0x12;3 {- ?8 `' J8 F6 z9 h
- TxMessage.Data[2]=0x34;" p1 {8 f1 a1 _1 q( R
- TxMessage.Data[3]=0x56;% C" c$ ]$ v9 x5 o7 H- j1 Y2 S
- TxMessage.Data[4]=0x78;
5 w) d) X- _0 m- r1 D% I - TxMessage.Data[5]=0xab;
4 n# j6 `: S, j& ~) S# H3 T* N# ^ - TxMessage.Data[6]=0xcd;) H" l( O* r9 P
- TxMessage.Data[7]=0xef;
4 a b" c5 E7 f2 M5 S" ~& f" p - . a6 L1 {! T4 B, o' i
- TransmitMailbox=CAN_Transmit(CAN1,&TxMessage);$ n Z: N& ]# Q' @/ U
- while((CAN_TransmitStatus(CAN1,TransmitMailbox))!=CANTXOK);
/ H9 K* |3 x% D6 ~7 _9 p6 e - printf("rnThe CAN has send data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn",
4 u+ g4 o4 v4 g. m' E - TxMessage.Data[0],TxMessage.Data[1],TxMessage.Data[2],TxMessage.Data[3],
: x; H b4 M7 H/ R - TxMessage.Data[4],TxMessage.Data[5],TxMessage.Data[6],TxMessage.Data[7],);, }0 u: Z' l! M9 O) v- X# L
-
* C0 J2 d% V5 I, Q4 g' Y - while((CAN_MessagePending(CAN1,CAN_FIFO0)==0));, w4 O+ e0 A, m; s% n: @
& ^2 {9 f# r% X3 F- RxMessage.StdId=0x00;. b& g% a' g# e4 J- @" H& A G
- RxMessage.IDE=CAN_ID_EXT;0 e/ t" h. A+ j- v2 p
- RxMessage.DLC=0;
3 r8 w) I4 f }' c1 v3 M# v - RxMessage.Data[0]=0x00;
( _' _+ l @( R: }1 f9 L - RxMessage.Data[1]=0x12;
: f% @0 |$ |& x7 L+ T5 y: _6 ^ - RxMessage.Data[2]=0x34;
, ?: |; y/ \) I6 T9 J9 T - RxMessage.Data[3]=0x56;
4 \# i% e& H% R5 s/ [8 y - RxMessage.Data[4]=0x78;
* Y1 Z8 C' P" @$ j6 ^( h" M - RxMessage.Data[5]=0xab;
/ f$ ^) r! R1 c9 J& K- G- E - RxMessage.Data[6]=0xcd;
7 ^) N I1 h% q: C - RxMessage.Data[7]=0xef;
5 Q2 o0 A- l% ~ -
! X `) f/ _8 L& E. s& X' A - CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);5 R: [/ m, e2 S @; n+ ]/ b- v0 S
- printf("rnThe CAN has received data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn",
2 M9 f5 y( M% x - RxMessage.Data[0],RxMessage.Data[1],RxMessage.Data[2],RxMessage.Data[3],
9 I; z# y8 O$ g a M L' p - RxMessage.Data[4],RxMessage.Data[5],RxMessage.Data[6],RxMessage.Data[7],);6 ?' e/ V) Q6 u! p" F- i# W" L# e* }' l
- while(1);
0 }' j3 N g& @; F7 b+ S. e) A -
: ^* A8 K3 S4 V# m$ u! i -
. l; D: k9 W6 B, S - }
复制代码
7 d8 y' k% C9 I+ w" X0 S- @4 D O) N0 g. c$ D8 ~1 T; x$ m- V
9 d" v" v9 C+ i+ c |