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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:: n( k! F3 @  i( [

  x" B+ D7 U/ Z0 W, k5 W
  1. #include "mycan.h"
    % e. r% ^) e7 ~  t0 I8 J' u

  2. 2 ?1 H& Y4 @$ D, Y/ D1 `
  3. //CAN初始化
      @/ }9 `3 l' J/ ]' E
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    % Q0 h" K" v5 M3 Z9 k% S2 d
  5. //tbs2:时间段2的时间单元.范围:1~8;% r% \1 A2 b* x' k) G
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq
    ' Q7 i" o7 _' \( F7 z
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
    5 b0 ?/ g$ n3 Z& d$ G  A
  8. //注意以上参数任何一个都不能设为0,否则会乱.
    3 D" k- o2 f7 G! @
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);! I' `6 Y9 Q# t4 z( Y' y+ B
  10. //mode:0,普通模式;1,回环模式;. a. W3 `7 ]% K2 S6 T) t
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
    : u# a1 N# c7 n0 p) n  ~; C
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps
    ' g* c0 P% \. d4 R  ^4 \* p

  13. " o" b9 m3 ~; ]( l' h4 n
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)/ R. v' W) F: r
  15. {
    2 Q2 L* v: W) S9 U
  16. $ f2 j2 Z  f8 f3 _, D
  17.         GPIO_InitTypeDef GPIO_InitStructure; / g8 Z- S- w& ~# ?
  18.         CAN_InitTypeDef        CAN_InitStructure;1 e& d7 h2 p- F/ g
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;+ c+ s. h6 V# G8 b4 V
  20. #if CAN_RX0_INT_ENABLE
    ( i# b: J3 ~) i+ W. {& l1 X" P
  21.            NVIC_InitTypeDef  NVIC_InitStructure;
    : A! `- S$ C( p! ~/ G' h
  22. #endif& P( P* H2 t0 Z) M& `
  23.                 ( L8 ], [  M- [2 I2 h; J6 }
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);" Q/ V7 [% U! v' p$ a% z
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    
    ' J3 h9 i+ n! y! `5 x! Y( z
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        % {* I. J$ U8 i7 Q0 b
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);: e7 `8 z. h3 F
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
    . F% b  q; ^$ I6 I
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        7 `) s7 n3 N: N: c5 h$ ?2 f0 N
  30. * j& z7 t% q, [. I! w/ t5 q+ N( S; F
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;; r; A7 |3 F# ~1 B! v
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;) ]/ `2 c. Z( a3 w% h
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;/ [6 j6 q  l* g9 E
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    8 G$ r& B3 D- J& _5 U/ x$ K
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    + Q8 F5 [. [0 o; `" v: w5 ?4 B
  36.                
    , @0 R2 b2 o2 @. w4 C
  37.           CAN_DeInit(CAN);# V& I) i9 Y2 q: ]! A
  38.          //CAN单元设置
    , ?7 T( w1 k1 r
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //3 C! H4 c! M1 d# L% P8 m! P
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //) j) U! O# p  {; ?7 W( |: L' c$ F
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
    " Z+ B; q! ]8 {/ W- K. F& M1 |1 W' T% U
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    - I5 s$ X' i) }1 V( n" i, N9 B
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // , \6 D2 P1 g# p. b
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    # T% i, O% h! w$ ]% ]
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //
    , j: W" }' h8 M. U$ q/ t+ h  O! O  l
  46.           //设置波特率
    - S. o$ Q) H# D  \
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq( w9 D% u2 T8 G
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq. B  C- O/ m& H# p5 l- n
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq, u4 z$ T; ]* \# a" D
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //& L; x! e" q9 e; ?" @$ r) I
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1 2 n$ b+ t" V! `" g
  52. 4 b# ?- C! a/ e
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0
    4 l1 r- a' p; V! ~5 m# C  ^* A
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 6 S$ I( I; W8 M  z, {1 T1 P
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    6 V0 \1 Z- W  R! e
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID- C4 [+ I6 l/ D% L# _
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;2 S2 \3 Q5 D) f. Q7 F7 ~$ S& @
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK! ^( ?- w: l* P, |. c, P
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    0 p5 y& @" E3 W. g$ G2 b
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0; U  ]" u0 E# E2 k
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0, D5 o/ L8 a* ]; `+ d: A5 _
  62. 3 Q, ^$ E+ C6 A1 V8 F: O
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
    6 W, P6 K1 J) q* n- f& L
  64. #if CAN_RX0_INT_ENABLE8 g" M9 M, F4 |' s, E( l
  65.         / ?- D  I7 v6 Z) [. p: \/ s3 T' w
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    
    ) p2 Y" H  u9 L( G

  67. 7 e+ L) M8 I( e, a0 s; \8 [/ @
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;: U& W/ Q  g' U/ [7 W/ Y
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    9 s6 \2 P7 ]+ s7 d
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    1 v& x: A6 l1 G" K2 g
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    & X+ f! _0 i1 q; ?% ~; _
  72.                 NVIC_Init(&NVIC_InitStructure);
    + K. I8 z3 ?# z. ?+ c; _7 ^1 K! C
  73. #endif+ t* {# [5 A! U( E6 k1 o' M
  74. }, q. _' J8 v+ ]( Y7 j2 P) B
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断
    # \  }. \1 j/ u3 \
  76. //中断服务函数                           
    6 r: `' T3 r9 o# b5 ~
  77. void CEC_CAN_IRQHandler(void)
    7 k' p" D2 Y* M( `, @/ E: ]
  78. {
    , H: F0 ?& h1 V; k' v# e2 ^
  79.                 CanRxMsg RxMessage;) ?' L* I- }* x6 h
  80.                 int i=0;/ a0 y5 I* n4 m7 u% S. q$ ]. ]$ O9 a
  81.                 CAN_Receive(CAN, 0, &RxMessage);
    8 C4 E, q% h: q/ ~  O
  82.                 //for(i=0;i<8;i++), F/ Y6 }. A* D* I) S
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
    9 m  C5 D. c/ g8 ~# ~
  84. }
      k; G7 W& z. g5 T
  85. #endif+ l: J% D: z4 ~7 u
  86. 8 X+ s' I9 g6 v
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        + E& i9 O  m; o0 N# w$ J
  88. //len:数据长度(最大为8)                                     ' C8 [3 u) Z  m( k' T5 e9 u0 i
  89. //msg:数据指针,最大为8个字节.3 X% h& z/ u3 [3 j1 R
  90. //返回值:0,成功;1 ]& N% ?9 C4 {- b3 H
  91. //                 其他,失败;9 P2 r6 |2 @5 `- z
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
    * g( b8 r1 E9 i: _. R+ C
  93. {        
    ! {; {" _4 r7 b  N$ l- S
  94.   uint8_t mbox;
    % C# {; |/ J9 O
  95.   uint16_t i=0;
    + e# Z' @: K  u% X& b/ l
  96.   CanTxMsg TxMessage;) p' h- T9 \: I
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为0
    / z4 |' A7 f" e+ E) c; V' N8 }( d
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    * T0 i2 B% J3 g, E) |. Z/ f& k
  99.   TxMessage.IDE=0;                         // 使用扩展标识符
    1 L3 H( B9 m( z- I
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位8 H: v  w: ]' Y5 j- ^' B
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息
    / ^' g3 K0 o/ I5 D$ }
  102.   for(i=0;i<len;i++)3 @% N1 g* ]5 ^3 W. R2 P2 V) M2 u
  103.   TxMessage.Data=msg;                                 // 第一帧信息         
    / ]# P; N" i' w2 Q' Q; s  M
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   $ y6 ?) V7 b  {7 S; P6 V' b2 h
  105.   i=0;
    + a0 E1 Y! u! `2 k- o8 j# b
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    4 y; c! C) Y2 E3 U! |% f. @, W  F
  107.   if(i >= 0XFFF)return 1;
    + [" N* M8 `0 o% v' I- g
  108.   return 0;                + c' s5 ~: T# ]# Z# j
  109. }  `( `3 T4 I& p. J- Y$ n
  110. //can口接收数据查询
    , A0 L' U" v* r- A
  111. //buf:数据缓存区;         ' ?+ ]) {: Y; d9 S+ s
  112. //返回值:0,无数据被收到;( U4 {3 S; Y( ?3 V3 `) @2 A  b
  113. //                 其他,接收的数据长度;8 o! L* b# a6 y- |
  114. uint8_t Can_Receive_Msg(uint8_t *buf)
    / d1 T1 c' M( h
  115. {                                      3 j6 p6 q* G# I9 ?6 W. f" _3 M
  116.          uint32_t i;) `7 O: D% t. F5 B) e$ ]5 [
  117.         CanRxMsg RxMessage;
    * f( A2 _- ^/ s% A
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出 ) m% m% _- [- G' s
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        
    4 i+ O) W8 d" _5 A9 Z6 a! d- F/ P
  120.     for(i=0;i<8;i++)7 y  M% p. v  m. L6 Z$ Q7 Q
  121.     buf=RxMessage.Data;  0 P' ^% y- O2 z5 b- u
  122.         return RxMessage.DLC;        
    2 t7 u, o; p9 p* h
  123. }
复制代码

$ w2 s: S% T4 H+ x注意:一定要根据自己的封装来设置
. m6 o7 {$ F" c4 YSYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;5 F: D) H" k1 V2 l/ B) R. x
如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败7 Z! Z% z7 z1 _  Z% U* N

3 Z9 x9 d1 F1 E9 R! e1 N$ Y# b" w& l  Y- t- I% _8 O  W9 i
赞 收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

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