代码如下:- M" Z# R1 J4 U' n) \+ l
2 N: x# H Y- Q( y( G
- #include "mycan.h"
8 @' k% C: S7 p - + z# W7 s2 n+ g. E# e4 B
- //CAN初始化8 i* }. s/ \& E0 ~& Q% @' d
- //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq9 k p8 v/ B( Q3 ^" T o, ~
- //tbs2:时间段2的时间单元.范围:1~8;
# S# w1 \2 Y/ ]3 T" t9 J - //tbs1:时间段1的时间单元.范围:1~16; CAN_BS1_1tq ~CAN_BS1_16tq% o$ g* Q% e; j/ [4 ?/ H
- //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk16 M/ K3 Y0 ?# b! Y* E
- //注意以上参数任何一个都不能设为0,否则会乱.5 @* C+ N4 ^5 k7 \2 D1 T
- //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
/ E" ]" {) x% ~" d' C - //mode:0,普通模式;1,回环模式;& i9 D0 L) }* M& @
- //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
- `' f5 n E7 Y - //则波特率为:48M/((1+8+7)*5)=450Kbps
0 s8 B: {8 |8 A" g& \1 @/ r - - j) ?% V. V( ]/ J- E: n3 e
- void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
) Q, T9 V8 L/ _; o7 O4 U - {) I- o8 u! a+ }* T# l- A3 a
; K/ |% l2 T3 y4 J- Z- GPIO_InitTypeDef GPIO_InitStructure;
% E9 Q, k2 k+ A0 ]% o - CAN_InitTypeDef CAN_InitStructure;
* A$ [/ W$ j. f! B - CAN_FilterInitTypeDef CAN_FilterInitStructure;
! q0 X1 j; v' \& [+ Y - #if CAN_RX0_INT_ENABLE
. q1 ^( v* B5 X1 _9 }) V6 h0 }! v - NVIC_InitTypeDef NVIC_InitStructure;
% w+ ?3 g8 m0 x' F6 {/ T: F3 U2 S - #endif0 N- z% r3 C) n4 W
- 7 b) r! f. {! t$ I5 z7 a
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);/ G, k; |. r6 C3 G6 M
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟
5 k5 ` w9 U. O9 G - SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP; //RMAP ! P7 y+ j6 @: p9 j
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);( y, ?. {. e( x y0 [
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);- L7 Q( I# k/ z3 [/ l9 ]
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟 0 L3 n- W! P d% K" Q
" X7 X1 K# G1 B% |6 G- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;7 R! h# P4 t, Q6 h7 ^
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
' x* P. N* I# t+ a: O( {% Z - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- q5 x5 U: C$ l/ P& a - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
7 A# o& J4 ]/ i - GPIO_Init(GPIOA, &GPIO_InitStructure);, r% e3 v" }1 P5 S8 F4 a. `
- 9 B- o' ]0 `; [: p8 o4 r; H* u
- CAN_DeInit(CAN);9 g; |. L7 U2 ^% |
- //CAN单元设置
y6 x& e5 H. _) r - CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式 //
* f$ E8 g8 o9 H; s, @ - CAN_InitStructure.CAN_ABOM=ENABLE; //软件自动离线管理 //) \1 y0 C, O! F- Y& ~6 [7 C
- CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
9 ]* ?8 h; l/ [' \/ ]+ ? - CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传送 //# ^5 V9 }4 e7 B: w4 R0 s- K
- CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的 //
6 C8 n" q. m. w) Z% d# c - CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决定 //
% n9 J% g. ^4 z2 c3 y; w u8 ] - CAN_InitStructure.CAN_Mode= mode; //模式设置: mode:0,普通模式;1,回环模式; //
' Y7 E1 J- P) J7 K3 h! Y/ p - //设置波特率
% r+ x, N7 S) p - CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
3 K( w8 v% z9 X y1 T# W3 ^ - CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq) \- x Y% B) x' W! L
- CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq& Z7 S, g& a7 \6 F r* T
- CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1 //
) n/ T& h, \4 y: r3 i$ i0 |$ Z' q' B" y - CAN_Init(CAN, &CAN_InitStructure); // 初始化CAN1 B, _. I# S; x* A& R
- ?4 D: t& x, A7 y7 e- CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器0
; X/ q6 ^& i9 @# n/ a; f - CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; ! |3 l8 b' a3 K$ b& \
- CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位 , ]. }6 J6 n+ x8 R8 o
- CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
' h2 Q: j& ~! ?2 r& C2 O) |0 y - CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;- h6 F |+ b! v
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK8 A2 M* @5 m# w4 o$ N! Y7 Q, p. x
- CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
- {# K2 ]' v- V- j: Q0 i5 R - CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO09 s( k: l, r, s9 c( B# |8 L, b7 a
- CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
1 T$ m/ A% w& X/ b; c - / d( H0 X- o& f3 H* @
- CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化, ^1 B" N+ B# O/ W6 e" f
- #if CAN_RX0_INT_ENABLE9 p. S, L/ ?9 j) I
-
, A' D( j3 x. G# c$ K3 k9 N - CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许. / f ~9 h2 v. w' _) [8 J) d4 p
E( t W+ J* m6 }% x4 y }- NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
+ X: L) C* X' Z/ W$ x5 t - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1/ j- w6 A9 D H+ a; k
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
6 _# q2 Y/ p2 h* g8 H - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;* O! c& s% F0 }
- NVIC_Init(&NVIC_InitStructure);
. |) k3 o. E f - #endif! f1 I; P0 w9 E# L; K* w0 a
- }) i$ d. Y4 t. b3 {7 q, }
- #if CAN_RX0_INT_ENABLE //使能RX0中断# v+ R( n. Z+ {
- //中断服务函数
) [$ G; u" r- d9 K( \1 g9 }5 T+ l* S - void CEC_CAN_IRQHandler(void)# q& D2 ]0 `& h4 \2 O3 Q' r
- {
7 B: X; A, S$ U7 r5 R& K( \ - CanRxMsg RxMessage;
1 o: v% g: n; s' z, Y( S) G - int i=0;
) f# k L4 n( q- `( @7 J: V - CAN_Receive(CAN, 0, &RxMessage);
/ w8 u3 r1 H5 B, h - //for(i=0;i<8;i++)% }8 Q2 z( X6 o
- //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
/ g3 @$ w N5 u, F8 _: {1 A - }
+ u1 d9 d8 P7 R' ] - #endif5 k! ]! }; c# I6 X' }& l( c9 w
- 9 W2 X2 s3 g0 _$ \7 ]- r% r1 Z4 [4 [
- //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
2 u2 C8 ]5 ]3 _& W, w - //len:数据长度(最大为8)
1 j; w4 z6 Q3 i: F: C5 e. } - //msg:数据指针,最大为8个字节.
% |/ \% J0 P B6 C% o. ^ - //返回值:0,成功;; G, s+ z1 m5 h, u
- // 其他,失败;
3 ?* Y. }# c% I- j7 v6 |% v - uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)) t4 }! f7 f1 \, k, d( p
- {
) G; d- k; z6 L/ ?) T% ~# ~ - uint8_t mbox;
8 `0 S5 `" o. a" o, U$ \+ \5 Y6 `- {% F - uint16_t i=0;
% g0 B/ H4 n5 U( Q0 e, N: e - CanTxMsg TxMessage;
5 ^/ b# g& X: K0 O - TxMessage.StdId=0x12; // 标准标识符为0
$ z" c8 b0 w- M( ^( X - TxMessage.ExtId=0x12; // 设置扩展标示符(29位)0 Q2 M# i, ~" E
- TxMessage.IDE=0; // 使用扩展标识符: N7 l; \" F) ?2 e
- TxMessage.RTR=0; // 消息类型为数据帧,一帧8位% k3 }/ X- F% U3 V5 S) j
- TxMessage.DLC=len; // 发送两帧信息
6 ]0 g# `7 K$ i2 _ - for(i=0;i<len;i++)
& t" D) p& ^5 G, K6 C - TxMessage.Data=msg; // 第一帧信息 & b& E2 e! M9 ~& b% t# m- N) }
- mbox= CAN_Transmit(CAN, &TxMessage);
* n) A! h3 H, C6 w+ @ - i=0;
$ N; C% s) f# V3 { - while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++; //等待发送结束
+ N0 k- J5 T4 {, N3 d0 A - if(i >= 0XFFF)return 1;
2 F) P" e" ^0 y0 G - return 0; 7 n; D# H5 y7 a, N3 u$ a7 w( Y
- }( c5 o2 n: S. b3 z- g5 O- e1 C
- //can口接收数据查询
% e$ D6 q& q+ a' @0 a - //buf:数据缓存区; ' F9 ^6 \! K4 A* c: p$ K
- //返回值:0,无数据被收到;
/ y9 r0 W$ ?7 {* U" z, R) u - // 其他,接收的数据长度;
( T( B J) a+ x7 A$ E - uint8_t Can_Receive_Msg(uint8_t *buf)
5 J2 o! }# V" H( `( I9 y - { + Q& A* n9 g! n# }( B$ ]9 t
- uint32_t i;
5 K. v7 a" g5 P% H/ h8 d - CanRxMsg RxMessage;
4 o& ?* T3 y) L, k# T - if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0; //没有接收到数据,直接退出
7 j) J7 h3 F/ K) l - CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据
4 D; L# M, k' R- F" Y+ ~( w - for(i=0;i<8;i++)
. [# [7 m. D2 q. q2 ^% u8 B - buf=RxMessage.Data;
9 u$ w9 A6 z. l0 Z% m5 {% G - return RxMessage.DLC;
6 d& S# ~# P1 \+ C' r/ Y - }
复制代码 & I2 Z& W# r l' q: ^1 e8 ?
注意:一定要根据自己的封装来设置
6 i( Q- V3 u7 qSYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
& Q; s8 ^. I, e! |1 a如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败
' g$ E) d( o/ o# q4 q1 `" v
4 N0 q/ M, j ~1 N2 b- |8 U. T1 t+ X. y
|