STM32F2-CAN通信-发送任意长度,调试好的,与大家分享. z9 c* p! ^5 J% a
+ |+ U: J7 ?9 ~4 z7 W- #include "include.h") ^6 H h' r0 I) e9 ]
- //************************************************************************************************************************************************) [$ A, C! A# y# B; }7 I
- //20190611调试完成
8 f7 I9 D# v: H - //By Wang7 r: o. R' M7 s p: P4 b
- //************************************************************************************************************************************************* J+ I# }( |2 a; c, S2 D
- ! o1 \) A& L4 r0 ?' o5 \
- CanRxMsg RxMessage;2 \0 p; e, ]( {5 E% c
- CanTxMsg TxMessage;
# X' S3 |. _6 z& K, i5 U/ g - //************************************************************************************************************************************************
# E% X% Z/ e/ M. h - //函数名:void NVIC_Config(void) V7 g- z/ K: b+ B5 Y
- //功 能: CAN通信接收RX0中断配置/ k9 @: p T- Z0 U1 i8 M) e
- //参 数:无# k+ N) X# H* u H/ P7 d
- //返回值:无
" p* g; _. ~7 Y. o, z8 r3 ~, H9 s - //************************************************************************************************************************************************
- g) J- t$ i5 A7 R3 Q8 K9 w
E2 v7 |- X# W1 L6 T f4 i0 x- void NVIC_Config(void)
9 v4 G/ o5 j0 ~4 M* L - {
" K i1 R' A% Y0 I - NVIC_InitTypeDef NVIC_InitStructure;9 D+ S+ m3 D& F+ v0 p8 v; y
- . g4 x" c! l, v
- //#ifdef USE_CAN1 + a- O4 g4 E* Z7 t0 X# V
, F0 P1 L4 e, |" k8 D; O3 \# Y- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别 E# o; V* |: E3 U4 f& V
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样$ v+ [' |. J M( p! [0 ~
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
( S( V5 A' h2 L$ } - : S6 ^8 N8 y2 z/ f( A2 g
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;7 E6 }( L3 y8 {5 g1 a T) r+ F9 s
- NVIC_Init(&NVIC_InitStructure);
# V$ ^; c) A- ^# r) R# @4 ~ - 7 _! c) _& p& K3 X* e
- }
# m% Z1 h3 a8 F, z3 l
! _ E2 L6 t! w/ V# d- //************************************************************************************************************************************************
; B& _( E H, [( N - //函数名:void CAN_Config(void)
6 T* ^% F* G4 K2 p7 z4 | - //功 能: CAN1配置 PD0-RX;PD1-TX3 J3 f5 u1 G# O+ p: g
- //参 数:无) W& K: }# O S
- //返回值;无
- M/ u9 y9 c/ F1 @% w) m - //************************************************************************************************************************************************9 o+ m5 [, @1 ?' W) o# J+ P4 C
- void CAN_Config(void)
" e! q4 Z# n; k. V - {" S' q7 {: U: f4 C3 E# H+ I
- GPIO_InitTypeDef GPIO_InitStructure; K% V+ u& @* o( Y3 ?
- CAN_InitTypeDef CAN_InitStructure;2 l* b& T$ {. ~- E1 l
- CAN_FilterInitTypeDef CAN_FilterInitStructure; C0 t: x( k+ K. l& W" ?) t0 W
- 0 {* ]. l2 C( Z" P5 z' j/ T
- /* CAN GPIOs configuration ***********************************/4 G2 {' I$ D5 | N' H$ s
- /* Enable GPIOD clock */
2 F5 |: ]- X) {/ o - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
# D1 X0 Y; i3 x. N' p5 X' j( o. n
, V# q& X. ?+ h5 C- /* Connect PD1 to CAN1_Tx pin */' c9 B( P7 X: j4 s% O# [' Q
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);/ _/ d; r3 r% f8 G
- /* Connect PD0 to CAN1_Rx pin */* G! c$ W/ ]5 t ]6 N4 _' s* l/ x; O
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);* T1 _ `+ n/ F5 g: T
! S7 p/ }' m' g8 a" A8 ^- /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */
E. I% v! E u; T - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
/ D7 c) ]% V' H o9 z9 _ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;. o: f2 k. a$ `" T
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;+ W }3 K% D- n2 W
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;% T% N* z4 T+ A+ M6 o% ]# i
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
8 Y1 x( }& p0 i+ `- N - GPIO_Init(GPIOD, &GPIO_InitStructure);# g+ u6 R! H9 [+ @
- # x- n! i* j0 u4 f
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
7 p3 v8 r9 ]& b. }% `" Y - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;, {+ W6 K; a6 \2 X. G, Z+ `" @
- GPIO_Init(GPIOD, &GPIO_InitStructure);1 g9 Q$ t. S- z% B$ r% g
- /* CAN configuration *****************************************/' P& F! y& q* z" @
- /* Enable CAN1 clock */
: M% {9 z2 ?9 o% i( E9 d5 t - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);% l; h6 H* h. z9 w4 P# Q
- X2 S$ R; ?+ B# c- /* CAN register init */& f7 f; I7 @- @: Q7 A# G4 Y" K+ n
- CAN_DeInit(CAN1);
. H( r: j. G( ~0 z I - /* CAN cell init */% f" d9 V( o3 Q
- CAN_InitStructure.CAN_TTCM = DISABLE;
5 P6 ?- y1 b# F: a( \3 D - CAN_InitStructure.CAN_ABOM = DISABLE;+ f7 L% J( \6 N8 r
- CAN_InitStructure.CAN_AWUM = DISABLE;8 L. W: d( X7 F9 x
- CAN_InitStructure.CAN_NART = DISABLE;
4 F3 Q( k) t* [ - CAN_InitStructure.CAN_RFLM = DISABLE;
0 m) ]1 B+ M4 t4 f - CAN_InitStructure.CAN_TXFP = DISABLE;
- t$ B- u, q% ?% E% K - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;7 a% [% o) H5 x
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
+ \- U$ y& w7 g& ?# N! ]+ P - /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k b8 x- t3 ?6 V) f Q. T, N
- CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
& j2 Q9 {# W4 ?( H! U! A - CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
6 o4 t0 Z8 ^0 H - CAN_InitStructure.CAN_Prescaler = 4;) G! Y' V) ^5 {* j u% w
- CAN_Init(CAN1, &CAN_InitStructure);% F& o" I; n0 i- |; T
- |' h S4 V; S4 y+ p- /* CAN filter init */
6 E& f2 }& y6 a! m& U - CAN_FilterInitStructure.CAN_FilterNumber = 0;$ s9 P' e' v: @1 N. j ] Y& q
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;6 W. Z9 d) z6 B* J; x! ?/ A) w- |3 N
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
$ f: i5 u6 y; p* D- W5 Y1 o. [ - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
1 S8 }$ M! h* C' n" e- P/ R - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
$ s0 C1 T0 A/ Z2 ^! F% F - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
! S t1 }3 c* w" q( A$ a. n" m - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;1 x1 s/ @! z( j2 i& U
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;3 ^8 D" j& a" N. ^6 V8 t3 d; e8 Y+ X
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;! I& C& y: R8 i* Q
- CAN_FilterInit(&CAN_FilterInitStructure);
' ]0 T4 m+ `5 m3 G3 I. z
+ F+ R0 \8 t" S6 l8 \" W o- /* Enable FIFO 0 message pending Interrupt */ 7 o# u v- N9 i1 V+ Z* r; W
- Init_TxMes();//发送结构体参数初始化 M0 }( F2 d' Z7 d( R8 {: M
- Init_RxMes();//接收结构体参数初始化
6 Y8 Z4 S2 T/ P5 n- `6 `/ l6 { - NVIC_Config();//中断向量配置& v7 O/ G/ w# J/ ?
- CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
. b" e0 b$ H% b9 K2 a5 K& e% J7 [" |
$ i" T( R" D# J# N; }, M) {& m' Y- }) o1 R' {' t4 z. H& x. s# e! y
- //************************************************************************************************************************************************
) J$ }+ k$ `9 j, J0 _$ j' s* G - //函数名:void Init_TxMes(CanRxMsg *RxMessage)7 R0 R/ B9 D# X7 E$ F! t, h! T
- //功 能: Initializes the Tx Message
, @- M- _: S: J( c4 s - //参 数:无
# X$ y1 I& e6 C- b+ \$ }7 A% } - //返回值:无
+ i( G/ C: {/ P) Q2 e9 e - //************************************************************************************************************************************************2 Z# b# f. _# i( y" [
- void Init_TxMes()
8 A+ c. \4 D; p - {% D9 ~ S3 s) X) S/ r
- /* Transmit Structure preparation */9 J& N4 i T/ [
- TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效) r8 D) m' U1 d; X* y# T9 h9 P
- TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
9 Y T4 l. q4 B: Z, q# l5 K - TxMessage.RTR = CAN_RTR_DATA;//数据帧+ _! A* {. S* C4 l
- TxMessage.IDE = CAN_ID_STD;//标准帧
2 a+ Y' x# z9 B5 n. K% Z, O& U - TxMessage.DLC = 8;//发送数据长度 DLC=0-8
- t2 v2 P1 i* S% U - }$ C0 ^" s7 _; S5 P Q. r
- //************************************************************************************************************************************************+ M" P/ Z# ^4 L! l# t( z* k6 t5 a
- //函数名:void Init_RxMes(CanRxMsg *RxMessage)( ]; V5 u% O! X' [# K4 L
- //功 能: Initializes the Rx Message
5 s: `+ H4 |, s8 t& N; G - //参 数:无
+ m/ X3 |: t. s- w( @ - //返回值:无: E5 Y6 z) S( v' v( I* x8 ?
- //************************************************************************************************************************************************* V5 ^% N" B$ A6 P- k
- void Init_RxMes()
1 H6 f( f* s4 a6 w0 M9 c+ V - {7 y5 m+ [; j8 p a- Q
- u8 i = 0;' b9 C+ e4 c! X* Y+ C# x4 m5 ^; S; s
- RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
$ J7 {' T" ]: q% P - RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 / `5 j% W% @" R9 ?
- RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
7 w9 Q$ k$ T+ x) V. ?+ i4 { - RxMessage.DLC = 8;//接收数据长度
2 G4 C& \* A4 K" l: B - RxMessage.FMI =16;//????????????????; W! f) W3 s5 X# p8 L
- ' H4 P+ t; g" E6 z4 p4 Z* z2 M
- for (i = 0;i < 8;i++)' K- U! z1 _) a6 [
- {
5 f( B1 E2 ~( D4 _9 h' ^ - RxMessage.Data<i> = 0x00;</i>/ K" y% e& ~' `5 i8 j) J
- }
& ?+ G! i, ~5 Y! f3 I - }3 H1 W$ w1 a* P4 F( b
- //************************************************************************************************************************************************
! u0 K" O0 T+ T" I - //函数名:void CAN1_RX0_IRQHandler()% q* E8 S8 |6 }
- //功 能: CAN1-RX0接收中断服务函数
! o. B/ `+ w0 u; x1 b - //参 数:无
2 R- j, Q3 f' R - //返回值:无
, l% u- @9 v) o - //************************************************************************************************************************************************
1 [1 w9 N @' r - void CAN1_RX0_IRQHandler() //与CAN1_RX1_IRQHandler()区别
3 J5 [2 O5 M9 e3 G - {
$ l' @" [5 C- j* [ - if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
& |4 V0 F) [7 B$ y' J# O - {! \0 X: x5 K9 Y7 {
- CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志
7 ], `8 x& \ r* z0 x! G - if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据; S: N1 T2 L6 u' r
- CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节( \7 d% d% s; ? V- V& w% N
- }
% @) K; l6 {$ g, m+ P" x - Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信
8 x A9 |4 U, D8 g, g - }6 ^. @2 Q+ o! k: i3 h
- //************************************************************************************************************************************************0 J7 M# F6 c% m* B- o2 @8 Q
- //函数名:u8 CAN_SendData()
* e( G9 o8 d+ q; q$ h9 h: g2 c# M - //功 能: CAN发送数据 发送第二步
6 m" v( Y; o6 L/ d1 x1 n - //参 数:Msg数据指针;Length数据长度% | F+ n" g" k- [8 I( t! y& y s
- //返回值:返回成功/失败标志- _8 y( v! E N6 x6 g8 ^
- //************************************************************************************************************************************************7 H$ D3 D5 T7 g0 D# S+ Z
- u8 CAN_SendData(u8* Msg,u8 Length)
l: B1 E4 S, H) P( ^3 l - {
7 u' h6 m: J. p$ U3 Z; F - u16 i=0;
8 F/ l% q( f& v% F - u8 mbox=0x00;
7 i' |& ^+ e$ v3 } n2 n9 i4 J - TxMessage.DLC = Length;//发送数据长度 DLC=0-8
# e' w8 \6 u$ [: u9 b6 u3 S8 ~5 Q+ h - for(i=0;i<Length;i++)
* N( Z9 ^6 i4 _. m - {) A# }1 \" E# ~$ ]2 Z
- <span style="font-style: italic;"><span style="font-style: normal;"> TxMessage.Data=Msg</span><span style="font-style: italic;"><span style="font-style: normal;">;# |; V3 b; T1 Y0 L9 Y
- }
% o7 p1 S: H/ e" b - mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据 返回邮箱使用数量
% `- U9 s' ` j9 W8 u m4 }
i V$ D4 w% A/ \5 \- // while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))
3 F$ h" }2 _" \3 a' G - // {$ N, b' {9 o$ j5 `" c
- // i++;; b& p. ~$ ?5 s8 m" h
- // }: Z8 k- F- b8 m
- // if(i>=0xfff) $ S k, S( T' F7 a- G6 m# D
- // {7 n* Q- {# C7 }/ J0 G5 [$ w
- // return 0;//发送数据失败2 C4 G& V! C: m( A
- // }
; R9 N/ X( e# f) U - // return 1;//发送数据成功3 i: R! F1 A/ Z$ h4 G$ \
- }
& t2 i1 w" P0 z3 U% Z8 h; j7 a - //************************************************************************************************************************************************
: H/ }0 ?8 }& }! A0 ^3 }! T3 U' y7 q, ^ - //函数名:void CAN_SendDataProces(u8* data,u8 Num)
5 |0 ~+ g+ _- J' e% j" _ - //功 能:CAN发送数据前期处理 发送第一步
Y$ `% g% o t+ ]1 o - //参 数:data数据指针;Num数据长度3 X5 M" y- M9 s0 D) W. k7 X1 Y% H
- //返回值:无/ k' Y V' o1 J, \3 Y5 T
- //************************************************************************************************************************************************1 p( b4 e' M+ i8 @8 \7 f) b" ?8 I
- void CAN_SendDataProces(u8* data,u8 Num)
( q2 f7 Y0 A5 t2 ^2 g7 N - {" j: s" ]1 i, v8 ~
- u8 flag=0x00,i=0;
: j" @; B( Q t" u) v$ ` - u8 Count=0x00,Left=0x00;9 D6 Z% b! d0 l/ Q# d
- : z' _ }" g9 Z1 @) `8 Q
- Count=Num/8;//求多少个8字节倍数
/ Z; V' c) s+ V2 M) _+ U6 L - Left=Num%8;//剩余小于8字节的数量
4 K* f+ L5 w( z0 t0 _2 G - for(i=0;i<Count;i++)* l4 S# q: ]" t0 Z' b$ E1 w
- {
" N! d! G/ o/ o/ E- \2 F - flag=CAN_SendData((data+i*8),8);//发送整8字节的数据
6 F& [: `" U" P/ I; v* e - } " @2 P* Q. n. A0 B
- if(Left>0)//有余数才单独再发送一次
' Z% p! F+ D; p8 T/ D# E2 H - {! M* Y0 ~; G8 T0 i: M% R6 R" r
- flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
# K2 l9 r3 D+ l1 G/ z - }, D9 g" I0 f* [# n8 u n1 f
- }6 } [1 V6 z5 z0 m
- //************************************************************************************************************************************************
3 B4 F3 k0 L ~, l0 z* P3 c# K - </span>
+ t/ a8 T, f! E. e! N - </span></span>
复制代码
T% j. \0 C' I4 V |