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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:
( {* r, n! I9 v  Z/ B! r3 k: ^0 I
9 \! ~# p0 I( d! R7 V
  1. #include "mycan.h"
    5 j& j0 w) N9 m# i" t8 q& p" Q
  2. : N% R$ b; v; O* ?
  3. //CAN初始化
    5 A# O. ]) ]- @" N, o9 ^
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq' r7 y, p6 p7 _* ^3 H- a
  5. //tbs2:时间段2的时间单元.范围:1~8;
    1 e4 j" |) ^) i/ E* l8 X
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq% P( s4 \1 M: t
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
    1 K" U& i- L' i9 z8 n
  8. //注意以上参数任何一个都不能设为0,否则会乱.5 F9 V4 I7 f0 r4 n; J' }/ l
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
    & u4 t. V7 ~7 v' p! P- m( I
  10. //mode:0,普通模式;1,回环模式;6 Y& [! P2 g6 s7 X
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);! @: }$ D1 N+ w! O3 _
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps
    9 m; G+ e% K" e' r" ]6 Q' U

  13. 2 r/ Z. d' V; g4 T0 j5 c
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)" m3 g, {1 _0 _5 s3 L" D2 T8 @
  15. {
    ) U  v0 c- N) C. |
  16. % o$ B8 A* b" J. U. E+ g, J% h
  17.         GPIO_InitTypeDef GPIO_InitStructure;
    " i) e* I. d! @: q- z+ [  ~
  18.         CAN_InitTypeDef        CAN_InitStructure;
    / W! z, |" B# h$ z
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;& m- O2 A0 }0 c, w4 T# j: u/ Y
  20. #if CAN_RX0_INT_ENABLE % n! w# K, b* k. [2 x3 J
  21.            NVIC_InitTypeDef  NVIC_InitStructure;
    , H4 v) b7 @; N% U# k+ U. X
  22. #endif
    $ y& t) Y  p) y& y  B
  23.                
    0 k) ]' C2 u) O- A! a" q$ \4 U- B1 }
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    5 P3 a8 N, U0 g8 i' r. \
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    ! c" t. F1 r3 w/ V& u% m$ y+ X- d
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        6 ]" p1 x3 Y# M& j" s7 t6 ~
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
    - z! J! W( u4 @* C: b; Y0 j3 e1 F+ A
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
    9 T5 ?$ t5 n0 J3 I9 i* H. y2 o
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        
    1 C) w6 y2 F0 ~" M

  30. 4 }2 \8 a( J* H# x8 |0 k
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;
    ' I6 [( }% S" a
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    ' l7 v# K: e$ y7 O: J- k
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    : G5 G/ O9 @& e- {# s6 _
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;+ x" T8 [6 N1 T  m
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    4 F9 t" r( D: R1 o. L  Z1 g
  36.                 1 s+ ]! V4 W# f! p# v) p
  37.           CAN_DeInit(CAN);
    - s& B2 X* s: S
  38.          //CAN单元设置- O6 Y, P! |5 {( ?2 V8 O9 P
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //3 d2 W; i% @* ]3 |3 u4 S& q& Q
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //
    5 |5 w# k% {6 g5 h+ T
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//( k  s- b! j, f; |
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    5 P6 u( \! h* F" \
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // " f7 v! q4 V+ m' E  @+ z4 F4 {
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //6 O0 n* g+ @& Y- ^
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //$ r. r$ {( S6 U
  46.           //设置波特率# n3 u# J) b3 S( ~: m! o. U6 a4 Z
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    # ~4 {4 W; Y3 b- h: n4 ^4 J, T) k
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq# F5 Z2 \+ x3 h6 i' |3 X$ t. i, J
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq
    ; C: F; R7 G- G* [& f- k# [2 [  M
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //
      D3 [8 C# [/ y0 v4 y7 P
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1
    * ]( q4 g) F) K/ w( m; q7 |7 X

  52. 5 q+ f4 _; v' j% u& f1 X0 @
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0
    3 W* j: r$ D, h; ?; q, [* Z# `
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
    , ]3 w  E% S  g8 f/ Z
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    / M' D) a; I* _6 j5 G
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID; Y% V- F- I' g" a4 W
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;" B) g, ?- v0 I& m* C8 G: G
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    8 `1 n8 e( J8 Y8 ~- J0 W
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    - C& g( l0 B, y* S# y  G4 I! ~
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    5 u  z' o) ?9 m8 k( m
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0) y+ P. n( s1 ?/ a9 c  V

  62. ( Q! n+ c# u+ G, n
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
    0 c0 _" Z7 `/ B4 T2 L
  64. #if CAN_RX0_INT_ENABLE  L6 {1 N" S+ g
  65.         
    ( B- f. r% F' i) I$ u) L
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    : B- l! |! I. j8 {, H* H, |' n
  67. - ~7 p( J+ C9 h
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;5 H* D6 t2 i  Y. B
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    . v% N/ a9 v* K9 h& f/ K0 m
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    7 w) v$ K2 P) g
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    ) G4 j: i& s" s5 c
  72.                 NVIC_Init(&NVIC_InitStructure);
    ; X- F. e5 t+ [5 p; t' W
  73. #endif
    6 ?, {- G3 w0 W7 h0 N; x
  74. }! z* h6 r4 B( p" O7 y- _5 a* M
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断
    ' P  @9 c2 o" M3 `8 I6 ]& u( K9 K6 F) l
  76. //中断服务函数                           
    8 s% |  U5 S0 g3 C+ e# U
  77. void CEC_CAN_IRQHandler(void)
    : G2 O' }" [( e/ j& m! t7 n( f! z
  78. {; @/ B5 l/ ^  n: U
  79.                 CanRxMsg RxMessage;
    8 v( B! e+ J, ~( c# g6 G
  80.                 int i=0;
    " ^7 N& b0 F2 m# d
  81.                 CAN_Receive(CAN, 0, &RxMessage);
    0 p+ f2 E- {7 A) y# ?/ R
  82.                 //for(i=0;i<8;i++)$ Y: x5 U5 A, u# @- {* i% y
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
    ) u7 ?( }( z" [5 M1 Y+ y
  84. }
    ) `1 L8 ]4 D# M  t' Q, I
  85. #endif
    # R9 t5 `9 ]4 e6 r# x- T

  86. ) u! o7 `/ d+ O1 @/ |: H* C
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        
    9 d9 S7 J2 h" V
  88. //len:数据长度(最大为8)                                    
    ( I, Z' I3 j! T
  89. //msg:数据指针,最大为8个字节.
    3 F8 J' R0 K/ q9 F* f2 R8 N' S
  90. //返回值:0,成功;( p7 D' N* Y9 k( a; W+ O9 K7 k
  91. //                 其他,失败;7 {! f5 n0 _% o1 L6 Q
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
    : J- i) O3 i0 ?9 ]
  93. {        
    0 g3 d; H) f' s9 B, \( X9 r
  94.   uint8_t mbox;
    1 X! B/ i) \8 s$ T  r6 a, J
  95.   uint16_t i=0;: E( f: }1 c/ ?1 p, A7 D* V7 Z
  96.   CanTxMsg TxMessage;
    - y  C; ^: E# h& {2 r3 h
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为0& q. K& A: }! z. T; h7 j' c
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    * T0 D$ I0 N( v2 s
  99.   TxMessage.IDE=0;                         // 使用扩展标识符# v. q' Z2 F5 E( r2 `: O5 `
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位: k( }, g2 D" N& y
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息
    2 q1 _6 ?6 ]8 J3 I, T( g
  102.   for(i=0;i<len;i++)6 r5 x* c+ n6 ?6 A" [  C
  103.   TxMessage.Data=msg;                                 // 第一帧信息          / B. z+ m5 Z! F" d4 Y
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   
    2 c$ ]; z: W. Y8 k7 Y
  105.   i=0;# X9 M  S! u3 G. e
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    6 O3 a! M3 c7 V( F8 l) y  ^9 h& b
  107.   if(i >= 0XFFF)return 1;
    " i( _9 m( C) k$ a- C$ I# t1 ~. ?  t
  108.   return 0;                $ y' m5 b- w& J+ ]7 M
  109. }
    : x  I! @6 G  e6 p4 O# ?8 b
  110. //can口接收数据查询
    . X  y& ^% j* B1 \1 K/ [/ A8 |. @1 q
  111. //buf:数据缓存区;         
    & Q, f4 W5 k0 f4 t5 F
  112. //返回值:0,无数据被收到;1 B' Y2 {1 Z, H) S, i% e
  113. //                 其他,接收的数据长度;, [; g* C8 O4 I/ ~( ]
  114. uint8_t Can_Receive_Msg(uint8_t *buf)
      f  g' @. ~0 V6 V
  115. {                                      
    / x8 t( L  T4 o3 B* U' z+ w/ N/ V
  116.          uint32_t i;
    0 h1 p5 d; F, q
  117.         CanRxMsg RxMessage;
    , L4 r" P. v  z( E
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出 4 z8 `0 X9 I* F' w/ t4 [+ _
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        8 o! ?1 q: {2 `8 q7 ~8 {
  120.     for(i=0;i<8;i++)
    , p* L: }4 n3 n$ f2 W8 v5 B
  121.     buf=RxMessage.Data;  
    1 @: W" p# X6 L8 P0 Y
  122.         return RxMessage.DLC;        
    3 c6 y, e7 x# D9 W$ f
  123. }
复制代码

6 |# c# b" Y. z6 G& ]% u注意:一定要根据自己的封装来设置6 S( L0 d* z& v* [
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;6 P. i% ^' P! T: w" M3 X3 u
如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败7 t7 r4 w8 d5 _# n7 X

! E9 f2 ~$ O  T: z0 I7 p6 p1 U9 Y" R; |# U
收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版