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

无死角、全功能对CANx统一初始化(STM32F1&F4通过)

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!
5 [" r/ d# e# E8 u' `7 f参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点3 M5 m" @6 f" b

6 [1 L9 H9 M/ H2 H1 _# ?5 f
) z% @2 p1 d" q0 E9 i  l0 y0 \
1 J1 J: Z3 n# s* r1 o* w. m//---------------------------- AHR_CAN.C --------------------------------------------------------------
- Y! C8 l8 j$ v* v#include "AHR_CAN.H"1 z. j; \: L; \
int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208
8 Z: O1 Z; {; ?# M( u//-----------------------------------------------------------------------------------------------------
3 L# [, {7 {. V//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
7 `9 K: Q# f3 P  \7 p0 g4 s//参数cfgCAN位图: 31   30    29   28,  27   26  25  24 ,23 22  21  20,19 18 17 16,F~C,B A 9 8,7~4,3~0
( d5 c4 N* Q' W$ ?+ v' W  ]//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]
" X  T0 p  ^  ^) G# R6 q//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址' u# n1 L5 U6 p* o$ q
//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)
3 b8 _- ]$ D* O( k//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)# [" C5 T+ i6 x( B, a
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal" \% t0 g! l$ `+ O5 T5 o0 U" ]/ o7 t
//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack
$ F) d# ]/ r  x% c//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])" U7 {2 j) {% ?% E
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;9 p# j% R/ |8 }8 `. J
//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式+ N) J* @8 T3 R& `
//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)
+ U. a5 K5 Y, }5 |9 j7 L- v. K// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限
1 U0 d: g, x7 A6 e+ Y# R// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)7 G" f3 |* K, l' k6 q
// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)
; F9 Z3 B; @" @3 @5 ?( L- N// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);$ q9 g5 M: W; S% H/ i% b
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK
1 c5 c$ r8 X9 S4 w& _//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
  f" H' U0 l) u1 N2 D/ m//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位3 n( W) `, N; V% {4 d( ^4 \
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理
/ w" ~4 _$ B5 y' ^$ u# w; c) F* W: M//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
, Z+ j! J% G* x' R- x' [/ m% c//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)
' U% M; C- }/ \) G3 d. b  R//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);
% j6 _  ^5 i& F/ e7 w1 v//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps0 T- L* Y- B8 {; U% q- y; q
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps7 D3 ?% Q) ^8 J- O, c: F; u8 d
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回8 @/ k; X5 O) l2 B
//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元
( I/ {, b+ d$ h2 J//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元$ {6 z; `: S$ S) N* x, ~: F. Z
//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
# m) f0 [1 D1 _6 X6 i  y# y//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );% q" I% I) `' {) m
//-----------------------------------------------------------------------------------------------------
, K5 N7 v* ~& }8 Pint initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-02086 `  H' R1 ~. M' u/ A$ T
    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq
, h* q+ |  E# \/ ~    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1
6 c4 w6 V0 C( O1 D9 b# d    switch(0xffff&idCANcfg){
+ N" ~3 N4 f; ?% {; @1 D% S6 O        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出1 E0 J" ^1 ~; A- R  T9 r& S: L
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);: w" Y5 G% V- n' u
              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);$ r1 F8 ~  [+ i9 l2 h- m- L8 Y
              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU; O& Q% l7 M) \6 ^' P) q% @, Y
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入
' k: `9 L$ [+ g4 ?, H/ M        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出8 _3 v6 W! d  E9 K8 X
              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **
. G# k2 ?! A8 W" a3 M              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;
$ s; U, A+ a8 H7 J; U2 P1 j+ Q              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU, Y- N. q% e; j/ f3 [
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU
& Z+ L/ K) P' n. H        default:     break; //保留: 为了更多的CAN+ b+ _; {: D$ `$ {( ]
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完
7 X9 [4 ?) w; Y! ^: M/ p" M0 v7 G( }    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
0 Y5 q# d  ?% R) s' v+ t4 O2 x8 _# K* j    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作5 e, p- V$ i: G, w9 J* I' q
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;. I$ y2 s. z) w. c; E; O' B
    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK) @% \( K9 h3 ~- [  i7 p
    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:
: B# g$ _3 X) y6 m0 U9 m        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值
) U8 {4 V1 Q* W/ \# f        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48! t. g5 k- k% ~4 o# G
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定
' l& I6 F( H+ o/ F$ e        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化
1 b+ |# o7 e2 p3 X: Y' Q) V        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
) U7 W0 O- Z& Y) W5 J9 |        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.
  x5 [3 H0 W+ d9 N1 ]        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!
$ d  e* n2 l9 }) K/ [    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初# i! Z% x) i" z) G3 Q+ R  s
    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;4 W: B7 G4 w2 P  j: v! x3 }
    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01); A3 L7 j$ u" r1 }7 r
    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对
: @- E5 i. P' K3 c    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1
2 N  P/ w  t/ Q        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;
0 W+ d9 ~0 ^4 a2 ~8 h# g        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//- ], A3 W& w& U' J6 n9 Y6 ~
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));& w- \. R: ?% a: ~/ t: Y# [( X  [
    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh
+ H1 k* s9 ^$ ~& }    if (((cfgCAN >> 26)&0x01)==1){
' Q  y2 ?7 G7 g: o- m# [! G# @        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;% Y5 x! y5 |$ Q& f
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4$ T' X. B$ T/ d( H" g  q% P2 b# l
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4( A5 V) ~' c9 A. F9 @+ n: Z
    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。! u3 {4 G0 m+ J8 L: i
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;; h3 b( b. ], S
    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;3 k. A5 `* x1 Y  U$ i, v& R
    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment
0 K  ?6 ^* e# b$ E3 M. E. G6 q6 H    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;! [- o, y2 M; D4 v
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;& \6 b6 o9 P# }/ l
    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation" }8 x8 d$ t) j+ P
    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控
! d& B% W3 I; J    return retStat;
. T' j0 Y6 f; g4 P  g}   // <over 2019-0208 aiherong suncun>
' `" ?% u: S" ?+ u+ v9 R
' W: f& v4 V! j6 R% @5 q- s. `int CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)2 `. w: w7 u+ j* ~/ e
    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.
" Z. D% `3 d$ m8 V    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state
  U$ z1 d# U2 I2 I/ `6 y' |! n    TxMsg.StdId=0x12;                         // 标准标识符为0# ]) j9 f6 z) V, I( Z# s
    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)
( Z. B( @) _3 Z    TxMsg.IDE=0;                              // 使用扩展标识符
& h% q% s$ X# \/ B+ M    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位
0 x$ ~8 O& ^9 a1 ~: D; |: ]    TxMsg.DLC=len;                            // 发送两帧信息
. ^8 W1 y6 H- D' u( i5 m# y    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息3 H8 ?& W  }! k# B; g
    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;
: Q1 _2 N/ ]) {+ r    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;
, _  J* y$ U. }3 k    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;. `/ n6 `5 U7 I* Q$ x$ `$ k
    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
; [; F- Q% o2 I) ^) r& j: M$ L* z9 {    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04" R- s! G; M) F; n& H
          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?
; ]4 S2 A% [" i/ d          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);# w0 ~0 z+ f9 `" W# ^  v
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);* \2 u5 W$ [, _1 x/ b! f4 ]2 x" F
             TxMsg.DLC &= (uint8_t)0x0000000F;
2 m- i& u  x7 ?          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;% q3 I  t. y5 S5 s0 Y
          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;0 l2 H$ U# |5 x3 j2 M3 p
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR
% |% P& \( R+ x: {2 Y                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);
- k. X* [5 w7 b; B          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR
) f( H: f! c% `0 ?7 E. ]                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);) h1 e1 e' i2 I& H* d3 n& }& e7 W
          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求4 K% a6 A6 w" E8 f' Q* L
    }
2 }, p* q  Y6 H% S7 ^    for (i=0;i<0xffff;i++){  //等待发送结束% |+ A' {$ g) d. V
        switch (mailBOX){; a! |3 |$ p8 l/ o6 {+ _2 [2 [
          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)
; i, S6 T3 _. ~' N5 ]: n+ M' G          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)# L+ u) j9 s* A2 A1 p
          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)
, E5 b9 b, C2 U! J$ w+ W          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00$ A. c- L0 s7 k) b' ^+ ^6 ^# O
        }
7 W+ N4 R: k2 g, @1 [        switch (sendST) {% D# [" H4 e0 _" P* o
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
5 S) @6 |, g0 D6 }% f' k  _          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):
6 o- b! B4 s6 Z. m+ A" s          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):7 L$ w2 k6 H, N0 r* L
          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed4 c5 S8 s# L; r4 f8 A( C2 U
          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)
8 C* k  ]! x6 O5 t( x) T          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
$ w5 b8 @* N' q7 \) ^6 v* o9 O          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)/ r/ v0 U' Y* j5 n+ r
          default:        sendST = 0; break;
9 b- O4 `* G& Y4 T: i        }: l3 w  @* p& ~, R0 i
        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功
3 ^& b7 Y9 ?" U# M6 }3 e( l    }
$ \, Y& d+ Q; H+ e" h' \    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
$ A$ l+ Y& [$ z% E' O) S0 C                  return 0xABCFACE; // 返回 0xAbcFace - 成功! U9 j$ g8 {& C
}
/ e* c8 ^) @6 ?2 m& y! D* m% l2 e) P
int CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;  L$ r2 E, W" ]1 [. Y6 M& j9 M# N
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度
2 i7 I6 m5 ^- Q' F8 M0 l& ]) x  X    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||" `% C, j0 w" X2 |) l! o: R4 P
       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:
( L' [; Z5 N  Y        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R
3 g5 t  W" n6 a. t; y- s        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);
6 B0 |% A$ O7 g1 E. z        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);/ N5 G7 i4 G9 S) G
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;4 B, K1 \% c& H! r$ w, p
        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;
" q1 m: u! j2 g/ r& l  R        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8
3 a5 t% F; F; [, }6 ^+ n' Z        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R- L) ~& U4 U0 R( W
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
* o1 i: K9 [4 u6 m) p# W        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);6 ?' ^4 A- J& u  A; F* q
        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);
5 i$ o+ H, c( |; ^3 t        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R
9 m# W) L! P' T; w6 P) j        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);
0 j6 _0 ]8 b3 A  L        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);% }6 a6 h1 X+ v; l+ A
        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);- T2 Q+ }* X4 P' J
        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;' `" [+ _" H1 j
        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
: t9 E6 ]& n& F3 ^. F- |+ M        for(i=0;i<RxMsg.DLC;i++)
/ x9 s& r3 f7 i        buf[i]=RxMsg.Data[i];; R- p  Q$ W1 ]4 O3 \, C
        return RxMsg.DLC;
4 `, u$ p" l$ G2 @+ N9 P2 L9 n& L4 D    } else return 0; //无数可收故退出# `; ]2 c1 Y9 f* W) a/ Y: n5 w" K
}# x" N4 D6 x& e4 R) W5 D$ T
//-------------------------------------------------- End of AHR_CAN.C ---------------------------------
; |6 G8 f8 B  H& G3 X* `' H6 k8 H3 d: @5 j: W
//--------------------- AHR_CAN.H ---------------------------------------------------------------------
' T" \. |5 r& x4 \: T5 H0 S#ifndef AHR_CANETHUSB_H
* e( g1 W$ N/ [6 H9 M2 P#define AHR_CANETHUSB_H
- ]! {9 v" ]. B7 q' V#include "aiherong.h"
" p8 Y6 C2 z2 |1 j9 c' T#define   CAN_FIFO0            ((uint8_t)0x00)% ~8 |, ?. w9 A0 _* g
#define   CAN_FIFO1            ((uint8_t)0x01)8 U9 W5 A( p! _9 g% {8 Z
#define   CANid_Std            ((uint32_t)0x00000000)  
3 S! r% o3 b7 ~5 n* H#define   CANid_Ext            ((uint32_t)0x00000004)  ( l6 [4 R/ m. @" u
typedef struct{    //发送邮箱有3个5 n) L" A2 x/ }/ r
  uint32_t StdId;  //标准ID
1 Q3 `4 E  J5 r9 p  m) ~  uint32_t ExtId;  //扩展ID
7 w$ E' {1 w" T/ L  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
2 l! V% ~+ @3 H4 D7 [: C  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
" ?) q$ T5 B4 k0 T9 q  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
7 d4 W; N1 K; s/ y/ g- |4 p) M  uint8_t Data[8]; //  8 位数据
" z: K. A7 E' J) M} CAN_TxMsg;: B, A, a- Q7 v1 ?: C& L6 z! B
typedef struct{    //接收邮箱有2个8 `$ [! i$ P9 a6 h
  uint32_t StdId;  //标准ID
# D6 Z0 i2 o1 @( t7 z  uint32_t ExtId;  //扩展ID
1 g; p1 v4 [" g4 ~& O2 e5 S  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符8 r) ?9 S# T! k$ g2 A
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧2 Z" o# ]5 @8 R: a8 h% A0 l
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据6 M+ `6 ~$ L' B8 Z7 H) C, c2 w% s1 L
  uint8_t Data[8]; //  8 位数据
7 i$ e" I9 ~7 J2 V/ b  uint8_t FMI;     //过滤器匹配序号(Filter match index)/ H1 V. ?1 r3 R+ x1 u
} CAN_RxMsg;
0 T( H+ ]1 ]4 H7 e& g8 ^  ~5 ?        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB138 f# T7 g1 i! S0 A  _7 [7 i3 S
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
' U+ H/ A- j) gint CAN_SendMessage(u8* msg,  u8 len);         //发送数据
! j7 @8 f1 G- N1 e$ O+ p6 Rint CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据
9 B2 Q1 i. l) @( V& |#endif1 w* P! r6 ^( k# T( M( R/ v1 o
//-------------------------------------------------- End of AHR_CAN.H ---------------------------------
收藏 4 评论4 发布时间:2019-3-25 20:25

举报

4个回答
aiherong 回答时间:2019-3-25 20:29:19
直接使用!不依赖库函数
STMCU-管管 回答时间:2019-3-26 10:15:15
谢谢楼主分享
西点钟灵毓秀 回答时间:2019-3-26 13:41:08
楼主强大有啊
aiherong 回答时间:2019-3-27 22:50:09
承蒙坛主光顾!不知论坛里有没有我能干的活?1 I+ q9 U/ h4 @( i; \; P) V" t# K) ~
不挣钱的日子跟没头苍蝇一般,己快看不懂世界了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版