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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:
* Q8 N9 u; f5 L$ X# V; W) U1 o9 Y0 X
  1. #include "mycan.h"9 U) t5 k$ H( T; X
  2. & x  |* {4 P8 A1 _8 r! k! A- x  b
  3. //CAN初始化& C; i& i& b2 }5 f$ s# V. ~
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    8 n& h9 L9 A. [) r# R& L; h
  5. //tbs2:时间段2的时间单元.范围:1~8;) o$ P. `% K  z" {2 M1 G
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq
    1 u2 E% s. u+ s* R
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1! ]/ h3 O5 K1 }
  8. //注意以上参数任何一个都不能设为0,否则会乱.
    , k7 t1 S. s/ g6 w8 E% i/ G8 C
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);1 v" ?) U9 r8 s; u1 H" ~* R  @: J
  10. //mode:0,普通模式;1,回环模式;
    6 c( S; m5 Z+ p* R! V7 L
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);  `! e2 ?! Q! W# {
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps4 N: y' p. g$ ?1 g: c2 b

  13. % H7 ?1 b1 q# [6 `
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    ! k# i5 M( k0 I. k) c) S
  15. {
    : g9 S* _: M/ R0 z/ t

  16. 3 a3 k+ ~8 i6 b6 q0 }( G
  17.         GPIO_InitTypeDef GPIO_InitStructure;
    5 t$ u# w! E( s6 H
  18.         CAN_InitTypeDef        CAN_InitStructure;; v- f! s4 N) Q7 v" V
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    7 B; D- t3 `8 T) ?2 Q( W
  20. #if CAN_RX0_INT_ENABLE ' V5 C/ V+ o5 @9 e( _# E
  21.            NVIC_InitTypeDef  NVIC_InitStructure;. ]+ A$ E! t0 ]
  22. #endif
    8 }9 r1 K' \( b, P/ W3 j, {6 Q) d
  23.                 5 s4 f3 `4 r% Q3 Y
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);9 D6 F3 }5 Q, |4 l# `
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    
    ' E8 L3 w4 K/ W0 ?$ K
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        0 p( P" i4 V" X9 E
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
    ( @  ]0 p7 g* E: _
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);$ d# l2 [, c1 J4 }
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        
    ) g+ R- ^5 q' u$ D* `
  30. 1 X  m' U7 d$ `4 d& w
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;2 o9 f9 Q0 z9 B5 y4 m  H) a
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    1 ?1 q( ?% {0 p/ @1 F% N2 {- x$ I& G
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    # k! y3 F- r, X% f& ?# e/ `! H
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;/ G- B' h. I' M+ D. S6 q
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);6 l  t2 {. }. F& X
  36.                 8 X6 Z2 g0 u: r
  37.           CAN_DeInit(CAN);
    ( v( e7 J  X& S
  38.          //CAN单元设置+ f& y7 k! }  W. A/ |/ b
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //* c5 ^+ j+ G" Q% |* c5 `4 z
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //1 e, @/ c- L; ?0 G1 D' q/ {
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//# a+ W2 b; y4 i! C
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
    . p2 x$ Z  }+ D2 B  e/ p
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // 0 ]( ~- G% U$ ~. M" o+ l$ q, D" W
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //' J* M* `, ~" q3 T7 `2 S
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; /// Y; }- [% G! u8 F; I* q
  46.           //设置波特率! n5 _. ^, e7 k; g4 j% A" [
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    9 B! K! E+ w8 b* M% S7 `
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq. L& f- h2 O- Q2 q! @6 I
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq( j' f! d+ F/ d) w* g8 `8 e
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //' l9 j( A, W( ^7 ^3 r$ e3 s, }' ~6 j
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1   J9 P- D& R7 \' d' i2 ?! r

  52. 0 V) Y& `. T$ |- F, D; B1 o& m
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0
    " j, h$ H8 i* E# B! t2 [, d& ?% k2 s
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; " O) e7 |+ A3 l- G$ g* \1 S/ H
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
    7 C5 Y  x0 E- E! H" |8 I, Z6 V" j
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
    * V# I8 \' M! s, a1 r$ k
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    ! x% G( p$ g5 I; K- R. H
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK' m' \- L! o1 i  [& _
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    9 N1 ^& p# l9 _' `
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    ' C; Y$ t$ I+ r4 h
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器00 v6 u! Y; `6 W% N* Q
  62. " ^1 ]8 D/ {8 N) c7 B
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化  j+ X& |( b: s4 l2 K# N) [
  64. #if CAN_RX0_INT_ENABLE
    7 f9 E% |% m2 B
  65.         $ Y4 }4 d- J( t) ^/ j% g# }
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    
    3 M: B* P& I; k$ `; s6 L- k7 s2 D0 M

  67. / t, m: }0 W, R" P3 Q# j, e
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    % }3 N1 ^1 Q1 m8 Y
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为15 W& ~" A) ]" d0 R  [
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    9 g) a3 W7 Z+ a  G4 D
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;0 O6 v4 l3 v* B: B/ _$ U
  72.                 NVIC_Init(&NVIC_InitStructure);
    ! ~/ u! }5 ^9 h, o8 [' c% L" A
  73. #endif
    ! [* p* u( V( O& P; F
  74. }0 b6 B5 E+ q( k
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断* W4 }$ m! F6 c# K* q# ]. q, f
  76. //中断服务函数                           
    9 W6 {/ E: l# s" y$ c3 p3 g: X
  77. void CEC_CAN_IRQHandler(void)
    ) M3 g9 d& v8 e5 l: m
  78. {* Y* [, s- n+ F. ~* `8 Q5 B# I
  79.                 CanRxMsg RxMessage;
    1 R' M8 S) S) ^- T9 p1 g. D
  80.                 int i=0;; H/ R# G. E1 H- O7 v- S
  81.                 CAN_Receive(CAN, 0, &RxMessage);
    : G0 `8 G9 [2 y" y1 w) ]! u# ?
  82.                 //for(i=0;i<8;i++)
    4 [$ v6 F3 L! ]. M
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>' x* _8 f1 d0 \" c( l$ f
  84. }+ A0 A, d- V, ]' r3 U5 h
  85. #endif
    % ]& i" O: w' i
  86. ) ?# q' M$ v$ p% k! e4 G
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        
    6 ?" e* S2 a5 [0 Q
  88. //len:数据长度(最大为8)                                    
    / |* Z9 S. `- \' A
  89. //msg:数据指针,最大为8个字节.( i, Y# G) d" o0 x8 e
  90. //返回值:0,成功;* _! G" \) L7 F  ]
  91. //                 其他,失败;
    ! g/ ^  {1 r9 f
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)2 u2 [3 y* W& v& X6 O$ W: D) Q" n
  93. {        8 D8 S; R& x8 d% R
  94.   uint8_t mbox;2 o3 h1 W+ L' _! B) J3 Y( N7 r
  95.   uint16_t i=0;
    8 R6 K* h* D$ G" i/ m: J
  96.   CanTxMsg TxMessage;1 i6 U( I" M9 j( d  W8 t) r
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为02 C" u  Q" @8 y; ?0 i! p
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)3 n, J+ y( n# x6 L' s7 Z; U
  99.   TxMessage.IDE=0;                         // 使用扩展标识符  g2 t: _3 |( o5 t
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位
    2 V) L% n5 K2 d# E" D- C
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息; B8 g! D3 @1 t# @* l  i  S
  102.   for(i=0;i<len;i++)
    ; b1 R/ r4 W$ c/ s
  103.   TxMessage.Data=msg;                                 // 第一帧信息          . q$ C2 {1 x& m9 J0 d
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   $ |) O: v3 j4 R' ?( Q: O: ]
  105.   i=0;
    9 d7 r! s) t! o) I* v1 B
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束; o* l. Z# S# U0 W
  107.   if(i >= 0XFFF)return 1;+ l9 S/ p7 {* \  }/ |# r' c
  108.   return 0;                3 a: g9 Q- B; M6 y
  109. }( U2 P3 v; V% h2 w
  110. //can口接收数据查询9 D9 }( g# @/ w1 m$ S$ u' W3 R
  111. //buf:数据缓存区;         $ C& c: B* Z$ A" |
  112. //返回值:0,无数据被收到;
    5 T9 h4 B  d) v" D* ^3 W3 j/ ^
  113. //                 其他,接收的数据长度;! q- s2 G+ p; `; ]# I: \) A
  114. uint8_t Can_Receive_Msg(uint8_t *buf)
    : N3 x' D7 d+ a, m9 Q( h+ M- Z
  115. {                                      
    2 [# f0 [  F! ]" ^/ C: A$ w; U
  116.          uint32_t i;
    ( T+ r5 w' D- Z
  117.         CanRxMsg RxMessage;
    + q3 A8 T' C6 j: Z# u6 D
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出
    0 p7 v4 C6 I0 [2 I" h
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        # s, M/ i1 E% p& W+ L
  120.     for(i=0;i<8;i++)
    3 ]: |- v" h6 |" i8 ?
  121.     buf=RxMessage.Data;  $ q0 g" z# r9 ^( J( D  M* G
  122.         return RxMessage.DLC;        
    ! K! Q2 \) `$ k1 ]  C
  123. }
复制代码
, t6 R. s- }( r) K1 I* d6 c
注意:一定要根据自己的封装来设置
* m: o8 [: v8 i# USYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;0 ]/ c( q( @! J9 Z  Y. j, Z3 B
如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败' z/ V7 A9 l2 i% {- H

. `7 ?% V0 _+ W; E
; b$ L& Q; ?' Q3 P& {% Y
收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版