STM32F2-CAN通信-发送任意长度,调试好的,与大家分享4 V$ \1 u* R; v* \0 a" w
* R% D5 f' \" R
- #include "include.h"
3 Q8 I% c0 ?# m0 E - //************************************************************************************************************************************************
+ g4 I5 h$ X4 Y D; E - //20190611调试完成
, u8 u- M" _) D* G* D - //By Wang" Y, ~, y$ W6 ^2 V( f
- //************************************************************************************************************************************************
3 G& | F( Z( O6 x2 u. |/ x7 i - % c) I5 u/ e3 A, Y% N i
- CanRxMsg RxMessage;
& A, L+ G3 _0 @% _5 w) k4 P - CanTxMsg TxMessage;
! E4 s7 u9 ? s# e! J, `1 Y1 y) o - //************************************************************************************************************************************************
4 _: n4 ]! d5 Q3 W - //函数名:void NVIC_Config(void)0 \4 Z) m+ y* f( F& D( Y8 `% D
- //功 能: CAN通信接收RX0中断配置' c8 e7 C; x7 l
- //参 数:无
2 x5 `2 R+ D7 {: s: A. H2 Z - //返回值:无
! |; ]+ i; S0 s3 b9 B - //************************************************************************************************************************************************( |9 k7 x1 I- u% D# s) }! p. f: X
1 v+ R/ F) }2 V. N- void NVIC_Config(void)) L$ U8 h# ?5 i4 n: E
- {, _& ^0 l1 w H/ ~; P
- NVIC_InitTypeDef NVIC_InitStructure;) M% N* o h8 ]' p7 j' w
/ U$ p% s' x4 Y+ m% x5 ^- //#ifdef USE_CAN1 * O% K+ m( _9 p7 k/ ~
- 7 q1 w3 T* ^% c3 c3 z* ]
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别0 n5 y" [, z2 D% W( g$ H. T
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样" L: h) H3 t, j% j6 _) }, e
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;* p3 I- Y5 O* a, N+ K7 K; K
- , [2 @4 R' L7 O
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;9 T! s8 b/ [# }+ g" E# G5 f
- NVIC_Init(&NVIC_InitStructure);2 M; u' }8 q" F( w
) H8 A) @6 f# n6 l# q/ r1 ~- }
9 L2 f8 V" a/ F6 R8 Y8 ~7 m9 H5 X - & t2 Z) v: T! T3 L* L
- //************************************************************************************************************************************************- C; m: |" f' ^
- //函数名:void CAN_Config(void)
) K. Y5 O& @& K1 ~& r! a- r - //功 能: CAN1配置 PD0-RX;PD1-TX
5 `5 G5 d e" z1 [# V- E - //参 数:无
- a* N0 O! a. V: G' `9 l' N) W - //返回值;无
& q8 ~5 ^+ }& N+ y - //************************************************************************************************************************************************
# o" z/ ^ W- w2 i - void CAN_Config(void): n& u# b0 n1 n+ S9 H
- {
6 A) E: V- g& H - GPIO_InitTypeDef GPIO_InitStructure;
0 a8 n3 u( d( W4 w8 t' F - CAN_InitTypeDef CAN_InitStructure; b/ P7 b- d; b# o6 C" y+ a% B
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
! {; I; x6 E" o: A( B- | - , K7 E. I1 ?* l1 q+ w
- /* CAN GPIOs configuration ***********************************/" y* B' c4 e7 i
- /* Enable GPIOD clock */1 S2 U% e& T1 S- _* j! l! {
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/ |: F! k* F/ T: O. { - - [9 z; c3 z: E. e5 ], x }, u
- /* Connect PD1 to CAN1_Tx pin */
# ]( x+ }6 M; E, n - GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);# h1 Y3 c# Y5 o: s. H
- /* Connect PD0 to CAN1_Rx pin */- R+ W3 [3 F5 ]3 O: h
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);6 r) [; R4 \, Q. _, e; g4 K/ Q
, z% d% e$ [! j$ ~. }- ~/ f- /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */9 g5 e) A' N% q. ]) L* s, _* K# X
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;5 Y* o8 q* b# K8 W2 A$ x" u3 `
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
! t* N" q. l. W! l5 Z) f- N! h - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
; E1 s, g! u0 |4 }+ K8 R! c - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;' |+ `( M6 f2 S' \# g
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
7 v' Y U6 Z; W; h) x2 T - GPIO_Init(GPIOD, &GPIO_InitStructure);
5 m* i- \' m3 p
, v- m2 W! d! ?: s- O/ a ?- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定 h n0 A1 z6 U2 f
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
6 b( T* F2 ^7 P2 Y' e: r8 T - GPIO_Init(GPIOD, &GPIO_InitStructure);9 _% @) Q* t+ O5 @: k0 X: F% i/ O
- /* CAN configuration *****************************************/# P$ I- O: E& a4 V. ^
- /* Enable CAN1 clock */2 _. ~/ x2 n @3 W6 c6 g& d
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
2 O8 t$ O( z4 T0 x+ [
. Z2 }* L2 m' ?) I- ?- /* CAN register init */
2 }% J* D3 `1 g1 ^ - CAN_DeInit(CAN1);6 B! B7 W$ F! M/ m% e
- /* CAN cell init */
$ T1 b5 E( z5 L1 y' z - CAN_InitStructure.CAN_TTCM = DISABLE;' q) s8 e7 k3 u. ?3 b
- CAN_InitStructure.CAN_ABOM = DISABLE;
, m" H4 K# ^- T, P5 T9 L - CAN_InitStructure.CAN_AWUM = DISABLE;2 w7 a. A* N2 F. Q; B: V. P4 o
- CAN_InitStructure.CAN_NART = DISABLE;0 o8 ?. D9 T4 L3 R! N$ y
- CAN_InitStructure.CAN_RFLM = DISABLE;
1 B% z3 l! a8 r U - CAN_InitStructure.CAN_TXFP = DISABLE;% @; x5 E8 V0 d6 F; ^1 q5 O- F; S
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
2 F+ B3 q9 |0 S5 q" R4 E. z# { - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
# j1 E! k3 H% x ?% O" \ - /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
4 T7 C3 ] W& o3 Z - CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
9 p. d2 `4 p& V2 K1 E2 T - CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
7 B, i& l% V( A5 I - CAN_InitStructure.CAN_Prescaler = 4;
" V+ e# f7 Z! ` - CAN_Init(CAN1, &CAN_InitStructure);
. l \& v9 I: v. X0 _$ T' a
( V& ]% W+ l) L" H- /* CAN filter init */
4 \8 m% c6 }/ y - CAN_FilterInitStructure.CAN_FilterNumber = 0;% q& g7 \2 s( K
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;0 ^+ F+ R9 A) i2 C% G% w* r3 z
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
% o6 Z# L5 j; ^ - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
* I% q8 |( e! N- o) s - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;! H! u$ ~1 ?9 O7 Z
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
. _* s7 H4 M; F; t - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;2 c# T+ l k4 x, L( @" q4 U
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
, B& ~0 V1 A- \- V* R - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;, J; v1 u* S0 b$ B! k
- CAN_FilterInit(&CAN_FilterInitStructure);3 H, w/ N( e1 X1 h
6 }7 c: {. A+ J2 K3 _, |' x- /* Enable FIFO 0 message pending Interrupt */
' {: J2 o* N3 c3 N1 b' o% A8 x - Init_TxMes();//发送结构体参数初始化
9 m' A) ~8 y4 z - Init_RxMes();//接收结构体参数初始化& v5 l% R D' b2 o# |" `( t5 o
- NVIC_Config();//中断向量配置8 c) Z: ?. J( c* m9 p; y
- CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
: t/ S( C, R2 N' ~1 S2 A' g6 q - 7 ~, d3 q P; R! e! J
- }) h2 d- w; Z4 ~' _
- //************************************************************************************************************************************************
4 ^0 m: W; [& \8 p/ t, v" \. e - //函数名:void Init_TxMes(CanRxMsg *RxMessage)3 ]+ N8 i* W1 c( I5 a
- //功 能: Initializes the Tx Message
0 m4 S" S, X1 e% L, n" o8 K - //参 数:无
1 k1 h% P3 \/ U* v$ m3 B6 t( P - //返回值:无6 N8 T# U: @, E& t4 S0 ^ e$ [
- //************************************************************************************************************************************************3 G' g7 M2 x$ q3 U2 P! i
- void Init_TxMes()
, ~/ p1 L/ `6 ?5 ?1 ^ - {
2 L- e9 j4 X9 m; G4 e' E! [ - /* Transmit Structure preparation */7 P* v; g7 d# v
- TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效' R. C9 B' X$ u" ]! ?. {7 \6 e- K) W
- TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效6 G" G8 P; }; ]9 Y* l
- TxMessage.RTR = CAN_RTR_DATA;//数据帧: J4 n9 G2 s9 H2 y! I$ E
- TxMessage.IDE = CAN_ID_STD;//标准帧 * x; U) Q* H9 v9 Z; o1 ?: g4 ^4 G
- TxMessage.DLC = 8;//发送数据长度 DLC=0-8
5 Q+ n: y: @( m - }1 S* \* f" O7 Q! r( {
- //************************************************************************************************************************************************" W0 e; h7 A# ?0 s8 _. l8 L) ~
- //函数名:void Init_RxMes(CanRxMsg *RxMessage)
" h6 ~% L* @; l$ d! q- i - //功 能: Initializes the Rx Message4 A% w1 p' h3 ^$ a: x8 X
- //参 数:无
8 m7 j" e/ g$ n+ \ - //返回值:无
, Q0 l' l) l% \. M - //************************************************************************************************************************************************3 G0 T" k2 L# Y+ s) M2 T
- void Init_RxMes()+ ^* N1 R* E/ o* J4 d
- {
+ _. u: f2 P( B& J3 k$ e! N - u8 i = 0;% {7 L% m% k9 A* m' r/ G* E
- RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
E+ [$ m. ^+ i6 U- d/ U1 V - RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确
* T% q: E" B8 t - RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 # m% P" \/ U8 m6 Y+ U4 ^5 g
- RxMessage.DLC = 8;//接收数据长度" Q/ G* B7 U1 ~& d" l
- RxMessage.FMI =16;//????????????????! B2 j7 n7 u r
- % w* e1 Y- b- Z9 f+ ]
- for (i = 0;i < 8;i++)
2 p4 C' d6 W$ w3 d2 j T5 B - {9 F- y. R& C/ g1 T6 J
- RxMessage.Data<i> = 0x00;</i>
8 j& |& c, N! h6 O w8 ` - }2 W- V' g0 c+ G
- }
0 n; ]5 @! A4 j: H+ J9 ` - //************************************************************************************************************************************************6 [& ], I3 S/ z1 t A* J5 l
- //函数名:void CAN1_RX0_IRQHandler()* h6 n- a% V' X2 l+ ^8 y. |
- //功 能: CAN1-RX0接收中断服务函数2 p- ^% J6 r7 o, m5 m
- //参 数:无6 P# o* `6 D4 `6 T" e
- //返回值:无: F) x- d, \) ]; [) g
- //************************************************************************************************************************************************
+ t( g" j4 }7 r6 X- N. z& a$ ]+ J - void CAN1_RX0_IRQHandler() //与CAN1_RX1_IRQHandler()区别
& H% W+ g. n/ ^) ~. W. d' b - {& {3 k& a0 c; a) B* p( v; u
- if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
2 g, z1 i5 P# m1 {2 X: r( l - { p& `8 K& Y3 S- i* `: n
- CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志) z; r* ]' d; ~' C: }+ d
- if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据6 {# h o! `. o4 n% ~0 l+ f; K; o3 e
- CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
n5 F" ?* q n# B- |! O - }
, e6 }8 k# j8 ~. e* c* D - Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信 " X C; Y; O9 E$ E
- }# I. _% Y# M- u5 q
- //************************************************************************************************************************************************
+ R/ p# ?% [+ I - //函数名:u8 CAN_SendData()' k5 ]0 O, D5 ]; B- s" {3 L- @& a
- //功 能: CAN发送数据 发送第二步
1 z V1 z$ G: h& Y2 p - //参 数:Msg数据指针;Length数据长度4 h! L- V1 y' h0 s8 c
- //返回值:返回成功/失败标志4 q# R* x T; }) p2 Q8 O5 E
- //************************************************************************************************************************************************
) B% t- z! C% s$ T& _) J) y8 ` - u8 CAN_SendData(u8* Msg,u8 Length)
# s7 h0 {) z1 \- b- [+ R% I - {: a" Z: I) q! e0 t: p
- u16 i=0;7 r2 P; ]7 |; T. L8 k9 t; n- @
- u8 mbox=0x00; $ c) k& i$ K$ X
- TxMessage.DLC = Length;//发送数据长度 DLC=0-8
f- J# f1 G7 @" [, M - for(i=0;i<Length;i++)9 r& ^8 }7 G. A
- {" [1 `/ U5 Y: W/ q% u
- <span style="font-style: italic;"><span style="font-style: normal;"> TxMessage.Data=Msg</span><span style="font-style: italic;"><span style="font-style: normal;">;
- s4 x8 W# W6 N( n3 a$ L - }
7 N8 a+ M H" v. Z8 {' Q! K - mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据 返回邮箱使用数量
" D3 K( S+ Z0 o$ V# f - 5 ~" F3 i& F# K4 W0 B8 ?
- // while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))
+ x& [0 ~/ P" | H - // {
- R) |: r! [' S, U6 f - // i++;1 X! ]. e0 q6 z
- // }- D# s: \9 o' d( g
- // if(i>=0xfff)
/ @% H7 C: G3 ~% m7 f! k1 v - // {0 z$ C* K. a; d
- // return 0;//发送数据失败
. O2 F) L" r1 e+ X1 h, n' | - // }
3 B4 H7 C! v) p1 C! t+ W - // return 1;//发送数据成功6 P+ _: w2 E3 J
- }" a9 j0 p+ j5 q$ a; ^
- //************************************************************************************************************************************************, r! }. _) x' n- K# D/ A
- //函数名:void CAN_SendDataProces(u8* data,u8 Num)
' Q) G; h9 b8 }" Q, z - //功 能:CAN发送数据前期处理 发送第一步
8 _) u; S0 T( X - //参 数:data数据指针;Num数据长度
' M* E) |! |( a' D4 |2 { - //返回值:无
" B$ V( r, M0 r' i$ l - //************************************************************************************************************************************************4 F* ]. z1 B7 x
- void CAN_SendDataProces(u8* data,u8 Num)' g% {& U" u! g- A- ~9 g1 V/ A
- {
! h4 P9 J5 x0 Y" G; }# f, @ - u8 flag=0x00,i=0;
% p' }; W. Q! M4 I1 I' @ - u8 Count=0x00,Left=0x00;* d3 v: K# X2 k2 U! c& B
9 Z f. S. }/ l; b- Count=Num/8;//求多少个8字节倍数: z+ K5 m3 d+ L. E0 x& V8 c$ |; u8 R
- Left=Num%8;//剩余小于8字节的数量: V; `6 y0 Q8 G& E- e! K
- for(i=0;i<Count;i++)
, x, z. g d& z; a' u: ], V" [ - {, Y* P f/ E6 T% w* B) i9 x( C
- flag=CAN_SendData((data+i*8),8);//发送整8字节的数据: S9 \* G# q( \
- } # Y5 }( F! v! Y. e+ @
- if(Left>0)//有余数才单独再发送一次
4 `! K1 l$ u |- M# \; q - {
& i2 g) x# k Q/ d. t e1 x4 S7 a - flag=CAN_SendData((data+8*Count),Left);//发送剩余字节% d; A" f. `3 g: @$ v
- }3 x/ Z* K, Y( P, m/ |1 P
- }
1 \* K' N# i8 G) C7 ~. K - //************************************************************************************************************************************************) x# ~# [% Z% D y- K* ~7 B1 `
- </span>
2 B. D' t: ^9 I( N; ^" c- Q - </span></span>
复制代码
, T1 ~$ V6 r9 _% K7 f+ u |