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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 21:03
代码如下:
% e' l) E; r, ]. V6 |8 J- e! k* A
  1. #include "mycan.h"
    3 ~+ l+ g6 ^8 m" D9 p# U
  2. ( y7 ]) _3 P- r" S. l- T, P
  3. //CAN初始化
    0 ^( R) w! z4 _. g+ N2 E
  4. //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq/ m! k+ V  Y: b2 F; _
  5. //tbs2:时间段2的时间单元.范围:1~8;. Z9 B6 Q* i, h) c! i
  6. //tbs1:时间段1的时间单元.范围:1~16;          CAN_BS1_1tq ~CAN_BS1_16tq
    ( x" y! c* ]* A; d5 r
  7. //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
    : p2 K2 E2 u* i. {- S2 u
  8. //注意以上参数任何一个都不能设为0,否则会乱.
    2 Q8 N! C- Z6 h
  9. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);% F$ ~" s2 Q5 p$ {, R
  10. //mode:0,普通模式;1,回环模式;
    / m6 z2 _* s. x' e) m# P
  11. //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
    # ?+ U$ @% }& H  v( o4 M" _
  12. //则波特率为:48M/((1+8+7)*5)=450Kbps
    ) |4 e- p3 J* ]- E( b) H

  13. " s2 D9 e1 {& s+ M0 {& g* e1 `
  14. void CAN_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
    . h& g8 f, g8 ?" K0 u, F
  15. {
    8 R# K/ S  \8 O2 \$ i

  16. 9 ^3 ^8 o/ k7 o: a: o& v4 ?, {
  17.         GPIO_InitTypeDef GPIO_InitStructure;
    + y% U* D; h4 K  X0 _
  18.         CAN_InitTypeDef        CAN_InitStructure;+ Q3 _4 U- G4 S8 v" S$ j
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;7 W9 a( a: }. Q4 B5 r  H, H! |" l
  20. #if CAN_RX0_INT_ENABLE ; x8 y6 b: e2 P3 h1 r  o9 B, S
  21.            NVIC_InitTypeDef  NVIC_InitStructure;
    / y/ t3 K/ i* J( X# s
  22. #endif+ a9 ]0 ]4 u) D6 A
  23.                 6 a3 g9 I# A7 X, W
  24.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    # R8 n% t8 Q) F5 I3 ?- E5 }
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能PORTA时钟                                                                                                                    * E+ I5 h) R/ a- R
  26.           SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;                  //RMAP        ( a2 G+ j, D6 W3 X; `1 R
  27.           GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);! q) u' G& o9 s6 z
  28.                 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
    ' g, f6 p5 N; x: o! t. a9 e
  29.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);//使能CAN时钟        ; N: w. U+ t' V, m3 Z4 E! ~: E
  30. 4 j! o" A- W* u$ f
  31.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11|GPIO_Pin_12;
    2 Z- @: s  l0 d
  32.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;- A, V) B8 w7 o& {8 }; o* n
  33.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    # v7 c2 P6 l7 M6 O) R
  34.     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;3 {5 q$ F* i) c  c9 b
  35.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    " r7 j. q9 ~) ^
  36.                 / N) ]' J3 m8 ]# x
  37.           CAN_DeInit(CAN);
    1 ~' v: |3 c- G1 s" x3 v
  38.          //CAN单元设置- b2 X4 ^, L7 ^* ~8 e& H: G
  39.                 CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //3 Z  y2 f+ @/ z7 t6 Q2 a
  40.                 CAN_InitStructure.CAN_ABOM=ENABLE;                                                 //软件自动离线管理         //
    5 R* V5 D8 V; A4 @
  41.                 CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
    4 j- o0 c1 r( Q1 U; F
  42.                 CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //- ^! E" J0 A3 B$ y% G% E
  43.                 CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 // 5 B6 A( E; g% n& L0 L1 E
  44.                 CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
    ( G% w# J! t, `6 C* Q3 ~9 D
  45.                 CAN_InitStructure.CAN_Mode= mode;                 //模式设置: mode:0,普通模式;1,回环模式; //
    ( e" U. D. y5 C# }5 H
  46.           //设置波特率
    9 E, W6 A$ ]9 z% W
  47.           CAN_InitStructure.CAN_SJW=tsjw;                                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq         CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq( n2 v/ \$ R. I& y: J$ o- i4 V% {
  48.           CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq# S5 y  {( ~; W( c) J
  49.           CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~        CAN_BS2_8tq9 M/ v) ]" T* r+ s9 o/ E
  50.           CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1        //& L7 }% o% H* y/ c+ R
  51.           CAN_Init(CAN, &CAN_InitStructure);            // 初始化CAN1 7 _! {. f% i, A" r8 [' S7 H

  52. ! Y* }3 k+ u5 h( \! E
  53.                 CAN_FilterInitStructure.CAN_FilterNumber=0;          //过滤器0) F) h* R4 v& k% P: \* L1 I
  54.                 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
    % G) s  y* i( h9 v* p) A
  55.                 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位 7 l2 j1 ~) ?$ @
  56.                 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID2 z3 p6 e: U$ g4 T! U7 l
  57.                 CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    3 l$ p& u2 ~( R' M# \4 e1 q
  58.                 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK- y8 h  W$ V( U! T
  59.                 CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;7 w8 Y# Y" O) ^6 J+ j( O: `
  60.                 CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    ( r  e4 A% ?3 v9 T
  61.                 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
    ' D2 u& H/ W4 @
  62. . P6 L8 H% X! T/ o: P( p
  63.                 CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化* B/ ?5 k/ i3 i- G# u9 O7 _3 `
  64. #if CAN_RX0_INT_ENABLE5 d( X2 z" k0 n+ P; J
  65.         
    8 H, F3 d0 Q- N
  66.                 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                    ( W& w9 s& H& B6 f6 L( g& W& I: B
  67. " A1 b6 A; V6 _3 W, }1 D$ @9 s
  68.                 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    + {7 K# I2 t3 Z4 u7 i; F# p
  69.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1; }& Y- q' ]* F9 d
  70.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    * d+ G- ~! ?7 w% Z6 B* K
  71.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    8 I) ?. d' H+ u! Z# F! B
  72.                 NVIC_Init(&NVIC_InitStructure);; E1 q/ S: T. F; B  o7 h+ M  V
  73. #endif
    8 z2 O5 U4 Y4 E2 B) k
  74. }8 w- d% g$ l- ^
  75. #if CAN_RX0_INT_ENABLE        //使能RX0中断0 _' ]$ q* v5 i8 N8 H
  76. //中断服务函数                            $ z' {) n. {) h0 w- T' Q3 q
  77. void CEC_CAN_IRQHandler(void): a2 Y- k0 I" L3 S
  78. {
    8 M' p4 [, ?, x, t( [
  79.                 CanRxMsg RxMessage;
    ) H- ?' g/ u0 ?$ {
  80.                 int i=0;
    8 q% B' s) w+ w# z  f" K% b
  81.                 CAN_Receive(CAN, 0, &RxMessage);( N3 C* p5 }1 C5 q' O+ D8 S
  82.                 //for(i=0;i<8;i++)% S/ y, _' B# J  u& d
  83.                 //printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data<i>);</i>4 M2 R1 f+ Z4 ~/ q- ?
  84. }
    0 k% G: h* H6 F; f  n( A
  85. #endif! l7 }: B7 K% Y% d- j+ ?  b
  86. + x' I. k9 y; }0 H* ~) j
  87. //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)        
    6 i) [, A+ |% w
  88. //len:数据长度(最大为8)                                     9 w4 r4 |9 i& Q
  89. //msg:数据指针,最大为8个字节.1 |% a0 c6 _' x9 W( W' x
  90. //返回值:0,成功;
    * R3 i+ ?7 T" G0 q+ |9 N0 m
  91. //                 其他,失败;
    # _8 ~* g+ m3 x8 S
  92. uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)- s6 q! e# J/ \$ A; f1 {
  93. {        
    ; Y( o6 v* c) x/ b5 u
  94.   uint8_t mbox;
    ( P* X0 r5 K4 ~% c1 ^, W( x6 k
  95.   uint16_t i=0;0 i- j! V+ |% R& g& w
  96.   CanTxMsg TxMessage;$ _5 i8 c# B* p! l
  97.   TxMessage.StdId=0x12;                                         // 标准标识符为0
    + g' ^  c$ y4 }& l6 K
  98.   TxMessage.ExtId=0x12;                                 // 设置扩展标示符(29位)
    . x* t0 c% V. E8 p6 t5 h
  99.   TxMessage.IDE=0;                         // 使用扩展标识符) `6 H0 y" h* w: P5 T) D: ~
  100.   TxMessage.RTR=0;                 // 消息类型为数据帧,一帧8位1 Z8 ?$ c4 R! s" r& @3 ]: @7 W
  101.   TxMessage.DLC=len;                                                         // 发送两帧信息4 N) E/ p4 u+ `, b9 a5 O
  102.   for(i=0;i<len;i++)- L$ B3 |5 i4 q/ F& S3 `1 h. o
  103.   TxMessage.Data=msg;                                 // 第一帧信息         
    - V/ k% U, J0 A" s
  104.   mbox= CAN_Transmit(CAN, &TxMessage);   
    ' v1 e0 w3 r: O+ Y
  105.   i=0;3 L$ i6 N  }* o
  106.   while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i < 0XFFF))i++;        //等待发送结束
    6 k" a9 ?/ V7 V/ G4 T7 U: I
  107.   if(i >= 0XFFF)return 1;
    5 N* u; V2 w, K/ m2 K
  108.   return 0;               
    " ^5 A* c, ~3 @  ~5 Z
  109. }
    " }+ c3 y/ ~+ u8 O. I) C4 r& z  Z% X
  110. //can口接收数据查询
    ( _! R% t$ p4 Z' o
  111. //buf:数据缓存区;         & P, k. g: r8 x1 A" }1 V
  112. //返回值:0,无数据被收到;
    $ X# R9 Y7 F! O9 |9 Y
  113. //                 其他,接收的数据长度;
    1 Y+ i: x- M" J/ Z6 }
  114. uint8_t Can_Receive_Msg(uint8_t *buf)2 p6 p+ F5 `, G" D6 y' ^
  115. {                                      
    ( k7 Y: R1 U5 j) t9 R1 e* w
  116.          uint32_t i;
    ! e. o6 Q$ d- K& W$ v1 A
  117.         CanRxMsg RxMessage;
    * u! l6 i3 q& i- j
  118.     if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;                //没有接收到数据,直接退出
    3 E, a+ i0 g3 A( X3 Y
  119.     CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据        
    , d! D1 o: d! c) p
  120.     for(i=0;i<8;i++)% F: @& r" ]& J! \
  121.     buf=RxMessage.Data;  
    - V7 _) Y. D$ n2 T
  122.         return RxMessage.DLC;        
    , b* j1 j! ]7 |/ Y
  123. }
复制代码

$ V& j1 w* n$ [注意:一定要根据自己的封装来设置) F# w* C7 L( A0 z7 v0 `) i+ y
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;  R; {; x- c3 |& {( A
如果不设置 CAN_Init(CAN, &CAN_InitStructure);会初始化失败" @# j4 u: A4 z6 {3 ~% i7 c

1 Y% l, ^$ ]2 J1 G! @+ `' q) \$ l  {2 Q! M5 r9 D
收藏 评论0 发布时间:2021-11-22 21:03

举报

0个回答

所属标签

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