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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!6 ?0 f- ~) ?* V
参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点0 m: m- z) E8 t5 D  k; w

# ]5 q% a2 s% K) a2 I  f; B4 O5 c, U( B1 _0 g# x
' N; N, H9 C* l6 {0 `2 u! ^; a
//---------------------------- AHR_CAN.C --------------------------------------------------------------$ p8 n! }3 v4 h
#include "AHR_CAN.H"/ a$ b+ y1 Y/ K5 v8 Z
int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208 ) n5 h$ ^/ T* m# y+ {% c
//-----------------------------------------------------------------------------------------------------
- e: o+ M5 j' _( p( p//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
) ~4 R2 R3 S& U: d) c5 Q' Z, K4 ^//参数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, x" r6 a# v( f) _, W
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]! B. X' F4 v  G# @/ X& s# k( s
//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址. w/ C5 u2 L5 D# M* j
//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)
9 y) z% H" L2 Z  d4 p* H- ~+ _6 g//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)# f2 d, R3 H' W7 n; B
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal8 H( r' U6 f; g/ ]: y+ E  N
//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack
. b1 A0 A- V$ l$ u' L//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])- {& i1 |+ k: K
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;
" k6 D0 r) t4 ~/ P3 S2 S9 n//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式( s8 V! B$ T* n' R
//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)8 p7 v2 F+ v3 Z1 o
// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限5 S7 Q* j) O/ ~7 j5 D
// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)
" x2 J1 E% V8 l2 m2 }// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)
3 J3 O0 ~( F& w' U// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);& C8 [3 \- e! q% s7 M5 ^- s
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK
5 x9 q% \. W. o' b+ h" M//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
/ s* `3 S- [* V$ u( ]% N, k% d# @" k' q//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位
" _( N; p& R2 S3 U//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理
; ]+ R& |, p9 @, C3 P% D8 N4 w//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
" l, E, |( }* l& ]( ]' z) I5 p//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)
* G2 k8 F0 C) c' ?//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);, F7 L* Q& K, L0 Y" x. k
//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps1 c$ y/ K; h& D; Q
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps
- W$ g% ~* p8 J7 \, D' W- x( B//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回
7 S0 @0 n- `- A. }- Q' h//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元+ R( ?. G' Z" S9 A/ K+ ^# t
//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元, T$ U) _4 E' r( z' K5 Q. {4 i0 m9 b
//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
+ @* t" ^/ p! h' R9 C$ E2 v4 r//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );
2 z& x2 U" x: i" E  w1 X+ L8 O//-----------------------------------------------------------------------------------------------------* C. k( P. |# b; F2 D, e6 {' O: R
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208
- P; \# X2 `' N/ w+ z9 G    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq. P4 T5 ?* n5 L# c1 ?7 V, i
    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk14 T8 f& p, Z8 A# z/ ^, N! m
    switch(0xffff&idCANcfg){' d- p' a1 C) C2 o5 Q) x
        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出4 x8 M4 u( u! B* p3 t1 J
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);: r9 d; R( |  @* N/ g' h! J: i1 a+ `  `, m
              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);+ d: k3 _7 a: r& N& e1 z, y. r
              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU+ ]4 {6 T4 b$ d8 W
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入
: t* @- T. P5 h        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出7 [) h" y  K: t( |+ y. t
              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **
. _7 X( Q5 W9 m7 i              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;
5 }$ u3 O0 x# O+ G              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU! j) k, t$ [/ \, D& z
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU
& J# e) C7 M& h# J        default:     break; //保留: 为了更多的CAN
! x5 c; ~- W$ e& k  R( h1 `+ C; e    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完
8 a6 |4 W5 a/ D; P) ^+ @3 J  a    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
: C" L9 b) H% n: ]% U    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作" f( _2 }( Z7 d% v3 P( w2 W
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;
& I: m- Q. L1 F( b; K    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK
* o3 U3 ?; u' g6 i) f) g0 ?7 k    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:
7 |/ U$ u2 @7 K3 G3 Y. s* O) i- d        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值  R* d8 C5 R" _* k4 J2 }6 W1 W
        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48
0 [9 b8 E; f+ X; \! {$ Q# x        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定7 g5 M* |2 z' z
        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化/ W& r( e# {  t5 R+ ~* ]
        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}  @6 S" {' z5 n
        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.$ S, x" o0 _+ I% q. ^' |
        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!
* l: Y, J& x0 o. I    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初. x4 k2 E# V- L8 \/ ?
    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;4 s/ H8 m4 _- t, `) M( t* V& J
    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01): {, O5 A; C% G- a
    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对
+ f2 [1 A( h, K+ I    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1! [9 H3 a. M9 l2 B3 J: u
        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;
  o. o/ C8 K" b5 T        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//' }: C( W" v! \4 y+ Q
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));0 k5 D7 h4 N4 |1 C: j
    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh
) h  o+ r7 [- G5 x: j8 L6 J    if (((cfgCAN >> 26)&0x01)==1){7 u* n. w- Y5 K* B& B
        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;7 D. R# x- i" m4 Z3 c
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4
: B2 A3 g/ f3 _2 l9 T        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4
/ F0 k+ Z' R5 l" g    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。6 x" @7 M) s( y5 h
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;
/ t* A  y% {  P; t7 V    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;) z. x" b/ T. i, l
    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment
3 C- m) ~6 c- q    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;, W: Q0 U  J: @9 z/ n- a4 [
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
: y5 H- J# w8 W6 O1 H    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation6 Q8 _& \  z  N0 O
    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控
/ {- E4 c6 m7 _" U5 S( @    return retStat;
8 j6 q* C) t: x# ~2 g, E" H}   // <over 2019-0208 aiherong suncun>
; f; K  ~2 F, r) `9 r; v% {$ X6 v; g) E7 }9 [
int CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
0 }* f: i# j. r; v3 ?2 ~    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.- p. d, f; y$ U# B# t- R
    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state
8 y$ ~& y0 }' s  N* r+ Q0 k    TxMsg.StdId=0x12;                         // 标准标识符为0
; }2 b' o6 {9 O+ Q/ J; c    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)1 t( Q5 K' _* k  V- T' @
    TxMsg.IDE=0;                              // 使用扩展标识符
' W0 S% T& X! W. W2 P    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位+ H( z. D4 P! X
    TxMsg.DLC=len;                            // 发送两帧信息6 D! @' y5 i; w0 D8 b4 r* E
    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息; p  B+ P8 ~$ Z: _! [, _* u' N
    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;$ O) r, c+ D% n5 c" ?1 {
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;
* P9 W( o! \  R    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;: |0 t) F5 @# I- ]. D: p, ?
    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
1 V$ ^, G/ I0 J4 x  T+ ^! h2 N    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x041 `$ k/ U$ o. ~6 y7 F8 N
          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?
, E; n( W: m/ E% Q          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);) K; o5 H, e9 }" D7 g; `8 ~, y
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);0 U" Q' ?( m* |9 X( P1 O4 [) h
             TxMsg.DLC &= (uint8_t)0x0000000F;
" ~: w$ ?9 }+ i$ Y6 Z; P          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;$ l1 J( i0 ^) U- Q: w4 ^
          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;9 E0 g; ~" y' |# Z% `6 {
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR
2 i& {, H6 m  t, w' `                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);
' E6 S4 P+ J% e          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR4 a& q. F* I- B/ O* ?6 Q
                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);
( `* T; n+ Y7 v8 ~& p          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求8 t; Y: `7 J$ b# E4 E
    }
6 H, z2 ]$ B- Y; A0 ^! v  L    for (i=0;i<0xffff;i++){  //等待发送结束# M3 ]0 P6 c' ?: X2 v
        switch (mailBOX){3 t7 h3 @, G" b9 ^! l! z6 T- T, {0 [- [
          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)0 x1 s# [* Z/ O& v) q
          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)
0 P. f+ f0 O( x8 W1 B% l* v          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)  [( F6 t/ A! O% O4 y) Q
          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00. Y2 f. _) u2 R& s3 y3 ?. E
        }
# M( q) K0 D& w5 h; q' x* ~5 m. M8 b        switch (sendST) {
6 F  w# n1 `( V3 M  j/ _% [+ x* b          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
* o6 g) Y$ M5 ~! P  Z$ n7 M          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):' ?: B' X3 `2 S) _- S8 J0 T
          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):0 k( ^5 D0 l  w0 W' A: J; F
          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed
+ ?2 y, e+ N8 \% T1 d" e          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)" v. P8 A" {; `2 Y7 q; b
          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
! v, V' W6 p6 u7 U( {* o( ?8 j! b' @- g          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)
0 q' A1 u1 V0 Q3 w" r" b7 S0 j          default:        sendST = 0; break;
; Y1 g) c1 f+ z& X        }
" g% ?' N1 h1 N% C+ `& P: I        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功
7 m" Q- l9 z3 o* w" ]+ }  }    }
- U# f5 ~+ Q! u2 w6 h7 a* K    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
; |; d6 U) h2 f& O7 D                  return 0xABCFACE; // 返回 0xAbcFace - 成功
/ z6 e/ l- V" g" G3 [) O}- x: P& @- s, t7 C$ ~

1 C7 [; U$ T# E0 l; Q1 Gint CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;
5 g7 q, j: ]) z- r  k+ K1 A7 V# ~1 O    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度4 ?7 ~0 k) {% J+ X% N: n% X
    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||
& k! i+ K$ v8 i' k. l       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:: r2 T, Y9 ^0 N! Q% W3 \- w) \
        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R7 d; h; E0 d% X) R4 ^( f* p. r
        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);
" K# O4 [; X4 L8 K5 b        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);' j( w9 j' o* j0 \2 z, @9 B; z
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;
, g# l8 Y& Y% B4 q1 m, t6 i        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;0 w- b7 k2 p( g: L3 R. [" T
        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8
# `6 `2 S! M2 c! F        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R1 }* k% i& b. t% g( ^) H
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
" a/ {( @: R& {# o5 X- k+ X& E        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);
/ Q" {, S! N, ^. Q8 `( c        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);7 Y$ g! c$ Z- `* Y
        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R) t: o0 Q1 X+ D. \) x! A( ^7 l; A  w
        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);# T3 J( m. y$ m. L. S" _
        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);
- p/ u; n$ r3 Z- V        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);
  a; X. ^# _' l4 j' a2 [; ^        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;
" ~1 v5 v. W8 \4 t4 k        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
& s: }& t7 K5 u. J) D3 Y        for(i=0;i<RxMsg.DLC;i++)
3 `* @; w* @) b1 `        buf[i]=RxMsg.Data[i];
' O. A* y: V7 r  Y        return RxMsg.DLC;/ d6 C4 V/ w$ X5 k! }8 k
    } else return 0; //无数可收故退出0 u' G4 Q8 E' e1 R6 I+ T: x) S
}# J6 H3 N1 ^+ N, Y6 X7 E
//-------------------------------------------------- End of AHR_CAN.C ---------------------------------1 m; B* t, r, ^1 Y9 L
/ E. u8 }, S6 C5 l
//--------------------- AHR_CAN.H ---------------------------------------------------------------------
* h6 Z1 k) x7 X- N* `; C8 n#ifndef AHR_CANETHUSB_H
0 ^" |0 o" w6 L, `% H; Z( p7 T#define AHR_CANETHUSB_H
4 _1 E2 I! ~) d/ }#include "aiherong.h"6 R$ ~  L4 n' L* m* K+ Y# \
#define   CAN_FIFO0            ((uint8_t)0x00)
! V: u" k9 F5 F/ {2 v# k#define   CAN_FIFO1            ((uint8_t)0x01)+ t; l0 r% o, N& g
#define   CANid_Std            ((uint32_t)0x00000000)  
: S; W! N% ?" P% P* z9 I% T- M#define   CANid_Ext            ((uint32_t)0x00000004)  : i& q; J9 q8 i1 L
typedef struct{    //发送邮箱有3个6 k: E9 |7 L, J* z
  uint32_t StdId;  //标准ID: z/ I- K: n! f# E/ j
  uint32_t ExtId;  //扩展ID3 I0 ^: b1 @0 t
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符4 r/ W0 e: l+ e  e# B) m5 z
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧+ _7 B- B* H: e8 O
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
2 ?/ i; t" y' G9 ^, z4 O0 y  uint8_t Data[8]; //  8 位数据
' o0 d5 {8 b: O  s( J9 n} CAN_TxMsg;
* R+ _; y# M( Ptypedef struct{    //接收邮箱有2个. l1 Y: J' m- e5 X+ |# G1 Q% M
  uint32_t StdId;  //标准ID
4 I' m$ e2 y1 e  uint32_t ExtId;  //扩展ID7 y* {+ O1 G, o' o! i1 x. C* w
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
2 j& b* i# Z1 ?, T, Q. k( }* g  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧& x% X% i# A8 w3 h
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
" m' I- g" \2 X/ N/ e9 R! V' F  uint8_t Data[8]; //  8 位数据; Z# }: O2 t! D8 V& m
  uint8_t FMI;     //过滤器匹配序号(Filter match index)
& ?, j, k7 E& D0 p' D8 e} CAN_RxMsg;' k% F2 H7 R. u" M! j4 V7 Q# D
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13
4 z+ U8 u4 K4 d1 ]0 N) M( sint initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
* `4 `/ L; e3 p7 @9 C: y. Cint CAN_SendMessage(u8* msg,  u8 len);         //发送数据# d" J# M) @4 x/ z( b
int CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据
6 k4 y! y# n8 j( k/ o" P; q  E, V4 d#endif) R( ]2 d; v6 X1 h  H- `& u# `
//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?( m2 [1 o( h; B% R7 _. ?1 q
不挣钱的日子跟没头苍蝇一般,己快看不懂世界了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版