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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!
) p1 [: f/ E( B参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点: A% Y* ?( z3 K/ b" K0 Q6 A" @, ?
9 x5 z3 T  {1 j5 F0 r% T  ~+ ?& y

9 ~, t+ Z4 E0 o- m% V! t+ E
% ^+ y( M6 ?! x- W//---------------------------- AHR_CAN.C --------------------------------------------------------------
* D) i  C4 p# V# m#include "AHR_CAN.H"2 f9 r$ J- i: X! b+ U
int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208
6 ]; _6 p$ G- k0 k//-----------------------------------------------------------------------------------------------------
) q8 V3 u4 D  d& b//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;/ ?$ q6 x* a  ]; }* _9 r6 [" h9 P
//参数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& {8 m: }2 Y! l" f+ w3 ~2 X
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]8 \" v& H# O  h/ W. a% ~& P7 i2 _8 W$ O  [/ N
//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址7 ]5 f; t. y/ M8 v& g2 z
//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)! R# g6 y3 n4 L' I8 f+ \" ~4 ?
//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)( i" C& u. H7 ]' _! _
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal
7 s4 }5 E1 T5 j# [" M: J& _//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack) L0 J( w5 G" M0 S+ n. E4 }
//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])- L! w  Q7 R: q- _" k
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;
8 D! r. Y5 n6 }/ w/ y% Z: a  J//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式" H2 {6 a/ B( W) L
//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)( {- n; H5 i6 \0 q+ K
// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限0 Q- R7 R7 M# X2 E/ e. a  w
// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)
% \$ g4 Y5 y* {3 f// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)
4 U" K. j. v: x$ \$ q6 \$ h* V$ O// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);1 q8 o  _6 G, l3 B- @3 |
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK7 c1 g: Y1 X5 A- i# W5 C' v
//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
$ x3 N8 L9 V* [# G//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位3 Y2 e0 s7 j; q% f) P! v( ]
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理
3 F; R, A3 s" _) l1 j4 N5 i//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!& v) ?& C% k5 n9 C: \3 U/ j2 V
//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)$ L, G% e/ X- P8 {
//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);
+ O7 g; Y9 k; s" D- U//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps; m3 u9 Q$ A( Y6 Q1 G( b2 Z
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps9 i* x+ k6 `) W- z( ^
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回2 V' E4 w) m% p! Q3 Z
//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元
2 N- v1 u. e+ `//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元) ~$ c$ f! M8 J8 m
//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK8 S) m9 j% a) w) A% m
//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );
! W/ `0 a/ h% j: i1 j+ V" q$ G- j//-----------------------------------------------------------------------------------------------------: Y; O' }4 k5 X7 D0 ^
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-02084 X( D4 i8 W2 Q8 D2 z( U
    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq& k% @; l7 F0 ^
    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1
" P2 M. V/ a0 S    switch(0xffff&idCANcfg){# Y" K& P: k* q4 H5 N
        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出& W) A+ S9 |5 V4 T$ y; j* t% r; x+ l
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);$ h3 o* n& l/ s( A
              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);4 W  {( A$ G' G9 @
              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU) J+ J7 J* x. O. W6 H* e2 q/ X
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入, t2 N  |1 J( m  }4 R# H
        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出
2 U6 G- [* b: B$ u              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **( e, q8 M$ I5 c# W
              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;
4 C# J" p# d/ @- t+ x              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU" P, S4 r+ o% C2 v3 u% T: b% N8 g1 E  Q) c
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU" w9 K8 J* u! L' k
        default:     break; //保留: 为了更多的CAN2 u, o- u* O' C; }$ j
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完9 @- a7 F  C$ F* O, n
    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠! b- ^+ q9 ?! i) W& e  \
    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作
. `1 ^9 _4 H/ E4 }    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;
' k) Y" }, J" y0 g& i7 z    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK, e6 A3 S8 g' j" y5 m  L
    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:
0 i0 w: g4 Q$ N        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值; \" d1 e& j% D$ G8 S) K& z1 u' t
        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48- F; Z# [5 B& O3 l+ p& [
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定
0 t3 j& x/ D9 l5 g5 }  X! X, P        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化$ |7 J$ n2 U5 k  ]
        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
4 A5 M8 ^" t; J        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.8 D: }$ q$ ?  N4 C
        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!
' u8 r2 n# D2 ~3 N; B    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初
0 E; K9 O' m. o    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;+ Z, Q( c9 _/ W: A- {! r& A
    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)
9 Q  ?, n" y+ e# _/ H) w; F# I8 n; J    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对0 G$ a0 V/ z& q! |
    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1$ \: N) X5 r  a5 }
        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;; k& x4 V6 p) H: Z" W) q! h
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//! c5 c+ G+ C" K' A2 s
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));
' E* I* K# o) r    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh
1 H9 b3 f9 |9 ?! k! X5 O    if (((cfgCAN >> 26)&0x01)==1){
) g$ b7 m" n: z+ W2 Y$ k        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;' p% c0 r8 G, A% p+ e& d
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4& V- \8 A9 s$ u/ n, _! _  M
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+45 V' x, W' w3 o4 B
    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。
+ l$ m: F" M6 R5 u$ g) U- N! N8 G    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;; B! n2 i& x( N% J1 P2 ^
    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;
4 l2 i% b) |. g5 F    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment
0 {# G& Z6 |: E    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;
+ c) H0 a' {. e5 g* ~4 Z    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
; H3 N- f' ^: F, x" U    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation
* m6 }7 d% q, k    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控' e) @% _8 u' n" C
    return retStat;+ J# v. S- E; W5 N3 _/ ]
}   // <over 2019-0208 aiherong suncun>
! D5 z6 b% J- l# n2 B1 S3 u2 a7 f1 T5 O+ P
int CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
- A  W: Z5 _7 U% X7 ]: g    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.
+ b: c( _% O; ~5 @5 W    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state
0 S  g! I6 ]3 `! {$ k% u# }, C+ j3 O    TxMsg.StdId=0x12;                         // 标准标识符为0) ?, W% z9 r/ h% S' n
    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)
0 x! j- h* b' v$ y6 m; d1 m    TxMsg.IDE=0;                              // 使用扩展标识符- O; a2 F8 u( W5 T. V* {
    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位
4 B' P# Q. z- P2 q* d    TxMsg.DLC=len;                            // 发送两帧信息
5 z+ Q7 q5 F2 p1 u+ O5 ^    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息% K% ]0 W; Z/ m
    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;
9 Z6 P8 Z0 K* E& {& Z2 {    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;) ~* k) `- @  Z4 w
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;
- [' Y. X7 }7 `    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
% @  ^! S  w8 E/ d$ f. H    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04! }( i* P; U6 O" H
          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?6 p& _  j6 G9 V# `  ?' z
          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);
. r- F5 D0 Z1 T$ q3 ?* Q2 G$ R          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);4 D1 `! N0 o( c$ U+ x2 @
             TxMsg.DLC &= (uint8_t)0x0000000F;7 ?- e* i" g2 |: X+ ^
          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;7 K! M. B7 o( L  Z2 T5 w" W. m: D# m
          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;2 l' P+ i7 S6 h6 J4 k6 z2 b
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR" v6 u0 k& w7 r1 d5 J
                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);
, A# q+ h) f! ~. F4 M9 X( J          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR' U) K5 u2 d0 o8 E: R$ V7 o5 j
                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);- \" w# `  C, H  C; K
          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求
! A$ H/ E- s$ t7 n    }
' s4 X  a/ d( Y: V8 B% A    for (i=0;i<0xffff;i++){  //等待发送结束
. k+ b* Q& D; G6 n2 p        switch (mailBOX){. W) S' }; h* t8 A- i8 W
          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)3 ]  x2 \: x, k+ `, M
          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)
# h0 n1 o! T$ s0 a, J  J# q          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)# _  t: J, P( _$ r8 ?0 X! l* v
          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00
( Z3 ~2 o# }6 C4 h& l8 q# d' p        }
! g" o5 a7 e% ^0 {- U        switch (sendST) {( U7 _" D* t, X) |* J' \
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
. \. q* ?3 F7 a+ @, d2 |$ l          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):0 _1 g$ A9 h* N
          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):
+ E" m; v" ~6 ]/ W9 Y          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed
. K* p& Q, `8 [! t) E  u4 D          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0), V# x6 o0 c) F- s8 W3 L
          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
4 y9 r0 H  D+ F& b          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)
. J& ~# `6 l  u+ Z9 Q9 S  s          default:        sendST = 0; break;
" K6 C1 W: C$ v- j5 F  T% P- G        }
# s0 w9 c# g+ M# G        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功" {: x# o  r9 ^9 c
    }
, o& y& r$ L& D8 F    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
0 h6 z( D! u! E                  return 0xABCFACE; // 返回 0xAbcFace - 成功# I$ T. n5 e+ J1 N4 l; M
}
" ^* \/ `, ^. f  r, ~' A2 Z& o1 I4 a7 G, |; p6 y6 W! n
int CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;6 Z+ R( P8 ?9 ~% B3 B
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度7 u  e# ?! x! |3 U0 J
    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||
0 c8 W7 j8 T8 S- o' \/ F       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:0 ~# w' o9 ?3 Q$ n( f! S" P: u6 v
        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R; o! r/ P6 S. D9 \6 ]
        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);& k7 M* M8 J. \8 X8 n  P$ E
        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);9 P" k3 z8 b2 `7 b, s8 X
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;
# [' p: S% `; V8 H& t& p( Y        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;
! Y3 }. e1 H2 I4 ~. e& F4 q2 W        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8
$ J" i2 d2 {3 O' o  a" K" N5 P        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R' {& }9 R& x5 l) ?9 O8 k
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);0 }* z3 X. u$ H4 Y: D9 w( F4 q
        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);
. ^, {7 Z& B# q- U: B        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);
0 T7 I9 W, @5 k, U! k        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R: J8 N) |2 Y4 v- C, F+ g; i
        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);  U- f. R; l6 x' @2 s
        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);
- @1 _0 ~( o' N        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);; {+ T; x% |3 P% V  g( Q8 u
        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;
6 |; @0 K6 i" s9 Q+ V8 c        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
8 v) l5 Q  O7 _* g* F$ s        for(i=0;i<RxMsg.DLC;i++)* q, S- E' Y: a4 B
        buf[i]=RxMsg.Data[i];
  g! a7 R8 X6 i+ O3 W, w3 [1 q  O        return RxMsg.DLC;; O1 x7 H( G5 ]2 X
    } else return 0; //无数可收故退出/ q. L# u6 }4 `! k0 j, ]. \( v
}0 e% K  w# M; F7 ~5 B3 W4 ]3 F
//-------------------------------------------------- End of AHR_CAN.C ---------------------------------' B8 K7 h* O) ?) u' J* w$ i

. l8 V* e" h# m1 q2 l8 U //--------------------- AHR_CAN.H ---------------------------------------------------------------------
- D% I+ h; Q/ R/ w/ C8 `* S& {+ [, a#ifndef AHR_CANETHUSB_H
$ E+ L2 C! @& A#define AHR_CANETHUSB_H# F8 h4 g( \; w$ @- {6 a/ Y
#include "aiherong.h"
+ `  S6 P; c# a1 V% B#define   CAN_FIFO0            ((uint8_t)0x00)
& ^" I+ c2 {! j#define   CAN_FIFO1            ((uint8_t)0x01)
" m9 s7 d& i3 |* ]# p3 i# }#define   CANid_Std            ((uint32_t)0x00000000)  
, t; T1 A  r8 I/ L& W3 N#define   CANid_Ext            ((uint32_t)0x00000004)  
( I: B8 \: R$ r. e& R- d% b/ @typedef struct{    //发送邮箱有3个
+ f  o0 C9 @: d6 x- B7 e  uint32_t StdId;  //标准ID# [3 l- D3 ?! Z( X% ?9 g/ _
  uint32_t ExtId;  //扩展ID3 m( R6 V; T6 `0 Z) q
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
/ t, t2 O4 Q8 `. i8 b  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
" u+ h; x0 Q) B) q; @. ?& k  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
% u# q- K8 M+ O8 B; D  uint8_t Data[8]; //  8 位数据
# N. T2 D6 p' f. d+ F  Q6 S& a} CAN_TxMsg;' H& |$ i  \3 g8 h, y0 Y
typedef struct{    //接收邮箱有2个6 @% z3 a% W1 t2 B+ B+ s1 ?
  uint32_t StdId;  //标准ID
2 t; W8 j- ^+ D: U. h  uint32_t ExtId;  //扩展ID/ a; _, n  u) U4 @. \& k
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符( v4 K* n1 I' W( a: C
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧, k# `* R+ W' l5 J9 S
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
' v& m( B: }3 m* |( F8 e0 E  uint8_t Data[8]; //  8 位数据
  {  z1 z- A, a$ _! H  uint8_t FMI;     //过滤器匹配序号(Filter match index)+ S0 |/ Y* M. V$ `& M, u3 q* n
} CAN_RxMsg;! n* l9 H! j9 {8 `
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13
! Z! ~2 s' |2 B. J( Bint initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
8 K. j+ c) M+ j: Iint CAN_SendMessage(u8* msg,  u8 len);         //发送数据
2 b! ^4 L5 H! L1 H: L& rint CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据
- P4 K5 z6 \4 p# N#endif
$ c- a, n  a+ ^/ B8 K0 d: }//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?5 n6 G- W' Q* y- v0 {$ i9 u" v
不挣钱的日子跟没头苍蝇一般,己快看不懂世界了

所属标签

相似技术帖

官网相关资源

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