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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:
6 c( k. F, G4 K. w) J4 x6 h$ S6 ^) h4 W: o4 N" K# ^
  1. #include "mycan.h"
    ; G9 k! Y( F" p; ]

  2. " |# v2 H3 X" j
  3. //CAN初始化
    : {2 h1 ?! h0 o+ u$ F* P
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq: }  `8 N, v4 T( @/ n+ X& v
  5. //tbs2:时间段2的时间单元.范围:1~8;
    / o" P: o! P2 J2 G! [4 H
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq
    - [$ m# G" \7 Z' G" h
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1+ y) |' h- Q4 I! I% p/ Z6 R+ Q5 _7 Y
  8. //注意以上参数任何一个都不能设为0,否则会乱.
    . \* z. |6 N7 p- ^2 O; Y
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);- |9 @' W7 ]0 X1 j5 D3 Z* \
  10. //mode:0,普通模式;1,回环模式;
    8 o9 X2 ^0 O7 h
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
    ! e0 a' t# I; L# J
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps/ c" a+ M& C6 Z7 ~8 h

  13. 4 j& H2 e2 a0 V5 ~% N
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    8 e5 \1 ]3 `& r' H8 k! g
  15. {5 Z5 O+ |: l* r; Y+ y

  16. ) K, v' _. B7 P, p$ o1 W
  17.         GPIO_InitTypeDef GPIO_InitStructure;
    8 ^4 A. ?$ _, f8 Q6 _
  18.         CAN_InitTypeDef        CAN_InitStructure;
    ! k. U* i2 V+ v: [/ u6 v
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    # Q8 r$ T, `+ s9 M& g
  20. #if CAN_RX0_INT_ENABLE
    2 H1 j/ W- R  i! {
  21.            NVIC_InitTypeDef  NVIC_InitStructure;
    7 X0 P; M# c% n4 V' \' a# ]# b% q
  22. #endif
    ( d' c! W) f! A0 x" ~
  23.                 + o* f) ^  R5 I1 d2 F. ^* p8 f
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    3 F/ Z) H. o" c0 F6 F# g/ A8 \
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    " e4 x5 {. q/ d' v$ t* j2 o; c7 i
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        ; J" Q: s* ~8 B" M# B
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
    " s0 i: ?4 K6 D, V8 B/ c
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);7 r) v+ n) K4 O! K+ N& J: S9 A
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        ) Y* _( i4 }: B& K; F1 {

  30. ) O) m$ [, D) t/ I! X( V
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;
    # k/ h5 j- @9 t+ E* I* l
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    . |, V% f# {$ Q: k1 H
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;4 D. U. H. A0 u8 l
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    * H9 n" B! G+ D% Q6 d( ?
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    ( v( B( D' r  k
  36.                   Q4 O6 z9 \/ G2 f! E
  37.           CAN_DeInit(CAN);) m3 \8 F  ^6 K7 b
  38.          //CAN单元设置% S# r  v: v+ ]; w5 ~' ~9 ~( t; p
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  /// |( d( ?1 }$ {! `* L
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //
    " Y4 x+ ~- m0 X) l2 f
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//$ ?: D$ b% s1 P- F  M
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    $ w5 l' O- q, R$ Q5 G
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // 1 L5 ~* R3 B& u) n3 n2 v. S& ~# {' U
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    0 G" h# a5 @$ x7 {* b
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //
    9 P5 b9 A3 c* \" s6 a7 e9 ^. v
  46.           //设置波特率
    : P' V+ u8 v% I/ u5 K8 ]* W
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    0 O5 B4 n5 _3 C( j
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
    6 i/ h( @( t) E# I9 ~  F* ]
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq9 d0 j2 d4 w  o( s, L) H# F$ ^
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //) v; M6 K. y4 o$ m7 x" H; s% W
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1 / b9 Y/ z# z, @4 g0 m) C

  52. 8 T$ a6 _6 G; V) y% x" c7 H4 K0 v
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0: `$ {8 h( K# P
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; - A0 v% e7 F$ ^4 Z+ e" V3 G
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    2 `9 X- K& [% L: v4 \; b0 p
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
    $ e0 T! M0 B0 C( @# {
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;8 f& i/ e) e  z& ^; h( u& n
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    * b# }  |2 [; n6 c+ D) a: ~0 E
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;+ C) B4 S( h  z) \
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
      B, N9 d1 ^9 [: F5 i8 j
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0; Y7 w' ^6 q' \" F. L' e$ P  A

  62. % g) {( f. [' G6 Q. e- \
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化$ z* q3 k& Z) O+ {" k
  64. #if CAN_RX0_INT_ENABLE
    & v1 c9 b7 _8 c3 x( ?+ n3 Q
  65.         5 _8 f& O  k: h4 \4 H% x$ A* q
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    + m( C0 Q3 d) h& r% m0 F
  67. 5 S8 D5 T: V3 s1 ~5 m- n
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    9 Q9 |# A/ P! X0 |
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    " D* I* r  r* P3 _) Q5 K9 k: \
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0( y6 P; H$ g. F5 Q- }9 K5 X
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;2 V+ D: K7 e) k# ~
  72.                 NVIC_Init(&NVIC_InitStructure);% Y; {5 R, a2 j& l0 y5 q" u
  73. #endif
    3 {9 D1 Z. \) F( l8 i
  74. }
    % V2 E( U5 N3 w# M% M2 G1 _4 T5 ~! a
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断
    * W7 O. C! i0 j3 ]
  76. //中断服务函数                           
    ) Y' ~$ u5 {7 j8 f2 _4 I% B
  77. void CEC_CAN_IRQHandler(void)
    2 V& r& a6 ?2 [( u( y6 ?
  78. {
    ) {" Y; l6 c$ F; B  z; e
  79.                 CanRxMsg RxMessage;! Q+ |% B4 E; t' n9 e# l. H
  80.                 int i=0;* q# h) ?" P1 F5 C+ p( g/ E" A
  81.                 CAN_Receive(CAN, 0, &RxMessage);. d5 a; @, g: z% ~
  82.                 //for(i=0;i<8;i++)
    ) h* L( h" ^3 I0 F9 M! u& K$ r
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>! r9 ]* O6 b7 b) T) t! ~
  84. }. S0 n5 o; z+ k4 p, |) I
  85. #endif4 w; \4 R" C4 L* a3 ], [- g8 d6 y* ?' s

  86. 8 T  v6 n/ C, l1 ~
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        3 @$ M! v. y- e1 E* v4 w
  88. //len:数据长度(最大为8)                                     6 y- J) k$ @6 \  g: m. S
  89. //msg:数据指针,最大为8个字节.
    ! J  o; D. M- P) O* L9 W. }; e6 q
  90. //返回值:0,成功;
    $ s( L* t2 Z* y: s) H* M4 j+ h
  91. //                 其他,失败;1 n7 O/ r2 f4 [& S. ^, ~
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
    * a/ [- e$ r# `6 e8 X0 e$ G' v/ P/ d
  93. {        
    . L% u# O: d" d& t% U" b# N
  94.   uint8_t mbox;
    5 H8 o& n8 P' D6 K( }/ D+ q
  95.   uint16_t i=0;
    : k& v+ {, N2 q; K% J
  96.   CanTxMsg TxMessage;
    9 ]7 \- s! l8 E2 E0 I: h6 M$ z/ t
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为01 B2 d. W8 H/ L4 }
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位); G& u7 M9 ?) \7 M5 {$ X
  99.   TxMessage.IDE=0;                         // 使用扩展标识符
    1 r0 J9 @* w' \1 W4 Y& i# M  _
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位
    . b( @& }4 D) U
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息
    - {* I" S- J) |3 p" l
  102.   for(i=0;i<len;i++)
    ( J9 `( Z8 M, f- a9 H
  103.   TxMessage.Data=msg;                                 // 第一帧信息          " j2 F# w, N5 k( B! b
  104.   mbox= CAN_Transmit(CAN, &TxMessage);     _' a6 V* f/ S2 m& M( J( E
  105.   i=0;+ {1 X7 m# [4 _+ ~' \( Q  j
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    9 o" a8 j, ~& s8 E9 R; t- f: C
  107.   if(i >= 0XFFF)return 1;
    : x+ y0 V  _, S
  108.   return 0;               
    . L! S% x' i5 z5 M: i/ _/ o) l
  109. }
    8 R2 o( ?# b# b7 L
  110. //can口接收数据查询' L( P$ b+ r( S: w& ?; e
  111. //buf:数据缓存区;         ) K  {$ f! y  p3 z; f7 m$ h+ R
  112. //返回值:0,无数据被收到;/ z9 U" b* o2 Q- k/ H& v
  113. //                 其他,接收的数据长度;" R0 f: j" ^9 ]4 ^( u
  114. uint8_t Can_Receive_Msg(uint8_t *buf)3 v' S/ y, u- W& w2 h7 K& s" u* ]; U
  115. {                                      0 v; w! A6 L6 j. W* F" x
  116.          uint32_t i;
    # c: U) v9 N1 S0 i
  117.         CanRxMsg RxMessage;3 o& z) h' g* Z  E4 B
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出
    : B, P7 ~) V7 f+ F9 L/ k( P" n
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        + }/ ?4 v7 f# Z! d7 Y" i1 d
  120.     for(i=0;i<8;i++)
    9 z% G+ B. H2 x( y, i3 U. r
  121.     buf=RxMessage.Data;  
    % C( t/ ^5 y0 i  x$ Y7 C6 @
  122.         return RxMessage.DLC;          s) Q! }! ~" |0 ^
  123. }
复制代码

. [* {$ I! v7 d9 D% Q注意:一定要根据自己的封装来设置
+ R- n7 e3 q& N9 H5 n1 K/ pSYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
- a5 `  E7 i- _如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败# d5 a/ i+ e( v8 M( n# T
. o3 W6 l, X3 V- c
. W: ]) @2 {7 m9 s" r) B
赞 收藏 评论0 发布时间:2021-11-22 21:03

举报

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