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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!
9 P, N. b) D% W; `参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点, v1 ^( G! i9 o( U! O' d9 t: M
, b; z9 G% X5 p4 l2 ^9 B8 E

9 q' V) K3 U4 |; u; S
3 }' b; K( l* F//---------------------------- AHR_CAN.C --------------------------------------------------------------
- a) H: `$ W; b#include "AHR_CAN.H"
1 D* u7 Z" T; A6 xint CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208 / s9 o" s1 p5 i+ j- `: E
//-----------------------------------------------------------------------------------------------------
6 J5 f+ Y0 F7 K4 b- p: A* K6 Y7 U//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
5 T) l+ P# v- M8 ?//参数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; C. J5 c( }6 a# _" N9 h( T
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]
: U/ n9 V/ a' R0 [: u) ]- y( b//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址7 {  Z% W2 P! A6 e0 {) z- ]
//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)
# h9 N: {: i9 ?, H$ S. F//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)2 s$ b2 Z. E6 x$ P5 t) K, l
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal4 E8 ^4 e8 `( `5 Q" P+ j- `$ U
//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack3 N3 j) k  p; R5 V
//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])) F# c1 M4 ~4 P; h7 T
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;
9 m& J: u5 n5 {5 i$ o, ]5 ]1 Q//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式" h* C0 j! X3 U/ B
//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)
+ p6 `+ L  {* t' \  z// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限7 z  i+ y) x9 K* W7 n
// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)
( x7 |( V# l) e// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)
& s. Z2 |8 y: |! [4 T+ s4 Y// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);) [- c* o4 P- `7 I
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK/ F+ ]; X4 [8 d
//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13; @6 D5 a% }7 j- ~, f+ b: R
//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位) l& O+ I) U; @5 _1 F
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理' S6 y. m; D" z) a
//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!! b. A! C+ |# ?
//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)0 Y* i) ]7 c, L9 c: Y$ n: ~
//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);  M# c  L4 \3 o8 S5 A  J! R) L
//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps
# D$ E# y+ M6 L6 [; R' z//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps. v( `1 b6 s3 ^3 d
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回
! U' d, E1 ~9 y//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元" H# q0 j% Z( d8 ?+ H  w
//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元5 T. W0 J) z, j7 l3 V# g
//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
1 l; I. j0 t, o+ j0 B//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );! G# x4 y2 e4 Q
//-----------------------------------------------------------------------------------------------------9 s- a! |8 E- R) P" c  R
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208, l$ \; z; m+ h' B
    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq
4 |; H/ H4 C& D& X! U    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1: Y( X8 R- d8 S1 W( }
    switch(0xffff&idCANcfg){
1 I# e) {9 S' L        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出  b7 Y" _9 L) ]) ?9 s: a, J
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);0 v& @7 b5 c" M! M0 F7 J$ ^
              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);
& I' |1 |1 e$ {# I2 P& \8 V; b              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU
& `  B, h/ G# m' [1 u              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入+ \5 Q5 g1 @, N5 H6 V
        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出- P. p# T9 G! t& N: R" ~% i5 I
              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **8 `! e5 q; E& \- |' t3 C, q( N
              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;
4 K* j% M( o, {( |              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU3 C$ l+ ]  @; i
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU
7 Q' C" N9 z7 x' y0 ~        default:     break; //保留: 为了更多的CAN" E! N  l7 X$ ]: W* X0 ~4 k7 e8 k- _
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完
! G7 @: W' I. B/ X# N- Q: P! B    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
9 s4 z) n- O# W. Y    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作) P6 q* I6 U0 @$ ?# ~5 z6 k- G/ W
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;) y% R- A# {* Y3 d
    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK
/ R+ n  C4 ~. e) [% L    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:
2 ], t0 R$ r" t' j$ |; _+ {        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值) X& I; K* n$ V, u& g' w
        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48& e, ]: x3 o. y4 O& Z- N: G
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定" t8 x( S1 ~% f" l6 D
        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化1 \6 d, W, o) J
        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
7 e2 g& k/ S+ k8 Y/ x        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.  L; a0 c0 i; ^, I* o
        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!# M& q, y, Q! j0 D0 x
    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初3 X: N8 T! i( }- b2 _
    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;
9 _/ G9 t$ }9 ^, p: C6 Y( D    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)
* t. n* P) G6 t' q  w; l3 w( L    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对
: k; E) @9 S+ U7 f. H; v    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1
' t% _- t- F8 l( E# `! r8 o        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;
: U; h# ]. A0 A2 C# k        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//# j" H* U: t2 T3 D6 B
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));9 g* V0 v. {, [6 C( ^1 G
    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh# Y. F% g5 H) ?5 o8 C# T
    if (((cfgCAN >> 26)&0x01)==1){& I2 B# P* ]- {- ^
        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;
1 O* e  {; `1 |6 }        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4
1 e- ?& ?4 x" Z        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4
0 t* |9 Y8 G+ G1 V* B( m: _    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。5 Y% J. x; H% ^0 m# l1 K/ ~1 y
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;
: F6 |$ M# V! h$ S2 X! g    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;4 {+ @4 K6 d' s- r
    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment
* G, H" N' c& K    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;
+ z! P1 a! u, @( q  {3 e    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
9 I8 {) k0 {* S% U    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation) d3 K4 Y& z8 V3 D1 S
    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控
8 z0 ^, `, y- s    return retStat;, _  }* O' ?+ {
}   // <over 2019-0208 aiherong suncun>
1 Z3 ?$ Y) e3 }  \3 o
* F, W- y) a! `. u$ o. cint CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
+ w0 w" S$ I6 d+ c4 S4 D  z  `% O    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.9 m- w; F' J- T
    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state
( i/ j  J% [. Y2 n" L9 ^3 n7 Y    TxMsg.StdId=0x12;                         // 标准标识符为0
9 T) r/ b8 X% ]% z) h    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)- R; v6 H: c( p0 D0 A
    TxMsg.IDE=0;                              // 使用扩展标识符- r. h* Y6 Z( Z
    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位4 H: v$ I! u9 r, p3 `8 C
    TxMsg.DLC=len;                            // 发送两帧信息
; P* k  Z* c* O2 A% }: M    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息
5 C$ Z2 p8 h$ }    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;
$ x" Z- i3 T' A    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;: \' T( @( ~0 O* a3 A" h' C' R% Y
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;
% W$ \- \% A2 `$ L4 d+ G    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
% v7 d- ?: t6 C    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04
6 k# K% ^7 `5 F/ D0 }# {          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?( ~4 [; x  F* N1 i# h* E
          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);; a" Y3 \4 W) J* M7 |. R
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);+ E( `# j- F8 X+ ^
             TxMsg.DLC &= (uint8_t)0x0000000F;
) T5 h! r+ Q' ]/ Y) S* y" r          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;
- C: r8 A; X1 p  l4 J, E          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;" H# _0 K* p- I3 F  r
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR
; f; f4 R  ]' Z& m                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);
1 ?( c8 q# Z. T0 `0 b; k" S7 \          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR
" w- p2 C7 B+ k4 g2 F# Z  q                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);
9 l0 U6 ~( z; U$ V6 q          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求2 p+ h. F- ~' f3 D1 e. W" C; |
    }  G9 y4 U! K% n6 n! z
    for (i=0;i<0xffff;i++){  //等待发送结束
- B8 z5 ]0 ^% a2 ^* x% A! V        switch (mailBOX){
( a4 n8 K' o% C# s$ R          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)
$ z: |" X* _/ f2 C7 v          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)1 a4 R3 s3 U8 _
          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)1 V: A' B- u) h. B
          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00
+ V6 G4 q5 I. }3 X9 Z        }: G3 O5 Y" p/ @' B
        switch (sendST) {/ |$ X1 @" t) y( p# W
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
, p6 U; W! M" z8 s, A9 N          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):" L# j7 x" f3 Z- T( m
          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):
0 O! X2 d) N# l1 S          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed' y+ @' X+ ]- w  T
          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)
! X/ A# s& J) Z1 P( p9 L+ S# t          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
1 Q: ^' O. {3 p/ |1 G0 h          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)# b1 K3 l4 E: E4 n- i  F, a; A
          default:        sendST = 0; break;
( a" P& m. R* F( p        }
! a8 x7 l% N/ G# a2 x( }& G        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功
9 Z6 g7 U7 R# l5 [    }
3 S% A9 z; m0 p) [) e6 Q    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败3 L- \3 {1 D) o6 g+ P- U4 M+ h& J
                  return 0xABCFACE; // 返回 0xAbcFace - 成功+ s  K# o$ ~% w# G, e2 w
}
2 N1 F- _' q4 W2 C3 J9 C0 K8 ]5 B5 o& b3 Y. @( ?0 u$ r# X
int CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;, K, O, g, |& K1 w, l' T
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度; C" x6 j, S8 X2 |3 R5 ^& ?
    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||
* n& N; y- k' ?, t       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:0 I4 I1 s# P* t, x
        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R% S$ Q# J% K6 w- B; J4 t' ]
        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);
% T- ]6 f  i/ u" J( f" ^! J        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);- y" I& ^) n! o' ^/ C
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;
' j5 z/ m5 h$ ?) k3 s1 n        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;( Y2 K1 W$ }; r  f
        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8
% j  j2 K9 _& a" ]+ G        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R9 |& m3 S! `7 F0 @
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
. n! p8 x' [9 _+ X+ f        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);' d0 d  O" G; W
        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);
' V; Y0 w/ L7 M0 v0 m3 G        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R
, ~% c4 k+ P5 Q# K5 O1 z        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);* \. H, F* B" o+ M- Q3 N
        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);+ x1 w, ^8 N' n) C& I
        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);
* |* T% P# e8 }4 w4 v1 [        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;+ Q  z1 c% L% e5 {. }2 C
        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;4 d. t. Y" l7 Z* e' }/ y
        for(i=0;i<RxMsg.DLC;i++)
5 {( m' u' C% ?: t5 b, v        buf[i]=RxMsg.Data[i];
- P, k  V& U' ~* j/ M4 y: j3 B        return RxMsg.DLC;
) _+ c, |7 Y" B; B7 {0 s; o    } else return 0; //无数可收故退出* ]! R6 I) L/ F$ d0 {9 ]. v) n
}
. O, L# g; N% I9 v# I//-------------------------------------------------- End of AHR_CAN.C ---------------------------------5 G2 {* I+ a5 N3 a9 L4 ^5 j$ x& x

; W4 ?/ J0 @2 X# d* _- q( C //--------------------- AHR_CAN.H ---------------------------------------------------------------------$ s9 ~5 f% X9 m/ s# w$ D* e0 w
#ifndef AHR_CANETHUSB_H
* c9 `% {( _$ p( J#define AHR_CANETHUSB_H
. }) m! M9 E2 [2 S6 _#include "aiherong.h"7 A' u! [2 J5 P( o0 b
#define   CAN_FIFO0            ((uint8_t)0x00)
2 O  U0 V$ Q4 C( m#define   CAN_FIFO1            ((uint8_t)0x01)
; G, n4 c, E1 v. C; b#define   CANid_Std            ((uint32_t)0x00000000)  
, `2 t! P3 Y6 ?#define   CANid_Ext            ((uint32_t)0x00000004)  
# s) Q( w3 H4 h. W4 vtypedef struct{    //发送邮箱有3个
6 [# N0 Q5 |- _, H  C5 T- ~- X! B  uint32_t StdId;  //标准ID
) X% f- f5 |3 z  uint32_t ExtId;  //扩展ID9 \7 m+ f! q- ^4 w
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符' \; r$ o4 C& X4 M
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧, A# P! g: q/ A' Y
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据; S- }: d+ Y6 o$ B& B# r+ F3 z: j
  uint8_t Data[8]; //  8 位数据
$ G7 w; `9 J1 u+ m% `$ ^} CAN_TxMsg;* k* P$ A9 e& S) X; K
typedef struct{    //接收邮箱有2个3 j/ g7 V" t) t; R/ o) U! U
  uint32_t StdId;  //标准ID7 l, U/ Y9 w6 T$ O! U4 T
  uint32_t ExtId;  //扩展ID
; [5 ]1 o& ~% I3 c( j. u1 W  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
5 a2 S; V- e& I& n% O0 f  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
- x- q* `9 N3 t- [  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据2 `2 q4 J, a$ N3 T3 k8 ~
  uint8_t Data[8]; //  8 位数据
, L* V* ?) y* O3 c0 j6 R  uint8_t FMI;     //过滤器匹配序号(Filter match index). r$ P9 D# y; k) \) W- m% Q
} CAN_RxMsg;
! R% Q+ k' `9 E: v; s  o" m        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13/ u" z/ q) x8 R: V" Q
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)1 Y4 `* U3 j& c; j) i: L
int CAN_SendMessage(u8* msg,  u8 len);         //发送数据9 p4 z8 B& a: J3 |# V9 _& q
int CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据& }1 d& M. i* Y' v8 W9 e& k2 e/ t
#endif* O' S7 N) y# C! m; E  T
//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?
. k1 l3 C% s# V! a  p1 j不挣钱的日子跟没头苍蝇一般,己快看不懂世界了

所属标签

相似技术帖

官网相关资源

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