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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:" w+ J" Z( A7 Q- j
  V% u% d% L% e$ A
  1. #include "mycan.h"
    " P; c% w# {" b) k$ K$ U/ J6 J
  2. 3 D1 r% b8 b0 A
  3. //CAN初始化) t/ x2 h5 i/ w5 g) [) u" E, I
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq9 O: m* T0 C3 s$ e
  5. //tbs2:时间段2的时间单元.范围:1~8;  K4 m7 _) B/ w* ~
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq7 `8 [! h7 x, x: C- w+ a! L
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1) m. }4 L3 V7 A6 x$ ]
  8. //注意以上参数任何一个都不能设为0,否则会乱./ {# a. p) U6 J$ c6 e7 H9 G2 X8 @
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
    " N- s9 S4 @+ s& l4 U
  10. //mode:0,普通模式;1,回环模式;
    2 I6 b, ]! |/ J2 F9 ?
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);* E+ p% |6 [) @" _4 B) [# B
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps/ L+ H% r+ i" b

  13. 0 Y. e0 J  I& I8 v, x3 `
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    1 W- X) O9 c, ]/ ^- H
  15. {
    ) ]  g6 e0 k  {- Q$ m2 N0 b" K

  16. / c1 Q" S" t. h
  17.         GPIO_InitTypeDef GPIO_InitStructure;
      h" F" q4 c+ i5 j( v0 t5 U; i7 _
  18.         CAN_InitTypeDef        CAN_InitStructure;
    % p3 Q! l+ s6 ^+ e& Q& ^
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    / a2 V& G. n+ r& s6 o3 o
  20. #if CAN_RX0_INT_ENABLE 9 [. D8 E+ G- Z7 a0 w* _$ R
  21.            NVIC_InitTypeDef  NVIC_InitStructure;- @, V: q( B6 f8 L6 N
  22. #endif
    6 ?0 Q% _! V  L- R! X; I/ G$ k4 u- E
  23.                
    4 Y8 M, \% {: M8 O& U6 V' I8 [
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    8 A8 [1 |6 o- s1 x  h3 u
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    ( F% `7 D& Q# l8 Z% f7 v
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        3 ?9 u. J' t( m7 C. F$ z3 j
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);/ O' ^4 x/ k; g3 `6 T* {
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);6 q( L6 y, l3 H4 v; T
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        
    5 D9 w; Q6 _9 A6 |/ y, f2 v
  30. ! d; r1 `6 Z% g% F( d6 g) l0 W& l
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;# G3 @: t2 ~1 ^3 M
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    ' Y3 S# [5 W1 p& o0 D# H
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    " T/ c: d0 P6 T3 T
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    8 i0 l: K8 _: a7 |
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    " Z2 Z* d6 Q/ t) h* Z
  36.                
    2 I" W0 X0 \% E9 U. \' N, y
  37.           CAN_DeInit(CAN);
    1 }) q8 G% `  C* N+ D! m2 \5 J
  38.          //CAN单元设置
    5 b  b8 Z0 {9 v$ N, e7 R
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //7 ]& D0 R% `: h8 B9 K
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //; u: W7 ^4 g+ [- Q
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//+ r) v5 g3 n- r2 n/ J! G; c
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    ; ?& j, `7 z; D3 ?+ H: @/ ?
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // & \5 K% H8 ^3 Q+ S% I9 m# b3 i6 ?
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    - d  K# ]3 z* Q4 i. K
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //
    5 {8 K5 j5 Z. p
  46.           //设置波特率
    0 H6 w. X1 F) G; y1 N
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    2 q2 z& ]3 ]5 p, @
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq" F7 W$ j1 D1 R& S! Q3 E! y
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq
    + v  {6 [% [2 p/ E+ p
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //
    & }& R' Q4 V( M$ a- I0 M. W
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1
    : F$ D  A4 W) |" M

  52. ' i9 E+ `/ |" e: L! V/ s
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0
    5 ^' }  S- u" M( f
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; $ b1 W/ }; X$ x# `5 F
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    " Z3 i$ B0 i7 l( t6 ~  p( n" z
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
    & v' n2 F/ t% f% J4 b- Z
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;+ D) ]5 v1 D1 @! [- K) @
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    - u, {$ J0 b1 f6 O$ S- f0 u* B
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    * c: ]  ]2 W8 G5 `3 O. Y+ c3 r
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0$ P: d" |( I9 R5 ~
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
    7 n6 v' c4 g0 |7 d; _: t$ p
  62. 9 C: n" N' G7 f9 G
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
    + [6 l: ]7 T8 D+ @: B$ |0 q
  64. #if CAN_RX0_INT_ENABLE  i: B' r! y4 B
  65.         6 f" y' t3 K9 d9 F: z  m
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    
    7 K$ t: C/ b  k5 h) L; r

  67. 2 Y' j. a/ b7 [  m2 q, H' L
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    " f2 m! Q1 P. c# I4 K
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1' X/ [" G5 i: g+ X) W+ u
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0  d  D6 c) a: T  y; c: k& J# T
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    0 F* V' h  {0 Q) F/ t. V* }/ J/ c4 {
  72.                 NVIC_Init(&NVIC_InitStructure);
    : q, x1 F+ g% V% t9 Q7 Q9 [
  73. #endif# W: N' L. h! m* U! D2 ^
  74. }
    3 D! r2 o; M: |$ U! l" _
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断* C+ h9 i+ d" A2 M6 S2 F
  76. //中断服务函数                           
    : S4 B) X  o) n$ w( c3 U
  77. void CEC_CAN_IRQHandler(void)
      i: y5 X* a" M$ S" S9 T- T7 P/ h. g
  78. {
    % J" ~! g) ~2 \% n
  79.                 CanRxMsg RxMessage;
    . N! g+ \, ]: I: o* G
  80.                 int i=0;
    ; q! m: Q: K4 T/ _6 j- L6 U
  81.                 CAN_Receive(CAN, 0, &RxMessage);% U7 B8 P- o# S9 X8 x
  82.                 //for(i=0;i<8;i++)+ [6 R  o  X3 Q
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>
    2 A1 R* W( Z; R$ {
  84. }
    9 L) x$ t. D- R  p0 S* }' v
  85. #endif
    / {' ]) |) l7 o$ ~; X( Y

  86. ) v8 }6 P; a4 K9 o
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        8 M' }5 i8 r$ T6 T
  88. //len:数据长度(最大为8)                                    
    $ h/ J! j4 _( p4 @" R) m5 a
  89. //msg:数据指针,最大为8个字节.
    ' N7 H' c& ~4 b$ f# q0 b
  90. //返回值:0,成功;
    ' F/ }8 q% p3 m4 `  g: G) C# b
  91. //                 其他,失败;1 V8 t+ d" w3 w$ ~: ^
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)- G/ k8 k+ N2 \. L- Y7 `
  93. {        
    ' L% I, v6 I" |7 w2 e$ v; A( N
  94.   uint8_t mbox;  @$ d" K9 k) l+ M) O2 S9 t
  95.   uint16_t i=0;
    ( A' @5 s1 K+ I* P9 X
  96.   CanTxMsg TxMessage;5 ^% K+ w2 a/ X+ g+ U
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为0
    7 ?! N% [' _/ I) H- B* V
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    - S, V( P; n# B* m- G; S% y% n
  99.   TxMessage.IDE=0;                         // 使用扩展标识符
    ! K- O" o; b: p8 h- d
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位/ q' c. e5 h3 G  u
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息& [. b! U, m4 W% h: w# J! B6 F
  102.   for(i=0;i<len;i++)
    * S+ I6 N7 m' O0 I, ?) \+ g
  103.   TxMessage.Data=msg;                                 // 第一帧信息         
    6 o9 ], Y* E/ N) s
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   
    . U; \( F' s- `( F* F; |
  105.   i=0;* b+ L/ N1 p! l8 ?2 `) _; N: x$ G8 V( _
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    6 f  d1 R6 [2 L, R
  107.   if(i >= 0XFFF)return 1;
    ! p( a" I* i5 y' F
  108.   return 0;                . {% D6 b9 Y4 @3 D& {
  109. }
    + C% m' L  l8 A9 m/ |
  110. //can口接收数据查询; j' K; M) E9 N2 m! q' P
  111. //buf:数据缓存区;         
    , l5 V6 Z& x  R; M' U
  112. //返回值:0,无数据被收到;  @- e9 Y' q0 Z/ o5 X' t* Q$ [0 ]
  113. //                 其他,接收的数据长度;
    % ?' P; G0 H  ^/ C  ?9 y, Y8 h5 \' b
  114. uint8_t Can_Receive_Msg(uint8_t *buf)! \  G2 c3 X" N  F1 T
  115. {                                      
    8 @+ U7 z$ O$ \. n: J
  116.          uint32_t i;
    3 b+ c% r' l# L2 X2 A
  117.         CanRxMsg RxMessage;
    ! c- o* H, h4 h4 z/ D
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出
    2 t4 {! K3 O0 Y+ `; Q
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        
    - p3 @0 _2 |" i6 m, c& A: s6 w) T& f
  120.     for(i=0;i<8;i++)
    8 h7 V. y: F7 U4 X& h+ C6 w
  121.     buf=RxMessage.Data;  8 w  I& u" u" U3 s, n
  122.         return RxMessage.DLC;        2 j+ S3 n4 Y! {% V+ _+ O
  123. }
复制代码

1 H7 H2 ?" S% h6 O$ ^注意:一定要根据自己的封装来设置
$ b+ |$ I! T" {0 C3 GSYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
) |0 ^6 l+ C$ j# B) I0 J+ c7 W如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败) L* D9 y+ |! W

) @* d6 d  [  u+ u4 y. d
' Z- Y; U- l0 B8 c5 @3 ?7 _+ ~" r1 d- @
收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版