CAN通信是STM32中比较复杂的东西之一,它 的初始化主要分为两个部分,一个是CAN的初始化,一个是过滤器的初始化。自发自收只需要一个器件,CAN的模式选择回环(Loopback)模式,这种模式下发出的数据也会被CAN本身接收回来,只需要检查接收到的数据和发送的数据是否一样,就能测试发送是否成功。: e' t6 g. v: T# L7 l9 W' j
代码:
q8 H# I q, @( w7 u8 g- void CAN_Config(void)
7 @& G# h2 v0 @8 \- S& X - {' D; x4 S! p) ^
- CAN_InitTypeDef CAN_InitStructure;
4 h( `8 x. F; e - CAN_FilterInitTypeDef CAN_FilterInitStructure;
! D$ u' G/ x1 C" [, R6 p
5 k; G1 r: A. s" ^, |; O$ T) h. O: U/ z- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);7 g1 S) V6 E: c3 ]9 {
- CAN_DeInit(CAN1);
# B8 E" j" K# g2 @; t( ~8 _0 | - CAN_StructInit(&CAN_InitStructure);
^6 m: b; k; N' X. `0 {& g
% K0 G. U y+ U' Z- t- CAN_InitStructure.CAN_TTCM = DISABLE;
) M- H }* v" r - CAN_InitStructure.CAN_ABOM = DISABLE;2 E7 U" R, T3 H, s+ I' R- q: }
- CAN_InitStructure.CAN_AWUM = DISABLE;" `- K s) y' t; T8 j0 |5 k
- CAN_InitStructure.CAN_NART = DISABLE;; g& v; {- G# F' E
- CAN_InitStructure.CAN_RFLM = DISABLE;
/ m9 {5 u, c" Q- [3 o' G( o2 [ - CAN_InitStructure.CAN_TXFP = DISABLE;
' \. k( _. C3 k" N# ^. }; u - CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;//回环模式5 T& F ?6 R2 T0 x6 B0 Y7 M' E M6 ~7 m6 K
- CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//1
$ z: Z! D4 v3 c$ L9 _ - CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;//9" |% d' t, }& w( v% w8 x5 t
- CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;//8; t4 P% Q! ]4 c5 K9 V% i. x
- CAN_InitStructure.CAN_Prescaler=16;//16分频/ \: q/ Y2 x* [+ j; h9 C
- CAN_Init(CAN1,&CAN_InitStructure);
3 m, u' G5 E. a! O - 9 n+ C3 T3 z, i) m/ Q( C9 a. `
- CAN_FilterInitStructure.CAN_FilterNumber=0;& X. ^( I- m% n6 T1 ?) C
- CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//屏蔽模式 d; P) `- H/ }4 b( Z/ _
- CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;, b1 Z1 ]0 y A
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
* D+ Y9 d- C7 B) K$ d. Q, b - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
9 b; n# T8 o4 Z, P( u% _ - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;, x9 j8 E" N8 h4 t8 c+ Z u1 Z
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|# {8 ^7 a, b5 G7 I. p6 m - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;3 `1 G9 A! @$ D3 j+ j
- CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
# x/ D0 Q3 n( g+ f/ ^+ ]9 h5 r - CAN_FilterInit(&CAN_FilterInitStructure);
" A& n+ o4 }' M. z6 N$ I6 r" \ - }
复制代码
( }2 X. t! y( ?+ g6 Y q配置完成,开始发送和接收:
! l' S# `) T/ x! ` W& X- void CAN_Test(void)
! {; u. {' k9 \$ S, K0 s+ | - {0 H8 z$ S, ~! @$ I
- CanTxMsg TXmessage;( h+ J/ Q' ?, E9 b$ {' I
- CanRxMsg RXmessage;: n7 Z# ]7 {5 v, m4 G
- uint8_t TxMailbox=0;% b, \5 T5 X$ Q- G8 y5 q
- uint8_t ret=0;
, ]2 {0 P/ p* y. Y+ v2 l9 M - 4 i3 b' t# I5 A0 m% B* w: U
- CAN_Config();
( n" @2 f& [& ]5 ?& V( ?% F$ m3 L - TXmessage.StdId=0x123;//ID,标识符
. V# B0 ` R6 u7 g$ w. e - TXmessage.IDE=CAN_ID_STD;//标准ID: Y! Y6 e$ a7 `1 o
- TXmessage.RTR=CAN_RTR_DATA;//传送的是数据帧 @) T4 | m& r: B9 r; |# I1 a% M
- TXmessage.DLC=3;//数据个数。不能超过8个0 I5 h8 s J' T: D
- TXmessage.Data[0]=0x01;//传送的数据) _7 m" I9 [3 E( A+ E r
- TXmessage.Data[1]=0x10;
% |9 l6 A+ `1 r, N! z) x+ L - TXmessage.Data[2]=0xFF;/ b% i4 M" _7 T
- TxMailbox=CAN_Transmit(CAN1,&TXmessage);//发送,返回的是当前邮箱号3 I+ {* c6 e* [
- while(CAN_TransmitStatus(CAN1,TxMailbox) !=CANTXOK);//等待发送完成3 e1 J o% P4 L8 R4 T3 F
- while(CAN_MessagePending(CAN1,CAN_FIFO0)<1);//查询接受状态位,看是否有信息(报文)到达8 y. N0 }$ ]& g5 k7 s5 n [
- RXmessage.StdId=0x00;//初始化接受结构体9 u+ @2 |/ F/ P+ m+ z* ?9 S
- RXmessage.IDE=CAN_ID_STD;
1 S- G s- q1 {+ r* j - RXmessage.DLC=0;
" @" `5 U I4 n* x$ ~5 u u$ T - RXmessage.Data[0]=0;' J$ t5 G% @$ B' N
- RXmessage.Data[1]=0;
3 ] ^5 P8 b( {* ^+ R6 R - RXmessage.Data[2]=0;- V" T: Z/ L0 A. w$ |
- CAN_Receive(CAN1,CAN_FIFO0,&RXmessage);//接收信息(报文)
2 W" C- @% Q; O0 x3 M: o' c - 3 Q' K$ A2 k7 E( Y+ v0 @
- //最后检查所接收到的数据每一个项和发送的是否一样,如果全部一样则发送成功,否则发送失败' P: D1 ?1 O5 K7 ?- v) h& E
- //设置标志位对结果进行保存,用串口打印或者LED显示不同的状态来表示发送接收情况
6 _4 o, B2 G4 S. D/ m6 r - }
复制代码
( r5 ]# c) N3 L5 {% d/ g' I* \
/ M; a! P: f" `) h- _; x b
% k8 T1 a% \- c |