STM32F2-CAN通信-发送任意长度,调试好的,与大家分享$ {4 {3 Z, M( ]1 ~6 L$ e# o8 A
. u9 v# d, W' j3 V' P0 @; M1 d& u2 N- #include "include.h"9 c7 G7 ~, ]! F9 r+ I! C
- //************************************************************************************************************************************************
& s' U; I& ^* E! E8 F" Z8 |3 O9 N - //20190611调试完成
+ t# A8 G' u) L9 a6 F2 n) d) S6 p - //By Wang: n3 Q( M; Q+ k+ l
- //************************************************************************************************************************************************/ J, @% y" N& E& O' D8 L: D, I
& J- B: G' T" B- CanRxMsg RxMessage;
$ l% A# q+ v, P: t( g+ u: H - CanTxMsg TxMessage;- a" n% h b$ L1 |! ^
- //************************************************************************************************************************************************
- c) _' X1 {- p2 I) K, T4 W7 C k - //函数名:void NVIC_Config(void)! v- U0 |& I H' E; k8 J7 }# p# x
- //功 能: CAN通信接收RX0中断配置
7 i; G' d4 D7 H# N& t* n: k - //参 数:无- M. t5 s" o+ v$ [
- //返回值:无+ n' |" t# x0 K/ `0 d) r
- //************************************************************************************************************************************************( M& p5 ?) f3 ]/ F; S
k* N8 ^4 _" T) M( g/ s- void NVIC_Config(void)" ?* X+ L& ^" j! s5 ]. c4 w
- {# E- l4 E2 u6 ?$ B2 K
- NVIC_InitTypeDef NVIC_InitStructure;
3 M. a# @' w2 P- @$ s7 C - 9 i- a, w+ m) j4 ]1 O
- //#ifdef USE_CAN1 & [9 V, E8 U9 d& M, r
) p* _( C' `# f: K: i' ~( f* t- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别- ]6 d& t1 c/ }8 D6 o/ o- ^
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样
5 g0 e! G8 w9 j# X - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
* g9 j& j$ u: K! u5 I
6 m8 M8 P& B# C- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;4 w$ w& \+ [" K, a/ Y
- NVIC_Init(&NVIC_InitStructure);
3 S3 k H5 f/ Y- }9 h9 z$ ]! ]' n - / ]- `5 q; P* T" V$ R
- }1 y3 }+ G& m! i4 m& {
- 8 X0 w" t& p' b% W
- //************************************************************************************************************************************************
& F ^+ j6 S1 v# P5 H' v* O+ d - //函数名:void CAN_Config(void)2 q& P0 P( z7 `# h' s
- //功 能: CAN1配置 PD0-RX;PD1-TX
/ w& ?: {+ f5 n: g5 N - //参 数:无
* k: i7 d, w6 B% E) D# X, O - //返回值;无* `% j3 i. i& F( \6 Y; T1 {* m
- //************************************************************************************************************************************************0 ~8 @/ o9 K( G
- void CAN_Config(void). M- \& V/ \7 |8 z- w2 C- R% _
- {8 B& A: f, f, a. }* h% L, \& Z
- GPIO_InitTypeDef GPIO_InitStructure;& O& H0 J4 g' \* \% c7 r+ n
- CAN_InitTypeDef CAN_InitStructure;! T# }$ ]1 b- q4 N' x
- CAN_FilterInitTypeDef CAN_FilterInitStructure;; G% z; j3 `- m) j
- ; r' R7 k5 B* b+ d: A
- /* CAN GPIOs configuration ***********************************/
4 \4 r/ \3 \4 H' H7 R - /* Enable GPIOD clock */
( j' V6 H l; _% E+ `" L6 z# u* P - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);1 g0 t+ s2 P; _! U5 O+ I: d, `( ~8 z
& |- ?- F! z: @/ {5 Y' ]. [- m- /* Connect PD1 to CAN1_Tx pin */* F" [) d& P4 j! q+ \
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
! i9 K- j7 o# M: } - /* Connect PD0 to CAN1_Rx pin */$ _( a0 b2 D& h
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
5 `# b+ D% }3 h
: i* |$ O6 K3 ~- /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */( w2 M; b/ v9 O9 B+ E( O8 n
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;" N9 ] ]+ r3 X
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
4 o" V4 ?, T! J2 i - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ H$ R0 ], G! |2 \ - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- g' }# T4 q- |# J' m - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
x0 \' o+ \4 e - GPIO_Init(GPIOD, &GPIO_InitStructure);
2 E9 [7 {. v& ]3 H0 {5 q* V
. e& `& {: j$ M/ J! \ ]$ `6 b- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定" X7 @( A4 A+ I3 k5 [
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
. H# `; J' d* E - GPIO_Init(GPIOD, &GPIO_InitStructure);! d% B1 h; L1 ?
- /* CAN configuration *****************************************// n( h: k2 v' J% B8 [0 w6 M- x
- /* Enable CAN1 clock */3 K. w& X+ K" `! U7 ~
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);1 R6 v$ D. G7 W7 T. Q( Q! e
: g" d: O( d4 O7 s2 X) F- /* CAN register init */) V0 A! x* ~3 @. J w, M
- CAN_DeInit(CAN1);2 L3 S$ r( F1 Z, H- _+ k
- /* CAN cell init */( }' G) P3 q# S' d) X
- CAN_InitStructure.CAN_TTCM = DISABLE;
. }, p' M" g; M7 C - CAN_InitStructure.CAN_ABOM = DISABLE;
/ n: N7 G! U- A% V$ { - CAN_InitStructure.CAN_AWUM = DISABLE;
2 g0 t5 x$ W* g2 W v. C - CAN_InitStructure.CAN_NART = DISABLE;
! b( I1 c' u/ N - CAN_InitStructure.CAN_RFLM = DISABLE;
/ f" g) O v5 z2 B3 [$ V8 H - CAN_InitStructure.CAN_TXFP = DISABLE;
' X" L. b& E$ ~- w% f - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;4 I' }: b1 H0 l4 [
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;, G; C7 f' ?8 ]" |5 A
- /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k! S: l+ {: k) @; j, S
- CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
2 q/ Z# g u) M. J( g - CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;! L D: I8 Q: C9 N9 i: K( U
- CAN_InitStructure.CAN_Prescaler = 4;' P5 |' a( J* P) h
- CAN_Init(CAN1, &CAN_InitStructure);' e# S" Z) k& j, [( P
2 S- B% z+ l9 F8 ^! g- /* CAN filter init */
* R& d+ e0 s, a4 N1 s/ q - CAN_FilterInitStructure.CAN_FilterNumber = 0;
! T0 ?0 S6 c m& @ - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
8 {- C* t' R) P; O' W - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
) U2 z- _- C5 r0 W - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
" U" c6 |& T% q- H - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
5 h( h$ T m8 ? - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
" P4 U( g# N1 H, K% D7 }; S - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
, V7 O& L, \. J+ j - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
/ }" Q9 L% i" g: d - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
& a/ U) y7 k; r - CAN_FilterInit(&CAN_FilterInitStructure);1 O4 c y7 I' x: M( `# T
- & v/ Z' C7 ~" x' N; K
- /* Enable FIFO 0 message pending Interrupt */ 3 r4 H2 D4 H* X$ o* f
- Init_TxMes();//发送结构体参数初始化
9 A0 @" a5 D/ Y8 M/ ~% R j - Init_RxMes();//接收结构体参数初始化
0 u3 b9 Y( r; K; N1 K" {8 e0 j* ^ - NVIC_Config();//中断向量配置
6 ~5 D% E0 T h# f: x. j o: a u* [6 P - CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
, m! x! b7 p- b S$ @6 N# Y
+ Z6 |; L8 F8 X7 F; ]- }
, \* X8 i3 z2 \1 k( F: B3 x - //************************************************************************************************************************************************! ~: K* v8 {( _0 m( _
- //函数名:void Init_TxMes(CanRxMsg *RxMessage)
) P4 v. e3 \; f) v% K - //功 能: Initializes the Tx Message
/ D) ~- ^( q8 h9 J0 I - //参 数:无% q/ M# A( B* P6 e$ t ~
- //返回值:无+ r3 E5 U9 G) L+ C; H, n
- //************************************************************************************************************************************************
: @ M, h" i1 y# Y - void Init_TxMes()
' `8 \/ [/ h/ I% }- ` - {$ `; q0 i7 O% K" `2 A
- /* Transmit Structure preparation */
1 L6 Y- \+ z5 l - TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效6 \& y. \( U# J4 e& ^0 I
- TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效 F- M/ a' V9 T+ y6 X5 R
- TxMessage.RTR = CAN_RTR_DATA;//数据帧
# q/ z1 ~3 J, k" C* C& P - TxMessage.IDE = CAN_ID_STD;//标准帧 - J w. r8 y$ O: F, \ T
- TxMessage.DLC = 8;//发送数据长度 DLC=0-8
0 x$ \5 M0 u. g* j# F - }4 b% w$ t4 Y& z; `4 p# {
- //************************************************************************************************************************************************4 J" A6 `' b4 u+ _! L
- //函数名:void Init_RxMes(CanRxMsg *RxMessage)
* P* {4 f+ V+ U& C2 }: i7 l - //功 能: Initializes the Rx Message" H8 t* V1 ]' E1 u8 n& {
- //参 数:无
4 k! i; h0 B; y/ W9 `% ~ - //返回值:无
3 V2 ]" v6 o! l/ m - //************************************************************************************************************************************************" h$ W4 @! M; Y T* N: s
- void Init_RxMes()
* U9 q+ P, o6 B0 }$ \4 p/ N% | - {8 g+ b, R5 ]% [/ n! d
- u8 i = 0;
4 R/ E$ s) f7 B- H; a - RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
3 n) z* c |0 ?7 K" p - RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确
6 E( C2 C: u+ f- W. Z - RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
2 M1 W7 e2 p1 B \. q% N0 w+ G5 v - RxMessage.DLC = 8;//接收数据长度
: E) T) }7 z+ z/ ^! M* I3 b - RxMessage.FMI =16;//????????????????
, G0 G) V# z4 t# Y2 s y
& u9 B) D" ]5 I" { e% i5 D" n2 m/ L; Q- for (i = 0;i < 8;i++)
) `- p4 w1 e' J: ^ - {
: @: e: Y! l1 ]6 ` - RxMessage.Data<i> = 0x00;</i>" v9 d! D! k0 P% g! @7 O
- }) T6 Q. Q6 _" u/ C. [: }
- } C4 m+ N) A% B' p
- //************************************************************************************************************************************************
2 r$ l2 G$ a \: i - //函数名:void CAN1_RX0_IRQHandler()
7 I1 o6 X& c5 F( T' D - //功 能: CAN1-RX0接收中断服务函数
6 A* [) |! N o, A- v - //参 数:无
% n5 h0 a: f% w - //返回值:无
8 c- S% \6 y" C3 l% A - //************************************************************************************************************************************************
" q& j3 S9 d8 ^! b - void CAN1_RX0_IRQHandler() //与CAN1_RX1_IRQHandler()区别
2 M. M: [3 Q5 ~6 X5 C8 a9 O - {
% i4 l5 P, a" G - if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
4 p8 T) r' Z" d+ d2 E& }- K - {
5 _" f# G3 _& C0 A - CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志( q) }6 W9 Y! k3 D4 r( }! A
- if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
5 }, u$ f/ O H; W* [- ` - CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节' h) H% S' C/ c0 R( z4 R
- }: w6 b, {5 S; ?0 k+ F! q* L9 C
- Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信
6 p1 L5 V, M/ B0 B+ ]* M% e - }
6 O* @. z# {: G$ w9 j5 ^& d - //************************************************************************************************************************************************
# ~; B+ z' L8 \2 Z - //函数名:u8 CAN_SendData()
- z- u5 |8 m b! k! R - //功 能: CAN发送数据 发送第二步
* _7 A, |3 k; v0 y - //参 数:Msg数据指针;Length数据长度* v/ [' m3 k L/ _ j' p
- //返回值:返回成功/失败标志1 f+ y! o$ ^/ ~& e
- //************************************************************************************************************************************************" P& U5 \. Y/ k1 x' S1 b: v
- u8 CAN_SendData(u8* Msg,u8 Length)
4 I) c7 ?9 b" J: p3 D4 b+ T2 K+ m - {
9 K! ^9 R) e7 z+ G* x% f! C9 a - u16 i=0;
2 i4 ~4 S+ P3 w; [ - u8 mbox=0x00; : \6 W" X+ E9 T" L+ d% t5 _
- TxMessage.DLC = Length;//发送数据长度 DLC=0-80 P4 e' o8 j J+ y! \$ l* J
- for(i=0;i<Length;i++)
& |* B, g9 J# M" v3 _ l0 y - {% \5 K7 J- ?& f0 U& 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;">;
+ S, A) `. j7 T" j0 l - } q5 u% V5 y$ P3 B
- mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据 返回邮箱使用数量/ H$ U6 ?8 o5 ~! f$ T8 B6 I, H
- , v7 H% x7 K7 A6 V% B
- // while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))6 c1 q; H2 y( n4 U0 m7 e) n$ j
- // {
# S2 g2 s Z0 t1 ?; G - // i++;" }) R; h5 P: R' J
- // }9 E' V& ~- w5 Y; e" f
- // if(i>=0xfff)
& M. c* X7 h0 o: ^( s; B' G - // {
6 P% a) B$ g! k; m% M - // return 0;//发送数据失败* {( v8 W# Q# i* V0 H8 F9 w
- // }
' N8 a9 ^* |! E0 { - // return 1;//发送数据成功
1 [2 U5 q8 X+ E3 L6 ? - }
# X) O$ F- [& a$ N* B0 i. K; s - //************************************************************************************************************************************************
. d9 N% C2 {4 H$ Z - //函数名:void CAN_SendDataProces(u8* data,u8 Num)
# [$ r% q7 W; y7 D - //功 能:CAN发送数据前期处理 发送第一步6 Z3 g2 S% i! H \
- //参 数:data数据指针;Num数据长度- ~+ h' S+ D6 ?1 I% {5 U
- //返回值:无
- b/ T- ~$ H" M5 {2 ~- H - //************************************************************************************************************************************************9 E C* z" q& N9 V0 Z- Q
- void CAN_SendDataProces(u8* data,u8 Num)
$ s# k& x- l6 R* K! K% c/ J ] - {
" x, O% o+ J6 Q" M4 ] - u8 flag=0x00,i=0;
% ]( Q) n. _9 n! G; ?, ?( V O) i - u8 Count=0x00,Left=0x00;
8 \8 k% J, n' K4 I9 L5 v( Q% G
2 B. W/ G, I% O5 J2 G- Count=Num/8;//求多少个8字节倍数! Y* k& _% x& a* a8 j
- Left=Num%8;//剩余小于8字节的数量
# y$ }' c6 n' V0 B% {4 b, S4 q - for(i=0;i<Count;i++)6 b( V$ [" L) R1 N0 }& ~
- {) l0 P7 v u! e A( T% P) }0 I
- flag=CAN_SendData((data+i*8),8);//发送整8字节的数据0 y9 R! u# P! [( q" E
- }
; B* ~9 l' |4 k0 r' i6 \& J! ^0 e - if(Left>0)//有余数才单独再发送一次& F( k, h! N. a+ C d$ D, V# M2 |
- {! ]/ i+ [# |. I6 H
- flag=CAN_SendData((data+8*Count),Left);//发送剩余字节8 U3 z- m3 K% Z( [3 ^
- }
* @, o+ R6 O5 A - }
* \- x! U2 K4 p - //************************************************************************************************************************************************" b0 Z: ] }2 l0 @
- </span>& H' ^) z1 }% h# k' t/ e) C* t; S
- </span></span>
复制代码
5 g( P' G4 E0 T7 O8 J$ _ |