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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!5 |% y! O2 \. i# k
参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点  v7 [- u4 X0 O0 e7 ]: P
2 y) ]! i6 \( m4 o3 Z4 g: u$ E
$ U0 K( o  s4 ?: p! ?) y( Q
7 }4 Q: T) k& y* R, {% F
//---------------------------- AHR_CAN.C --------------------------------------------------------------% a& J$ K) A$ O! T
#include "AHR_CAN.H"
2 k$ }( Z' \9 |" k# c. k. `int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208 0 [7 H3 n3 P: Q: z8 B- }- N9 x7 e
//-----------------------------------------------------------------------------------------------------
$ p& Z8 a2 S9 K//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
( a* k& h9 @8 ]" e//参数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- L: o1 r, X% }6 C
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]) U5 ^4 z! A3 w
//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址
7 l1 O* d& Z) s, n9 B  X//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)6 `6 Y- s+ s* @0 T
//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)' Q$ K8 j1 h; D4 t
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal
! v" _  p7 E6 h7 \//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack
9 w3 H8 x; n# J//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])
' _" f( H; J4 f7 d2 m3 X//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;
- j3 Y5 r+ {4 N% e) t! _//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式
: R. k8 @" \7 {//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)
1 o$ m; E5 k/ P4 I" W& B; K+ r// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限2 r, j6 l/ g9 ^( K
// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)
5 T. e) t# z! C+ R- p// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)0 d! _, S, M& U
// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);3 d. @/ L. [0 B, v3 X4 [5 \; t
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK& x( A4 C" T  k: g6 t
//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF138 n; W, D9 @( Y2 L
//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位4 K* w3 D; c$ G+ v
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理- u  a% S( }+ v; I; ~' y" [# [4 p
//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
  A% M/ [& ~( R3 S" O//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)
+ m" A% C2 r, m//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);2 o) l- i+ @! a3 [7 z9 }
//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps
8 W- B  e0 |3 X//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps! r! D& I8 e3 ^2 j
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回
4 C! Y  O- {* e+ L0 ~1 H) n//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元
/ ?+ ]& l) d& a6 @" A7 p//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元
$ P4 d* A; @& X; X' v, Q/ P$ }//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
* M0 t  B2 ^* H  r; b//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );5 `- C# x+ P5 x3 H6 t; H
//-----------------------------------------------------------------------------------------------------
  h2 d6 x* p6 C' X2 e1 K% P0 K8 o* }# {int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208
9 G5 H3 \# U$ S: h, G    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq  ~2 F& a  i* }2 v) E
    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk14 u0 r" l% C% O5 L8 Q( r( q# f
    switch(0xffff&idCANcfg){: P* {; `" h2 t7 H6 ]
        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出2 Y& b; B/ M- @
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);
  Q) t0 A# l/ A2 c' v8 _              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);' \! {& ~6 U" B; g% o) H/ g; ?) P: f
              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU9 Z; o( e6 {/ Q: g3 H5 ^, I
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入; \  B( `: j: i9 y( [
        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出# |8 T  S: a% y( N3 @( v
              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **$ [0 M! j6 \; V1 X4 i, d
              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;. L) }( I& m! ]: r& C$ v, P; ?2 E9 m
              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU! c5 h' d7 }* d5 a  R; S7 V5 C
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU5 h8 \+ c2 I$ R* K
        default:     break; //保留: 为了更多的CAN
0 O4 B7 w( q  R% d# y/ f    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完" p+ V& }+ k" i( |# E% z1 j
    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
' C- ~; W7 e2 L  d7 g/ ~    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作& [! A* s, C; |) `
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;
$ i6 [8 ~* [- K# D, P9 r    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK
( I; L/ J& T# G# `% A" I    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:9 t6 B) G$ D* ?0 X% [
        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值
1 q/ O0 ?2 x3 `4 D9 A        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:489 ^* y# `3 O4 b2 i3 g/ j; t
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定
# _& J8 v* B( G        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化3 d: ~. L2 X  z+ f
        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
/ C* m2 \$ ^6 a5 K& M& ?        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.
' m0 l+ [0 x5 q, M6 X% E9 b8 f        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!
/ z; D" E' m$ {4 r# `, e    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初& w3 U+ T: O) v5 L8 _% o! G
    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;6 B3 E3 t1 v, R1 J9 H  G; w; G& W
    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)  i. |* }- X  w2 Q9 z6 |8 j/ y5 b
    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对9 I. u9 m& A5 z; K" ?
    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1
2 Y5 X; k4 Q: ]        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;
: f3 e& ?$ C: ?2 a        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//( t8 A% }7 L/ ^" v
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));
1 Z5 W5 a/ E: ]) k: r9 w) @$ [  V    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh
- v' q: z; A  Q* R' a& p    if (((cfgCAN >> 26)&0x01)==1){
; N+ Q. ^2 o, ?/ j        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;5 `' G+ ]- k3 u" h- r' g; P5 t
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4
$ S" r% y2 {1 B3 u* M& n        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4
! x& i( @# ~3 v; N7 |    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。# @+ H. i7 w2 E/ E' ]6 ~" A* c
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;
/ u" M2 [+ B7 V, G% v8 `$ c    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;
6 j) a/ p& B+ d5 D1 o. c    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment& {, p$ @4 X, @! R6 ]# C
    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;+ [4 l. S4 [5 P
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;4 j; p$ V, {0 o6 t
    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation
7 J1 ]% K, n" a! q8 f1 ?2 ?1 c    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控4 k" Q! a% c% z& _9 o  g% h3 t
    return retStat;* c7 P2 t4 v% Q5 Q/ \! S
}   // <over 2019-0208 aiherong suncun>
+ u3 m! G4 R7 u8 Y+ o, m4 Q8 k7 D5 `4 A# p! Q
int CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧); V8 n& T- A8 }6 O' o/ K( H
    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.
3 w2 q- z( [, M( h, n0 G9 D  R    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state2 I1 Y( J2 O* {" n; E% f
    TxMsg.StdId=0x12;                         // 标准标识符为0
9 M: N- T* g' c    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)
: a8 f* |) y' r5 C    TxMsg.IDE=0;                              // 使用扩展标识符9 @  D4 K* A  q$ B- i
    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位
$ E" ?7 e7 F; b( i6 p2 p+ Y    TxMsg.DLC=len;                            // 发送两帧信息
; o9 i* d4 w) Q    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息
. Z4 m/ V/ P. U/ |. E0 A    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;$ ~) Y. }+ w* V% [
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;: Z3 Z. A3 J) L0 c" W1 m. [
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;0 t  j$ k( _9 [9 g+ w
    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
9 @& P; n) X! E* k) a" q" p  |    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04$ ?* i  `6 \' w3 A' |
          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?* K% b2 a% b5 }
          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);
( X: B9 g% y$ T# A          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);# e1 e+ w& F6 b( E) i
             TxMsg.DLC &= (uint8_t)0x0000000F;
- F/ ^" z. k4 [( l          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;
$ [& V( }+ G' L5 |6 R- k2 J          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;3 [3 ~/ z) q5 g0 f6 |5 h( y5 }
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR& _9 v# L1 l7 I( J
                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);4 N& q2 D/ ^9 M4 M
          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR
0 r' w/ {3 r- i6 m  Y                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);, b' i$ l( ?5 Y4 D
          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求
: s% U! b; u9 }7 @& [! X$ t    }
; G0 Z4 t+ N) f  A9 D- l    for (i=0;i<0xffff;i++){  //等待发送结束7 M! ~; d5 X, E
        switch (mailBOX){
* }( l9 Z( i& @: W( K          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)
5 J/ J4 C; V: \2 U          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)9 N% V+ e  x1 B6 Z" _  H
          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)# Y% X" h. O2 X' u
          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00
$ }9 s, @* G1 Q& L/ a  v4 I        }/ c- S0 |, [4 L- s
        switch (sendST) {9 s+ w; ^6 Y! N. l: }# N' v
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
; p1 p! n, E9 t8 Q) N          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):: u0 t0 J* I1 g  d
          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):
2 A9 ?( L6 f# b& Y( I) m/ L5 Q: P7 F          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed8 M" ~; T5 [/ f! ^& V: y, G
          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)0 R3 w- m( G4 [0 B- W
          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)8 ~  N3 |0 g5 {1 H
          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)
; |4 I( |1 d: O' o& Y6 w8 }% ]          default:        sendST = 0; break;
' Q8 N0 Y. |3 y% @        }
" N! O3 m! E* a: [; e; o: @        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功' s. e: k" J& L' `
    }" c2 W8 s9 C! I! \! Q1 v5 y
    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败6 |1 [" {. e1 f- x
                  return 0xABCFACE; // 返回 0xAbcFace - 成功
$ l) |" k9 Q  R}
5 J( j" v7 q5 R5 K) o5 Z
$ }* G' m4 M+ {- Vint CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;
" D. u6 ]$ T+ N) ?* |    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度8 N8 A, ^0 I9 \2 @9 t
    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||/ m+ s, k6 `7 V% W
       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:
( R  F$ f- W7 I" |5 v        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R
: ]8 z# A; M3 I1 u) O& {        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);' I$ f$ H* ?. Q( Y( M/ }
        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);
, u5 M7 l; Q* C        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;
$ F" R; t3 q; B: I( i. l- R        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;/ v& E  k! ]0 O  l6 y- U
        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8* @% |4 N/ p: \0 S0 m& f% i! @' a
        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R" r& n$ y7 a+ H2 v1 W
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
/ }' a& }# a" ~1 t        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);: R' F2 t9 h' g" l5 X, t9 Y
        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);
4 b; P$ L6 s# X        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R# l# b/ ]1 r2 [. q( B1 ~3 n
        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);7 B- k3 Q. i" j+ B9 i, l
        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);  z7 u  E7 q& e7 E9 V# p
        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);- x; X4 g' a2 l1 y# z# r# }
        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;# ~; g. P5 k& H+ \5 E
        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
! ?( I- P" G) D3 J% r, B9 u0 ?        for(i=0;i<RxMsg.DLC;i++)0 j& P' j# a% V4 c! W
        buf[i]=RxMsg.Data[i];0 B/ |# G8 R9 a' B% b, }
        return RxMsg.DLC;
( d2 H5 z1 h3 D- }( p( P+ ^% _    } else return 0; //无数可收故退出$ b; L. K  }- A0 @5 D0 V& }% ^
}/ X! |2 R6 L( ~  T2 V4 v+ a6 r
//-------------------------------------------------- End of AHR_CAN.C ---------------------------------6 j* `* ~, z9 ~
1 x- N/ Q: }; x" r1 z  m
//--------------------- AHR_CAN.H ---------------------------------------------------------------------4 K7 `4 o5 ]# T$ B6 k# `) i
#ifndef AHR_CANETHUSB_H( q1 Y$ g# [' ~
#define AHR_CANETHUSB_H7 h! p5 G% t1 o. m; @# u5 g
#include "aiherong.h"
4 g6 l) p/ Q& J  R+ I% T#define   CAN_FIFO0            ((uint8_t)0x00)" m/ T2 q! C; l/ j7 A# r! Y3 A
#define   CAN_FIFO1            ((uint8_t)0x01)
/ b1 {& F+ X& x8 G1 C4 \; V1 d#define   CANid_Std            ((uint32_t)0x00000000)  
/ E8 _' h- C( G$ e: `#define   CANid_Ext            ((uint32_t)0x00000004)  
# b+ w6 Q8 S; G5 R$ t5 l' Utypedef struct{    //发送邮箱有3个
# ^' k: R  |& B  uint32_t StdId;  //标准ID
$ K: a3 G3 w' Z, J. y) o  uint32_t ExtId;  //扩展ID# ?$ x8 s/ s; Y# ^: r) h
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
% B& m+ ~: s. X  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧+ ?' K! ?& e- u2 \8 f7 C! s" f
  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
7 x$ }7 R+ Y6 _$ `9 w  uint8_t Data[8]; //  8 位数据- i# K  W/ k, b4 b; y% q. C: A
} CAN_TxMsg;9 [1 q8 k8 ^9 b+ q
typedef struct{    //接收邮箱有2个- K3 U9 P3 _7 S" I5 o3 s
  uint32_t StdId;  //标准ID6 L/ C9 S, [* {& ?: k
  uint32_t ExtId;  //扩展ID+ ]/ C$ G% V: o3 r  ~0 f
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符! f8 j- V: A: c8 k& K' x- D* ?- v
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
% D# a' I* u4 |" K  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
0 H0 M5 ]0 i6 a" P) z1 L! L  uint8_t Data[8]; //  8 位数据  b  Z0 J+ S, }( @, s1 Z% ~
  uint8_t FMI;     //过滤器匹配序号(Filter match index)% J4 f* c, r9 b6 I6 i
} CAN_RxMsg;8 `+ [% t! x2 `, q
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13" @/ D. V5 J0 o: t: T, Y. \* I$ K
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
& c, H" r) n, L; F8 u2 {int CAN_SendMessage(u8* msg,  u8 len);         //发送数据
  p: F  `; g1 [2 P1 Z" n+ \2 S, X% oint CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据
, M' S2 o1 V# V$ j) c6 v2 a#endif# s. Y8 G  n0 I8 p! N9 L
//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?
; @# y; i3 G+ h$ Y不挣钱的日子跟没头苍蝇一般,己快看不懂世界了

所属标签

相似分享

官网相关资源

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