STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
8 z9 V9 C# V9 B# d
/ {' }/ q9 F: D3 ?2 d3 N/ a- #include "include.h", [$ T, M$ |$ X a8 S: L
- //************************************************************************************************************************************************& V; Q5 \2 _2 n
- //20190611调试完成
A: g$ U- D4 y: o. V* T* P - //By Wang* y' P. t& l. f( J. U( ]
- //************************************************************************************************************************************************
% {4 s8 T8 }, b
% Z, U. o; e& E6 }- CanRxMsg RxMessage;
: J$ L e1 Y4 }& p - CanTxMsg TxMessage;
1 d8 j# `8 S9 |( Q5 @! X/ G - //************************************************************************************************************************************************
1 O) d3 f' m' ~9 [3 ^ - //函数名:void NVIC_Config(void)
2 X ]# ?+ n" {6 v - //功 能: CAN通信接收RX0中断配置
/ y2 m& X4 p! Q7 k8 Q - //参 数:无0 P6 d% f/ n; v( d$ b E
- //返回值:无# ?, M Z" ?- f* [
- //************************************************************************************************************************************************4 F# @5 E$ b7 h2 _! K$ n
- 5 w! v7 U+ @% F. P0 e5 h8 m
- void NVIC_Config(void)+ F7 {6 `# B& d% y
- {+ [$ Z1 u* S8 n4 c' ^
- NVIC_InitTypeDef NVIC_InitStructure;0 T& \$ j+ Q: N1 ]- j6 j8 y+ |
- " K" ]5 ~/ N# q' D3 P
- //#ifdef USE_CAN1 3 s) I! {8 Y9 l# L
" ~) L# M/ ?# k" B- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别
" N# M* _. ]& T# q0 ~) K - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样1 O5 B) i! y8 P2 `
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
8 b/ T* o- A0 S! E
/ i+ i( ?- J- Z2 e! [- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- F+ X& s" p! ]9 x - NVIC_Init(&NVIC_InitStructure);3 T. C; A; P9 z/ W
" x- n! x4 K9 u7 Z( a- }
A3 A, P# t' h
6 e* Z X f, j" j& L( R1 a+ m- //************************************************************************************************************************************************
1 d, T9 I. d( Y - //函数名:void CAN_Config(void)
+ p7 S: n) z1 y( s - //功 能: CAN1配置 PD0-RX;PD1-TX
2 h6 a- S. F2 ~ s' D - //参 数:无
4 Y# e0 ]) c; V* V* p2 \ - //返回值;无
6 C6 o0 @2 N' d' e4 {2 X# ~ - //************************************************************************************************************************************************
) T H1 [0 B6 `5 b7 t6 l1 j - void CAN_Config(void) [, B9 |5 F5 b. E) J
- {
! t1 `; M1 \- w- e9 ] - GPIO_InitTypeDef GPIO_InitStructure;6 e- h4 x; Z+ H
- CAN_InitTypeDef CAN_InitStructure;
& x% q% K( K6 v7 }' u9 { - CAN_FilterInitTypeDef CAN_FilterInitStructure;
/ L8 W2 E7 ~& ~# B: ~8 } H7 \4 g - / d9 g* ~' J0 S. c- m" ?/ u
- /* CAN GPIOs configuration ***********************************/
8 ?- a2 u- d7 P" F$ {" M - /* Enable GPIOD clock */ s: A0 e6 e5 D9 _. Z0 N2 Y9 v
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
0 @' u. b4 v( q( Q3 V
, X% j" ` G1 f" q* l. d% j- /* Connect PD1 to CAN1_Tx pin */
# d+ f4 m. X8 Y - GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);1 P- Z; p5 w7 i" T, ^. P
- /* Connect PD0 to CAN1_Rx pin */
8 }8 T9 C5 ~% i# c- T - GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);4 j- e3 Y+ i( R/ q
* ^& \1 b" f2 f% \4 _2 M- /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */" |5 s( N# {5 }: y, J6 |! z- Q8 h
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
: b2 |; {) `9 K1 n( q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;! V, C' B- ~' Q; @8 Q+ n& W6 q
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 R9 @4 r2 I+ a) [' h! ~
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;5 q" O1 t0 P0 q6 J% K6 i' u/ x+ @; F
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
# P; G$ `, g: y8 a! o - GPIO_Init(GPIOD, &GPIO_InitStructure);
5 T) Q( o" e6 q @5 ~* _ - " H" ~. P- t0 l* j: O
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
$ r8 Y) G* l# v) n& X3 ? w - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;" t: g N6 }, B, \' {. J/ ^
- GPIO_Init(GPIOD, &GPIO_InitStructure);
1 h& P" i& p, x: s - /* CAN configuration *****************************************/
, w5 h8 f9 {8 ] - /* Enable CAN1 clock */
" e8 [- A, }" ] - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);# P+ f& K( D+ L9 `# o) }7 i
- # k- ~) H0 C. r: {% X
- /* CAN register init */5 y$ A# B1 d8 v6 l$ D0 E
- CAN_DeInit(CAN1);3 J9 k' N2 z, G/ O* b8 l: u
- /* CAN cell init */" x1 ^2 J" b9 x3 y. V
- CAN_InitStructure.CAN_TTCM = DISABLE;
/ Z: ]$ Y. i' X& |9 O - CAN_InitStructure.CAN_ABOM = DISABLE;2 ?! [9 L+ l* i. C) d6 ^' [' Z
- CAN_InitStructure.CAN_AWUM = DISABLE;
, B& y; i- D) s - CAN_InitStructure.CAN_NART = DISABLE;' n$ o' o n5 g. P' V+ B, N: q/ t
- CAN_InitStructure.CAN_RFLM = DISABLE;* E c/ n0 ?2 f# c4 y2 l3 W
- CAN_InitStructure.CAN_TXFP = DISABLE;
( y4 k% O: V6 @1 X - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
' r6 t* j1 L5 G. g$ |! a. p - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;9 Y( e( h& Q+ q& @
- /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k" `) y0 u V m5 b- u
- CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;, H7 u4 H0 v, f
- CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
0 ~; I# A" {1 S/ G7 _. r8 f - CAN_InitStructure.CAN_Prescaler = 4;* S$ X8 d( {4 C
- CAN_Init(CAN1, &CAN_InitStructure);
* b; g' S4 f3 x( K0 } - 3 s1 U6 F+ L; ?4 B9 P0 r+ v
- /* CAN filter init */
5 ~' s) w* z% T1 e i; n5 s - CAN_FilterInitStructure.CAN_FilterNumber = 0;
& x P6 l% o- T. c! P4 @ - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
) |+ z6 l3 L: o) L7 j6 a - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
u5 N, k2 z. p7 p1 p. N7 P. e - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
! p( A/ t. F+ e - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;9 d" J9 M2 f2 x, \- |# G+ |
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;) e, H9 N. R! k" j/ B+ ?7 F
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
6 T$ I/ ~5 I: n" c2 x1 M - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
3 t; `6 M& E% e - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
o& T( D% `9 O, H, f& T - CAN_FilterInit(&CAN_FilterInitStructure);2 g) V, P) G& R: n. q
/ t1 B% [4 {1 J4 ]5 q6 d! M6 n U- /* Enable FIFO 0 message pending Interrupt */
g- E5 n$ E" a9 M* t - Init_TxMes();//发送结构体参数初始化+ a& F" |. D3 r# h! D* [9 @. ]
- Init_RxMes();//接收结构体参数初始化, j5 E; u+ r& L' W) {4 i: B
- NVIC_Config();//中断向量配置
( ?2 d7 _# G& G# h - CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);9 l/ _% k+ M' h% O
2 p0 h6 t- P# W% m9 t- }
$ S6 W+ T* B5 O - //************************************************************************************************************************************************6 H, ~; P' H$ ]
- //函数名:void Init_TxMes(CanRxMsg *RxMessage)
* H0 h/ k; _5 J: u( Z( } - //功 能: Initializes the Tx Message
7 A0 e3 s! E3 c9 ]5 o- U - //参 数:无* m1 m2 Q* x; u- ]" [
- //返回值:无
" k% U0 J3 }5 m - //************************************************************************************************************************************************
: ^- C I7 o- g! q" @ - void Init_TxMes()9 z8 p% G8 n6 e: P7 _
- {! K6 g! z2 [* o/ i' P2 B
- /* Transmit Structure preparation */
" I4 H/ l% i$ D4 z. @1 ]" p- S - TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效
! a7 J0 C0 P( C+ v: o7 H4 u1 e) F - TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效, n2 D1 \; j" `) P$ Z* x; N3 w1 l
- TxMessage.RTR = CAN_RTR_DATA;//数据帧
! y" ?- |% M9 X6 m - TxMessage.IDE = CAN_ID_STD;//标准帧
& V+ p, y& m( p* v; ?+ b3 ^5 d - TxMessage.DLC = 8;//发送数据长度 DLC=0-8, m9 q: i- |; K8 D
- }- H3 p) ?" i, q* o* g
- //************************************************************************************************************************************************
8 t5 j4 b4 d, Q( p& S S. Y% O - //函数名:void Init_RxMes(CanRxMsg *RxMessage)' Y+ q& T& G# i8 ^. Y. n0 E
- //功 能: Initializes the Rx Message& a% n! S. c* D# B
- //参 数:无
9 A/ u# Y$ o0 U' z - //返回值:无
: w6 S/ J0 F* h - //************************************************************************************************************************************************
1 V+ ^: K% l1 ]& v" B$ _ - void Init_RxMes()8 _8 C% x$ p7 `7 w: U
- {
1 T0 z/ E1 `( C5 N2 B - u8 i = 0;
: L7 {7 w+ c' S! o - RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
c+ A7 X" F3 L6 E8 L$ i - RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 3 d" D4 t) {' U" [! u8 B7 }
- RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
1 W% e. q7 C( ? - RxMessage.DLC = 8;//接收数据长度/ e9 E- x, q6 U2 k
- RxMessage.FMI =16;//????????????????# I; C6 U \- C* x
- 4 t& A2 C! i5 r
- for (i = 0;i < 8;i++). f4 q8 }# f3 X
- {% x8 b N# \, l# W
- RxMessage.Data<i> = 0x00;</i>' b: |# m% U4 A" _; Y; \8 M; v
- }$ y' M, [ C, O q: B
- }! `9 O/ \0 y8 M2 j. a/ U4 H
- //************************************************************************************************************************************************
8 o1 ~& W. n7 G - //函数名:void CAN1_RX0_IRQHandler()( |! |0 @0 Z0 c9 M+ ^( l( [. y
- //功 能: CAN1-RX0接收中断服务函数
2 Q$ m' u+ _5 T5 A - //参 数:无4 E* g' I# C' Y% ^8 H5 e; b
- //返回值:无
2 L. q h/ ?7 v4 ? - //************************************************************************************************************************************************
, m3 x2 O0 z; J, v7 V - void CAN1_RX0_IRQHandler() //与CAN1_RX1_IRQHandler()区别
3 O+ J" \5 _ p. R: D; e6 P2 v3 P$ S5 ^ - {
* ?$ a$ U$ V/ v! y# W" t6 S1 o - if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断& n! ~& p5 W- Z; ?* R$ F
- {
% x+ I; a7 \: s; O ]8 g - CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志4 g# ~' y& |" I8 U2 h7 j; [; D
- if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据# G4 h7 M% u1 c; N9 q
- CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
# o* ~+ j/ y; X9 B- P. X - }8 k, @" I8 c+ O
- Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信 6 G) O$ W2 g0 L( b
- }: N4 ^2 o% P/ f4 L3 U
- //************************************************************************************************************************************************
! I' a- X: W2 ]. _ - //函数名:u8 CAN_SendData()
8 l2 ^4 v, a1 B4 p+ ~ - //功 能: CAN发送数据 发送第二步
7 F# u3 P$ l7 Z1 x0 X: l - //参 数:Msg数据指针;Length数据长度
2 C& [% e9 v' R- ?+ k - //返回值:返回成功/失败标志
6 u) K. l& i, B) x2 p2 p; ` - //************************************************************************************************************************************************
; b0 \+ E" [- U, Z - u8 CAN_SendData(u8* Msg,u8 Length)
$ F/ I, ~3 P: K' I( V( X; n - {, M% C; J! V% `; \
- u16 i=0;
0 k5 p4 ]0 c2 s( }" c - u8 mbox=0x00;
1 p! O# h5 ^. a; j W0 B - TxMessage.DLC = Length;//发送数据长度 DLC=0-8" z L0 R7 J5 J; {# n$ D
- for(i=0;i<Length;i++)
0 R$ J' {$ X& {# _# c% S- Q& b2 t - {
! Q0 [% z- Z) O J1 b1 j @$ | - <span style="font-style: italic;"><span style="font-style: normal;"> TxMessage.Data=Msg</span><span style="font-style: italic;"><span style="font-style: normal;">;1 R2 R; l0 p- o6 ^* ?* Z
- }8 g( S% F6 ~3 G }0 g4 [+ v
- mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据 返回邮箱使用数量
/ ^1 e* H# E( L2 a8 l& l
) d0 t8 Q% `' a& g* H( D- // while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))) v; `& V$ w3 _+ E! P8 ]; p- |
- // {4 }& x; B1 u! X, o) A, f
- // i++;8 B2 e P" J) Z, m. Y1 W
- // }3 l$ V6 l: i" x$ W0 q* u
- // if(i>=0xfff) , k' U& Y0 C+ `. n6 S4 ^8 i
- // {
8 V( [; C4 [- s% ~: H$ s6 ] - // return 0;//发送数据失败
) y' R, c6 w% z) z4 R* @ j+ q - // }+ D3 ~5 Q9 b5 k, I2 ]9 u/ q
- // return 1;//发送数据成功
( _/ q1 t% M! m- ?8 F4 [( k - }" e& ]9 I1 n/ D! N5 d q0 R
- //************************************************************************************************************************************************
* ]2 W' B$ o' k' i$ N' [ - //函数名:void CAN_SendDataProces(u8* data,u8 Num)
6 g) R- F8 ]$ y9 o& Z% [ - //功 能:CAN发送数据前期处理 发送第一步
5 }$ [9 g5 K h& i1 b - //参 数:data数据指针;Num数据长度# r, ~! H- v, q3 c$ a
- //返回值:无" G. }: p& q( N8 `% l
- //************************************************************************************************************************************************: d1 u8 C8 ?$ @
- void CAN_SendDataProces(u8* data,u8 Num)
* o) P, } T# c: D - {
0 }- l- W6 u$ t% q3 q3 ?% [" G - u8 flag=0x00,i=0;) z' \6 ?( k# _+ j' @& b2 v- T
- u8 Count=0x00,Left=0x00;
8 _) C, J% t1 j5 t* G - 7 t# v1 M- f5 }3 R2 ~: p
- Count=Num/8;//求多少个8字节倍数
- W/ r. Z8 ]9 H9 w - Left=Num%8;//剩余小于8字节的数量& A' x* s$ c) p" _
- for(i=0;i<Count;i++)) L2 ]8 [: h9 ?* J5 n. ^3 a2 x
- {& O+ O- E" @( ~+ N' U2 z$ ~
- flag=CAN_SendData((data+i*8),8);//发送整8字节的数据4 Y, K; x$ m ~9 ]" v9 f
- }
+ S: s* A' H: S: A- o- V - if(Left>0)//有余数才单独再发送一次8 s/ k" k f- \: e0 N5 J
- {
+ C4 i! [. X- s - flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
2 I1 p( r$ W! L& s; a% ] z - }9 O& q* \. H/ [# H) b
- }
" p3 m4 S! o; g - //************************************************************************************************************************************************
3 C3 h' X. ^. _* y6 j c; T0 f - </span>8 o9 j- n+ G9 i2 f! R& t
- </span></span>
复制代码 3 u- m3 D/ c7 r, } }2 a
|