STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
; h1 V1 c' B" e: j" u( P5 J2 V- |6 L
+ j. {, \' u& O4 c0 I5 d7 j, }3 d- #include "include.h" {' Y _7 l; O
- //************************************************************************************************************************************************
, Q0 Y1 n/ e* a2 d4 ~- P/ X - //20190611调试完成- f+ l, ]6 |: @; A: K
- //By Wang
9 @' v9 \; {; Z9 v' U - //************************************************************************************************************************************************% r5 m4 W$ s& |5 l
- / k5 j; [; x7 D5 t+ h# g9 }- |
- CanRxMsg RxMessage;4 Q. I3 `9 x5 K) B% |
- CanTxMsg TxMessage;
, c& l6 u& j E9 d K - //************************************************************************************************************************************************2 t# G& h$ T$ j# w, a
- //函数名:void NVIC_Config(void)7 z: o/ A. E( E y7 I( J
- //功 能: CAN通信接收RX0中断配置
* ] j5 A7 }8 M4 `1 U - //参 数:无5 L1 u9 c' f' i3 U6 E! ?
- //返回值:无
9 R# k- e F$ u0 b2 [ - //************************************************************************************************************************************************
' v) y# W; |7 _6 ^8 m) c
6 Q1 P6 m9 Q. h8 f& y- void NVIC_Config(void)
3 @6 {% _/ C; q4 ^: n# r% E/ W - {3 h3 c- Z0 Z: N8 H& l; C
- NVIC_InitTypeDef NVIC_InitStructure;: u. A+ W% u& M: z8 s
- : x3 [3 y& m2 f# ?6 k8 _
- //#ifdef USE_CAN1
9 a. j0 U# k% {1 D
# l5 t a, d8 B5 e- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别% Q! L l" ]8 }3 y% [
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样" U' c8 l: s8 N2 W) d
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;+ s5 s7 @0 c$ z* e: e2 l& J
- 6 R- j* w6 ~! ~" B+ P' Q
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;- y3 _1 S, |3 E E, Y% r$ b7 l
- NVIC_Init(&NVIC_InitStructure);( y0 m( r/ @, d6 K) _% J. Z7 J
5 E* ~# m% k8 w7 V+ k8 g- }" C9 T( O, D$ ~
- 2 t, V" A) b4 V
- //************************************************************************************************************************************************
$ Q3 K" y* d# a1 V. V - //函数名:void CAN_Config(void)
: v/ D, G) K% p2 P! q; y% M! X - //功 能: CAN1配置 PD0-RX;PD1-TX2 h' O" J: L4 R; n0 w& X
- //参 数:无
/ s. W x8 e! B; V" F4 f - //返回值;无
7 t7 D4 D2 A5 S* y, T - //************************************************************************************************************************************************
# b( O; @" _, `: e# e, K; J, r+ C - void CAN_Config(void)
# T' ?) Y& d- u* O" R" b# q - {
3 p. U# H: \; p. c( I4 [9 t - GPIO_InitTypeDef GPIO_InitStructure;/ w/ w* w! G' y1 Z* ^. Z5 \+ ? \. V8 R7 N
- CAN_InitTypeDef CAN_InitStructure;
; [5 a1 Y: l8 F5 z3 X& N/ c! S8 e - CAN_FilterInitTypeDef CAN_FilterInitStructure;
) l C# g$ z3 ?5 e" [# z - # f: Q- M$ e# f( B* [! [5 V1 \# W
- /* CAN GPIOs configuration ***********************************/
2 x% P. D* Q& {" A - /* Enable GPIOD clock */
( a/ D9 N" ]) d+ A& [- B: B$ J - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);% G# B1 H4 \9 [5 ?
- 9 F. j- P/ ~" Y0 w" l f: m
- /* Connect PD1 to CAN1_Tx pin */
% k z7 X0 }$ J8 j - GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
. \( d' p9 q5 A9 V - /* Connect PD0 to CAN1_Rx pin */, R5 h- _ z6 E- \% ^
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
8 R+ X% l5 R* d8 Q& v - E, O, G" [' t6 L
- /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */ Y: Y- I7 e) M- u1 m/ d/ R
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
" y* q, V& ?1 H+ V' G/ T - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
$ u4 s4 _! R7 Q. F( R8 ~$ D - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;1 m- x5 D& @" @3 R
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;" N1 D a" A& [
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- m" y1 U9 b* V8 u0 k/ K: J - GPIO_Init(GPIOD, &GPIO_InitStructure);
6 {3 o+ Q/ r. |" ^* _0 x - * ~6 P1 N4 z4 `" P: e4 Z* V$ D' C
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
2 k1 p, l, y3 x- ?. J- ~, s2 \ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
7 z* i7 \0 z, ^0 q - GPIO_Init(GPIOD, &GPIO_InitStructure);8 I0 Z! o" f7 H7 ~( U
- /* CAN configuration *****************************************/
! P9 A6 \3 W' p9 T. l$ {. O7 C1 L - /* Enable CAN1 clock */
! |$ u! b0 G( }: }4 x: f - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);( i0 u' l" f9 m( ^( T+ C! n+ x: H! R6 G
- ( D9 u& t% b4 n) S3 E$ h
- /* CAN register init */2 _ Z3 v5 L1 Q5 Z& Z3 ~+ I+ D
- CAN_DeInit(CAN1);# o3 m. Z/ Z: W, u( D
- /* CAN cell init */
+ q' d4 o7 U' S, ~+ B7 c8 B' `2 j/ |0 Z - CAN_InitStructure.CAN_TTCM = DISABLE;
6 \! ~9 e* e& A& j - CAN_InitStructure.CAN_ABOM = DISABLE;& I) M# \6 ]' G: ?0 J9 u3 V5 D
- CAN_InitStructure.CAN_AWUM = DISABLE;
7 h. Q# M2 A! |; @" n# Z @ - CAN_InitStructure.CAN_NART = DISABLE;( M2 d" i4 }+ h* Y6 v
- CAN_InitStructure.CAN_RFLM = DISABLE;. n& k9 e- N+ W( @! Y
- CAN_InitStructure.CAN_TXFP = DISABLE;; s& N. B. P. c* a! H$ o
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;- K/ H7 o0 Z5 x6 D7 Z6 e
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
$ j4 c, z+ v8 M! v( A% E/ d - /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
`3 H& n L1 j3 O2 ]# f0 P - CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
' Z) ^' G1 o% x3 M - CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
1 t# J; z& B8 n1 k* e9 e - CAN_InitStructure.CAN_Prescaler = 4;; L$ |$ V$ Y. `) g v
- CAN_Init(CAN1, &CAN_InitStructure);; Z9 U; }: E9 r+ C/ j% f! J* ~
( G0 f% V, t1 [4 I: g2 n- /* CAN filter init */+ o$ h C. _' O
- CAN_FilterInitStructure.CAN_FilterNumber = 0;
- S2 C3 o- U- `. R - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
! n1 q4 o. o* o% y; E - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;9 N& n3 T5 @, k
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;5 K# D0 Y; h" S+ W1 I
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;4 Q1 _* a- \/ j% Z5 c$ G3 Q
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
5 u, X% V V& k2 G! T, P7 S; K - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;' K ~9 Q+ [) Y
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;5 C H4 E5 {/ R" v& K
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
/ C% b5 n2 v; k% B7 Z - CAN_FilterInit(&CAN_FilterInitStructure);
7 T) p6 z7 m/ O! y - 3 I3 O- z. ^. Q, |- `
- /* Enable FIFO 0 message pending Interrupt */
6 _% P/ S& v n! R" [: Q: B' x8 h/ ~ - Init_TxMes();//发送结构体参数初始化- p2 S& w! }# `/ N- D/ M f
- Init_RxMes();//接收结构体参数初始化1 h0 ^" @$ s' k, S0 T6 @# V
- NVIC_Config();//中断向量配置
8 C0 G( L( t' ~. H B( n" ^* a; |0 r Y - CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
1 x' F0 x' V+ ]
z8 h4 g7 z& Y7 L) H% S- }
{& w6 v1 c/ d! N4 c* A - //************************************************************************************************************************************************5 S( h* G0 g# k' x+ D9 u# ^
- //函数名:void Init_TxMes(CanRxMsg *RxMessage), X" A! \" N+ w# |& ?3 N; a
- //功 能: Initializes the Tx Message- U4 }- H3 E/ \4 t6 }3 U: X% A; d/ u
- //参 数:无
6 O; d; O; B# p) l* M - //返回值:无
0 ~! }1 y1 N* B+ z1 X* z - //************************************************************************************************************************************************/ d2 l# R) V% @+ n. h: y
- void Init_TxMes()
. g! i3 v% y' B) e6 Q - {0 G; P9 J' H8 { ~+ |4 F
- /* Transmit Structure preparation */8 I- P, t+ w4 V* O7 U- e( t$ x
- TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效' d! G* x+ e( _. k3 o x% M/ Q- t
- TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
6 S' d/ F, O6 s6 K, q4 e& K - TxMessage.RTR = CAN_RTR_DATA;//数据帧
# |& s9 t& w# n& O/ T6 w - TxMessage.IDE = CAN_ID_STD;//标准帧 0 s, F( o8 }: q _" k, \
- TxMessage.DLC = 8;//发送数据长度 DLC=0-8
4 @# |' ^* S$ Z; v/ k6 P - }4 E& {' N2 O! q [( v& I
- //************************************************************************************************************************************************2 {: {# j& |& Q6 s5 Z
- //函数名:void Init_RxMes(CanRxMsg *RxMessage)
9 \0 Q1 ]+ k3 L5 o" y - //功 能: Initializes the Rx Message
7 |3 S# n2 ?; O3 d/ j. I - //参 数:无( b" A4 h- f+ t0 K) V1 b
- //返回值:无
. _5 E `( Y7 p- }, O9 y# U2 L - //************************************************************************************************************************************************
! `! b- p- `8 x" Z, b - void Init_RxMes(). |- ?1 {4 i x# x& ^$ ?4 n% A
- {# Z/ h/ b: }8 F6 [+ L0 j/ T/ O
- u8 i = 0;# j+ I" }+ n. u- K
- RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确 # q' u; S4 @. Y$ G; `6 o
- RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 7 }/ g, y: B ?) ]8 B
- RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 8 `' T7 V3 I* t* G$ H5 |6 U) ~7 d
- RxMessage.DLC = 8;//接收数据长度
$ I6 U* g7 a# R7 K {6 l$ q; g - RxMessage.FMI =16;//????????????????; H4 U) N: d! a
- $ t6 i+ C3 b; Y1 ^
- for (i = 0;i < 8;i++)
; k5 i, `9 R4 c" E" {, i: [ - {1 I- N0 k" D t+ H" l# o
- RxMessage.Data<i> = 0x00;</i>. u. w8 b6 o: U) Z1 \% q! c3 {
- }$ p: g) x% c5 i$ Z3 y
- }' R ^! v& x2 t! U2 A
- //************************************************************************************************************************************************
; W9 ?: y. N% \ - //函数名:void CAN1_RX0_IRQHandler()
# b' A7 I2 j, z) U. ]2 w - //功 能: CAN1-RX0接收中断服务函数$ b) A( M2 a# l9 m# x% R. v9 B# V
- //参 数:无
j: L, H! i. K: D - //返回值:无8 }" K! \5 d' ^1 x8 ]$ S4 ~( W. u
- //************************************************************************************************************************************************
3 j( a- E; n- d7 R* N" b5 ?8 r, J - void CAN1_RX0_IRQHandler() //与CAN1_RX1_IRQHandler()区别* h( p1 {: }/ [+ w& ^, y5 ^
- {
" u9 H f/ |3 M- n0 P2 B; z - if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断9 a$ u* j3 B4 U8 |; A% G4 i
- {9 o6 ~5 W$ ~6 R2 W
- CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志7 c( F2 j& ?3 M( @
- if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
6 i7 [7 W9 P' W4 I) ]4 H - CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节7 X, @0 u$ t/ l% O
- }; o* p( q! R2 K6 @. `/ d& V, Q. U
- Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信
" K1 o; g; R& J! q% I9 L( c) } - }
2 q g0 O# w' l5 n - //************************************************************************************************************************************************
1 Z3 M1 ?* d+ Y% m; X+ s - //函数名:u8 CAN_SendData()% v4 I1 j' ?" _+ b+ G. O. Y/ _
- //功 能: CAN发送数据 发送第二步
5 x i8 x3 g$ M" I: f L2 o - //参 数:Msg数据指针;Length数据长度& g0 \% H9 K9 |. I6 |/ m
- //返回值:返回成功/失败标志2 Y5 I# d8 F; C; x) ]* r( x6 w
- //************************************************************************************************************************************************
F' P( F9 `' u1 l9 s - u8 CAN_SendData(u8* Msg,u8 Length); M3 p, _$ u3 L( U* e' O
- {
1 }# F4 u: X `9 I2 ]% {- g! I - u16 i=0;9 V' \& ~3 R a
- u8 mbox=0x00;
! m! t' p7 ^- V& W5 Z* S( ?( [ - TxMessage.DLC = Length;//发送数据长度 DLC=0-8' n1 ~; c- C# j+ W5 ?
- for(i=0;i<Length;i++)
1 ?# e6 I' q4 G8 t7 e - {+ h! i2 N9 Z |8 Z+ S/ B
- <span style="font-style: italic;"><span style="font-style: normal;"> TxMessage.Data=Msg</span><span style="font-style: italic;"><span style="font-style: normal;">;
8 E" n$ m. f0 `6 { - }
9 s" P: @7 E8 l0 I* j+ I' ^ - mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据 返回邮箱使用数量
# D7 o, [4 z& e7 l
6 L2 i8 i- u( s& T3 m7 Z: R- // while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))! E2 W) c! b/ b2 |
- // {
' G- h- y' C/ {$ j w+ \ - // i++;
' }& m, y5 V5 U6 t) S - // }
5 l( {& j8 V3 C5 r5 R - // if(i>=0xfff)
( r* E J( v! }8 s3 k - // {
4 P. S& A6 d* U - // return 0;//发送数据失败- o/ \4 g6 q4 H; B$ |
- // }( E6 Y" L( X) e H
- // return 1;//发送数据成功
4 w, u0 ? Q7 m6 x - }
% a3 \$ k8 ?9 G4 V! d2 u - //************************************************************************************************************************************************( O o% |, Z0 G8 ^
- //函数名:void CAN_SendDataProces(u8* data,u8 Num)
- h: @* |3 V8 L5 Y7 n, Z" \ - //功 能:CAN发送数据前期处理 发送第一步
$ n% q( _0 P' ~( v! Q5 F2 l5 v - //参 数:data数据指针;Num数据长度3 Z- y: O7 g6 ~# `
- //返回值:无
@' O3 h; Q6 v1 Y, b% r - //************************************************************************************************************************************************' ^6 c" G/ I9 W1 x$ ?! Z' k
- void CAN_SendDataProces(u8* data,u8 Num)
2 ?0 A: {# [0 P; U- M M2 [' J& n - {
( v- Z6 |! p: M, o - u8 flag=0x00,i=0;3 S2 m# w, L. P5 w; v9 \! w: ~/ y9 F0 `
- u8 Count=0x00,Left=0x00;
8 R0 C) U. }2 S6 x
0 s R& q' e0 P- Count=Num/8;//求多少个8字节倍数8 m F! B# Q' c/ ]
- Left=Num%8;//剩余小于8字节的数量' |/ i4 B/ ~" S
- for(i=0;i<Count;i++)
% [- X5 l7 Y5 t3 [' C - {
3 y" f1 }, |& }5 `* J s; d - flag=CAN_SendData((data+i*8),8);//发送整8字节的数据0 O$ g) ]: f6 e M
- } d$ q7 N* P9 ]8 d
- if(Left>0)//有余数才单独再发送一次3 R$ r; S: k& i$ q) u8 G( w
- {" O" s/ W) [/ O$ ?
- flag=CAN_SendData((data+8*Count),Left);//发送剩余字节 _0 O$ o) ]5 k, i, l
- }
0 _( M# {6 S1 {. D1 b2 T1 r0 X, b - }/ M3 X6 Y/ n0 d
- //************************************************************************************************************************************************& r* {" F( @4 e8 ?
- </span>
/ F# W. i' S, M - </span></span>
复制代码 / a& _6 U Z+ r% f. m
|