你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F042 CAN使用例子

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:
# c  f4 P( g5 b+ k
0 P% F& Z) k0 K& g( h+ \2 E( w0 _- A
  1. #include "mycan.h"
    + o! d: \2 I' W( E

  2. 1 ~) U! M. y9 F4 i" ]+ r
  3. //CAN初始化' f6 a, `! f% V$ H" A
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq5 T" p. l  M. f9 e: s' J& v. o/ D3 L
  5. //tbs2:时间段2的时间单元.范围:1~8;
    4 ~% t2 G$ f! F! b3 X
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq5 i5 [+ @( Y7 J7 r' _0 `" n8 }
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
    # P7 D$ @3 T2 e3 {3 }
  8. //注意以上参数任何一个都不能设为0,否则会乱.7 A; g( S- j! E1 s% g+ I/ T2 J7 M
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
    2 i+ M% |3 Z6 q$ ?& e/ p
  10. //mode:0,普通模式;1,回环模式;- N: |8 ~! v* O8 M& Z% \
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
    ) N( `% h8 V( E4 i1 U* ^2 `3 g8 q
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps
    7 Q2 q/ |* W" |9 z# N* M" w

  13. & X; A/ H) w+ t
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    & M" m, g; s* \% L  C& ^
  15. {
    " i1 i5 b! x! U- R8 O* V0 U

  16. . o, C4 {% G8 j5 o) N( K- f/ Z  s1 k
  17.         GPIO_InitTypeDef GPIO_InitStructure; * T  _' M( u* x$ u" s$ ]
  18.         CAN_InitTypeDef        CAN_InitStructure;  H6 L2 d0 s( q5 [6 `' I1 n
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    + V# T7 t3 E7 n7 S# F1 J/ s) ], L! [
  20. #if CAN_RX0_INT_ENABLE % U! w5 b4 [& N3 d& f! ]. f
  21.            NVIC_InitTypeDef  NVIC_InitStructure;
    ' m- S3 C+ t' O9 [, E( f6 I
  22. #endif' v: ^! s( e+ O
  23.                 1 s& ?* p& b* V% o7 ?. K
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);7 f# Z# E8 R* l; R
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    3 u  \3 E3 b0 g" Q
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        . w" i! @" `7 s
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
    : P/ b9 P/ a3 S/ Z
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
    : m7 Q' i1 \: J( D6 @
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        ' k% d* X6 e7 K
  30. - C& D' ?6 [! K
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;) Q! x& e% y1 b# r! n; c
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;4 `: A/ f+ O! k. y; i, V
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    , }( H! H- g* I8 t/ ~; k9 s! Y' V
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    ! V, ]: l" F+ M( o6 |
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);: z( N9 B7 ~, m
  36.                 / z3 ~/ p* D6 U) c: s0 R
  37.           CAN_DeInit(CAN);' e  @, M  H- G
  38.          //CAN单元设置0 s5 c1 Q& p: G# _
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //
    - u. J! f* p/ K
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //4 t$ h6 A( V. l9 t( X1 _3 c) m, T
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
    0 z: ?; y4 ^: R% V
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    % f' e! l% A8 I0 k) j& z* x
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 //
    % ]; R5 I: \7 r) x6 Y5 D% h+ S
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    5 @! M: `2 N5 A: U
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //' a+ F4 t# m7 F7 J
  46.           //设置波特率
    . B8 g# s# L' N* N4 R0 X
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq& F8 _/ z9 F) a, b7 H+ n# E8 o* e
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq' m7 E- u& b8 m" S, ^  w, Y
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq
    2 w2 \% n# i. ]5 I& n0 u# @7 O) F
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //
    7 Q( h3 k  v5 U; Y7 ]
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1 ) S" y. B$ g- J5 w# H
  52. # w3 a/ e- L- O' i" o0 k
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器06 F" @* B$ f  k$ f- ]
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
    . n& T- Z4 V" s; J& [5 w" L
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    1 M& J& [, K8 e6 G
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
    # v  a9 x; \, S7 z
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;! P- y$ ~7 R. c1 G
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    3 S1 _8 H% l2 f+ w3 M% ?# ?- K
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;! o, l6 n, c- l6 `3 Q. d
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO06 [! e7 F. f* G/ g! j; u4 S
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
    # b% E5 M9 R8 y0 Q  o+ o0 C
  62. 3 w3 Y3 |) a4 x3 m  A1 l$ h& j
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化! ^2 I4 {3 v7 l3 h, i
  64. #if CAN_RX0_INT_ENABLE: T5 Y7 s( V7 R+ }: x6 L4 n' |
  65.         / u$ j, L' [# F4 F* H; j# u# B
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    9 `, l1 b: {4 v0 T! o
  67. $ W% C! e( z: R* H- o- H
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    0 s' b3 q/ m: W3 s' x
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1; n* }9 ~' s! g6 J4 D
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为02 x8 j/ P# o) W1 o& Q
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;4 [+ f, [" c/ l. s% c: q! h
  72.                 NVIC_Init(&NVIC_InitStructure);
    , c4 j  ~+ ~* A/ [) M8 F+ w
  73. #endif
    * @) ~3 |0 [# ^' w& w5 ~
  74. }. N; n3 g" o! g# o* I5 l+ d+ U
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断- |) A: n! _/ V( ]3 {- _4 T
  76. //中断服务函数                           
    ; n% A4 N0 v! C+ ]
  77. void CEC_CAN_IRQHandler(void)6 T0 J& Z$ y  d4 q
  78. {8 m4 C& F1 }2 L$ T% H
  79.                 CanRxMsg RxMessage;6 N  a" ~6 Y. s4 g0 v! S
  80.                 int i=0;
    1 e, C2 Z5 r+ ?8 Z
  81.                 CAN_Receive(CAN, 0, &RxMessage);. k" Z) Z0 k0 ?& S
  82.                 //for(i=0;i<8;i++). w- ?% I. }+ ^' ^4 `
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
    ; r' c$ @9 B. |% |  a4 ^& b$ Y
  84. }( S  P/ u2 i, G) q
  85. #endif
    * O- V# N4 v7 k5 R* E) v! B4 M
  86. + f- E, m" F8 g7 R! }
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        
    & K* D+ [: _  R/ n4 j4 \' ^5 s
  88. //len:数据长度(最大为8)                                     % e( T9 s$ X7 c
  89. //msg:数据指针,最大为8个字节.
    ! Q, G% u) o# r$ g0 a' n5 f
  90. //返回值:0,成功;
    9 V8 Z# z6 E. X' x' u
  91. //                 其他,失败;
    6 N7 k1 w$ ?- d
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
    ( z/ f, O- x7 _* i+ B2 f
  93. {        " C8 A# o9 ]& N' ^2 A
  94.   uint8_t mbox;
    / Z6 Y8 ]! [' j* S" J
  95.   uint16_t i=0;
    , U5 V" O3 M4 \& `! j
  96.   CanTxMsg TxMessage;
    9 ~8 j% W6 F, f
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为0
    + N9 i; ^8 r) \; M/ e3 q  E3 H
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    - D# s% d3 G  o; H
  99.   TxMessage.IDE=0;                         // 使用扩展标识符) D5 U. j. l6 q/ O6 c- A
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位
    / d4 U- L: f7 L' W/ t# f4 B
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息
    ; ^6 n  b. Q3 [1 n1 |
  102.   for(i=0;i<len;i++)
    8 G  r4 q; @$ B) n* B+ E
  103.   TxMessage.Data=msg;                                 // 第一帧信息         
    1 O2 v. T' A1 R$ |& D. z
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   
    1 l+ M* {% z4 u- g# B3 t
  105.   i=0;
    ( G2 w7 V' o. Q; w, h
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    9 e7 M% i* D! r* G* q
  107.   if(i >= 0XFFF)return 1;4 T! C# W) N8 O) Q) f
  108.   return 0;                8 S, G6 R/ L( G$ ~) I" T, e
  109. }) V  i& l2 E7 \- a. N: M
  110. //can口接收数据查询
    8 E( s( V7 d- T, E+ o; a2 }9 W
  111. //buf:数据缓存区;         
    ) Y* l- @6 l! k( G
  112. //返回值:0,无数据被收到;
    $ U+ e% e) l+ C  t! w- p
  113. //                 其他,接收的数据长度;
    5 v6 @/ a4 g6 p7 X' p
  114. uint8_t Can_Receive_Msg(uint8_t *buf)
    1 V, H9 P- }) F1 [: a0 e' m
  115. {                                      
    6 j. k, _( V- J6 M9 ~& q2 M8 ]
  116.          uint32_t i;
    * s6 w1 E) n" ^$ [
  117.         CanRxMsg RxMessage;# Y0 w4 j, Q% _3 _
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出 $ b2 u2 U9 s# x* m7 r7 e8 A! v- f- q
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        
      R0 N8 m6 {+ q+ l' y
  120.     for(i=0;i<8;i++). c5 d7 v- i/ T( {* g2 n" ^/ i7 R
  121.     buf=RxMessage.Data;  
      k! u. d5 ]" e( T; r, b; ~
  122.         return RxMessage.DLC;        
    3 v0 d- H/ @+ _7 w( M" T3 R$ b6 D
  123. }
复制代码

8 S7 f7 t/ k6 O  y+ X+ p注意:一定要根据自己的封装来设置
6 l3 r5 V* q& Z" u3 aSYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
# w: _# I9 P- J6 H% f如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败7 S  N- @4 h: Y8 G" B& @
" ^/ z- h1 _3 v& n0 E# m" t+ n0 a
" V* h" ]# G6 H, d" r
赞 收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版