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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:* A8 Z6 r: N* t7 i( E

5 w1 ]& }4 s! v# g3 f3 ^/ b
  1. #include "mycan.h"
    ' F* o% L2 M# @% g  F( ^. M
  2. $ Q& M+ u0 V' Y9 Y  F% _
  3. //CAN初始化
    $ P: K9 L6 A3 r( e+ @: W+ H' Q
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq' Y, T' x% a' ]/ T7 J8 [
  5. //tbs2:时间段2的时间单元.范围:1~8;
    6 F4 p6 j5 V  O" W
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq$ X8 e# D% z8 T- H3 t8 F
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk12 J! ^3 w) Z! f4 a# R$ j& ^1 q
  8. //注意以上参数任何一个都不能设为0,否则会乱.
    * m, [6 _, A( M
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
    6 ?4 O9 R" W: f* q- Y
  10. //mode:0,普通模式;1,回环模式;
    ' Q! o1 a1 C+ B
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);5 B9 B2 `+ }1 |' y
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps0 v" P( K9 f5 J$ \

  13. : z6 W2 S4 E- q3 A) R6 }
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    " Z8 x4 A1 O/ K2 S/ ~
  15. {
    $ L: x  @% K0 Y2 R
  16. + |) d$ o* a& s! [
  17.         GPIO_InitTypeDef GPIO_InitStructure; & S5 V; y$ G9 L* ]& U, X
  18.         CAN_InitTypeDef        CAN_InitStructure;
    - q7 Q1 i+ q# K
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;' k" y# w! j' u2 C! o% e' }
  20. #if CAN_RX0_INT_ENABLE ( M; B* O) V' i$ E+ j
  21.            NVIC_InitTypeDef  NVIC_InitStructure;/ @7 z0 a* [9 H
  22. #endif
    7 w5 x2 [' u/ b# i7 ^% N$ z& M- i
  23.                
    . j5 w+ S6 m# O
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    # T6 C2 t5 a5 ~8 g; |: X  u
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    
    + M& ]2 K: ]- I* ~
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        $ C6 ]$ r/ o* K; f- W2 v% E+ f& }
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);, `, o" y, F( C5 Q0 a" g
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);# @# d& }9 d- J$ R; @* j7 U, B
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        
    . ^2 ?7 l/ }. j! x5 ]0 z8 I

  30. - }3 i! d% c% |2 \
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;% Z2 z% i% w+ z" b& l
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;" Q; M  R: m9 C) J9 T3 s1 Y# }1 M
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    ) j' `5 a0 }0 f5 n% w) c
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;/ h4 M2 b2 W5 j2 C7 b% O
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    1 m' [! k6 @# U  J
  36.                 0 a5 u7 m5 O$ m5 K0 G
  37.           CAN_DeInit(CAN);: d* }3 u3 |* o' r5 J
  38.          //CAN单元设置9 {8 O: R( B/ E' O; Z" U# |  s- f
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //; c  T/ D' [! i
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //$ i, C/ C& n, A7 @
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//& z7 g: ^7 S" b) N& M
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //1 ^7 Z  }: O' \% B7 i4 m7 P
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 //
    4 A  h+ L5 Y9 [1 [
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    / p1 S9 z" ]! s2 b( g$ `
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //
    & w& n6 G# h2 i! {
  46.           //设置波特率
    " w  `) ^" D; l6 C
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    " X9 a1 E5 r5 l6 @
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq. k# W/ V  I0 g+ S) I8 @4 M
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq  }# [$ g( S$ q& G$ i! u$ m
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //
    + P# e/ y" e* P
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1 # h4 r! H6 ~! s; I1 O- f! O
  52. ( \& ?" Z* U5 `0 n- r$ }' |
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0* v6 y$ l5 A& P0 V5 k! m1 a
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
    % s( W7 `8 H/ H) w& u5 n
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    4 P8 ?3 }. d% e+ j$ w
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID% ?, {# ^) E  J  E6 h2 e
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    * }" P- Q' X2 X5 Y0 M- x! A
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK4 F1 m: @! d) E6 z3 z
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;( _9 l5 q! X1 M. x: ?' @) f
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0% B% @/ ]8 u+ I8 k# G5 b
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0& c5 y6 e, s: c7 \( B! _( C

  62. 9 v* s6 A- D$ B" J5 s2 {# z
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化; A5 D( ^  F# p( J5 _: _$ y
  64. #if CAN_RX0_INT_ENABLE+ F1 t8 R0 r2 d# F+ p; f, y" s
  65.         + L9 Y( t/ y1 A6 X, Y2 j& T
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    
    4 {  s7 M/ y$ ^; G( [2 i+ f
  67. + h% J; L' W8 u: ~/ b0 a& A' J9 s
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;9 Z( G* L2 l/ [/ e
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1# K$ n' q3 p( Y
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0: m9 V+ |. w  x* b5 h9 M  C4 K
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;) w! D2 Y3 M- q5 J4 C( p" ^0 {* u
  72.                 NVIC_Init(&NVIC_InitStructure);& D9 Q& J0 h6 I% M- j% |
  73. #endif
    3 D# L4 c# ?% W4 o
  74. }9 d1 \$ }3 h7 ~
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断
    ) |9 [4 k+ E  }% @6 n$ P
  76. //中断服务函数                            ( A# Z+ s/ L$ f$ X
  77. void CEC_CAN_IRQHandler(void)
    & H- i) w  c7 |/ G5 F' E
  78. {
    . |3 B" ^! Y$ ?; {7 M2 J
  79.                 CanRxMsg RxMessage;" R' |1 \5 `1 U
  80.                 int i=0;
    : }& A+ S$ f5 {. O1 Y
  81.                 CAN_Receive(CAN, 0, &RxMessage);
    1 G* y3 @' ?- Z- T6 R
  82.                 //for(i=0;i<8;i++)
    # i6 q% C  J- U7 z3 k. H0 ^3 n: N
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
    ) @, m' W$ f$ m/ z& G0 U- V2 ]! e
  84. }) c" Q9 u! P2 {" n8 b& f. x& F
  85. #endif
    0 Q2 s, G8 p' C3 V1 B" }6 H) T

  86. % C' S! `2 H$ z% ?! ]$ O
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        : \4 a) l# `7 q& h( G+ H  y
  88. //len:数据长度(最大为8)                                     2 D3 ?  k9 N5 x
  89. //msg:数据指针,最大为8个字节.' W% ^7 F! i, D* \2 M) L% r
  90. //返回值:0,成功;
    ' H$ s( }$ s2 ]! e
  91. //                 其他,失败;
    ( W% l, W' b+ }3 @% Y$ c
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
    3 a& N) |! T& j1 o
  93. {        
    ! I4 x8 R- z; f. s( [3 f9 e8 F
  94.   uint8_t mbox;
    , z0 \& y" A( y3 u+ q3 p; Y& j
  95.   uint16_t i=0;
    - T2 c% o% }" P1 }8 \
  96.   CanTxMsg TxMessage;7 s) ?$ X1 Q5 T$ o
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为07 B" T' p% ~0 V5 v
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    4 f* `* d: r, d  w
  99.   TxMessage.IDE=0;                         // 使用扩展标识符' F8 S. K$ f# q1 K$ }9 ^" t
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位. g7 P5 _3 @3 o3 M# o
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息
      X# F' j$ q/ r4 X7 W! i
  102.   for(i=0;i<len;i++)
    % G, x; D1 \9 R/ R/ }4 Y# b1 a
  103.   TxMessage.Data=msg;                                 // 第一帧信息         
    1 ]( Y4 ]) P. Z
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   
    3 S" m$ F* H  `# O  d  x$ ]
  105.   i=0;& D: j9 c9 a: ~% z$ m" n
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    8 j4 t: E& g/ I5 J; T
  107.   if(i >= 0XFFF)return 1;
    ) }' O' }! ]: x" z! J, K
  108.   return 0;               
    7 H: ~- [: W- o6 |' R1 r2 [
  109. }
    * ~! K" X! d# k) ~0 F
  110. //can口接收数据查询! L, s9 }0 V( h3 E
  111. //buf:数据缓存区;         ; r& Y0 r2 Y* k* b+ {0 m& i3 H2 r
  112. //返回值:0,无数据被收到;
    0 A$ c/ \" {" P
  113. //                 其他,接收的数据长度;: }: @- L! @3 {( F$ q
  114. uint8_t Can_Receive_Msg(uint8_t *buf). V& E- K3 Z  `' l( s  |1 z
  115. {                                      4 {, ^) P2 d- N. p5 J( c
  116.          uint32_t i;( X5 @0 }+ s; m! [6 w! |  ?
  117.         CanRxMsg RxMessage;
    ) F4 `( [" L, v* [% Y4 V
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出 , x0 f7 g5 F, O: W! |  b$ a4 r. c
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        + F9 y$ x# o6 o8 ~
  120.     for(i=0;i<8;i++)
    % h* ~% y3 z( z5 B3 O/ E4 l
  121.     buf=RxMessage.Data;  ( y  k& f4 Q( c. U8 z* s
  122.         return RxMessage.DLC;        : T) M. U9 ~) s! K: P2 B& w) B& r
  123. }
复制代码
% n) O4 S, _) ~* N/ q4 E
注意:一定要根据自己的封装来设置7 S, z; h0 ^. l1 P, i# s4 d- N, x2 }
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
. j( |5 m7 f* k& a/ Y3 U# b如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败
9 q+ V# C" Y) c0 f( U4 G! h( A& f
; v5 a) E( A0 `' {" G# W
- W0 ~" K  g9 g6 ^! s: D1 d! }
赞 收藏 评论0 发布时间:2021-11-22 21:03

举报

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