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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!
; b/ G( t, ^( Y0 `7 e参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点7 z4 o7 E) P2 U! F; `
6 v5 r! ^3 e7 Z6 i# \' m6 b

' d* m, e: d1 K* ~
( P5 @* c, N  P! Q5 ^4 \4 Q//---------------------------- AHR_CAN.C --------------------------------------------------------------
; N# A# d$ C. r6 y1 Q9 X- Y7 Z. L9 G#include "AHR_CAN.H"- Y' i/ c! |# a. {) V  t
int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208 % s+ Z7 @8 I3 g5 ^8 i" E
//-----------------------------------------------------------------------------------------------------. I% M% B2 }3 V, S& y4 I1 u
//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;2 j3 P  H; ^+ U$ _4 h
//参数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& ~3 o  b5 ^8 L
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]8 g( x- m& V/ z- B9 V3 J5 J. i
//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址
) R# M" d! I1 f9 R: K# \//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)
' _+ u5 J6 |% z' |//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器). G4 K8 i9 F+ _; C8 x  \+ m
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal" L4 _7 i6 H; f& u
//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack- _9 }, a& A" M3 v
//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1]). }1 v1 I- d+ D5 H- P. D0 [
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;  o5 \& w8 w- W) w$ Z6 f- I
//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式
4 j1 z" M. Q9 s$ o; L% ]4 X//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)/ y* v9 P$ J# A* \4 U9 ?: M+ H$ F
// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限
: E$ W" v' c6 M: ^; V// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)9 K# d7 q! ]$ N! B1 Y7 K$ i4 l
// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1), [2 {. m! \; o% v; i7 U% _* U$ k
// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);" s  \0 [7 i7 c, o
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK
  R: Z: u# l1 W! N1 }& p8 j2 q//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
% h3 |8 `( \  o8 `5 M, {2 T- v//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位  D6 |- R' {  X$ X
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理3 R3 h! }; n2 O/ A
//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
8 Y& e  ]5 B7 t2 ~0 e//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)7 ^5 r$ @, g- H; A0 Z0 h& _
//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);
. ^1 c, X( H% X6 K  s4 k; c//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps( T. [( u9 {+ Z% e( }* e/ ~" R, n
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps$ T; j8 g  b/ ]( }% S' y
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回
+ |8 n: l8 `' A: y. u$ i3 q//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元& b" x/ Y/ T8 j! l3 X8 Q, e6 F* ^
//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元
. \% s; s( M$ r5 Z//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
) \3 t& Q7 y8 v; q. V3 p6 W//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );2 V2 b8 l4 B. \+ L  R
//-----------------------------------------------------------------------------------------------------, E2 B1 [! Y; q& _3 e# J6 T
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208: l$ A! V& _( Q; B" h
    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq
- B* \2 Q9 k6 U    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1
% W$ k& C- S6 l* M    switch(0xffff&idCANcfg){; B( W) b6 J, e
        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出/ Y5 k3 {( S" G: t9 X- k; x( w6 s" e
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);- m: s2 @& P5 T! f
              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);
) ?6 \; D+ s' `! I              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU
: ~" {- d! v. G. B              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入
) q; J5 Q& b; L6 m. W3 L5 p3 t8 T7 J, A2 \        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出' j! `" G' W( G
              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **
$ m1 [, n: k" T! `              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;
0 H$ r) b3 V, S0 _. F              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU! D; v# I; @' m# g' J6 U- I1 R
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU
, P- q4 C/ o! B3 }, q4 k6 o        default:     break; //保留: 为了更多的CAN% p( j: ~0 c9 \7 m8 I( D. U
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完
! d  V8 R& G7 ?/ t' B' c# g    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠* p! y; V# }( O5 m, {  z# n
    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作9 s( d8 _. g  h3 X7 e) _) |- a
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;2 V7 y8 k4 N# b8 P$ b' ~: E
    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK' m% u+ _, N+ T9 W# ?
    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:9 I+ j5 R9 q5 p7 C/ `9 G* ]
        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值2 i5 I3 |& ^+ ~" p' ~! T$ Z
        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:487 T. Q+ O. e+ @0 x
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定" s! p6 D1 q, V: h# I4 C5 d8 z
        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化
+ L5 O8 `# Z! M( P# k        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
) x( ?/ N6 m+ @9 T2 l        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.% l0 I8 X/ K1 Q$ J
        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!9 j4 }% V+ c$ q1 f5 x
    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初
7 \/ E2 L  c0 j' c% B" @5 T# f    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;. c0 K8 _* X/ k1 ]0 f
    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)
% r* D3 [/ _9 |& e) V/ M    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对* P* F+ {# K2 {$ N" v
    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1' _, M1 q* [; {8 w5 R4 N$ _& e8 c
        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;. n1 ?7 z: {) W- Q: o+ e
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//0 ]! S. d3 e! J' Q
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));# `/ {; Z$ A" N9 j
    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh
0 f$ W, Y+ M- ?/ X+ ]; \. ?4 T* B    if (((cfgCAN >> 26)&0x01)==1){2 g: [  I! x) i* i5 z
        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;
# [; W* u- g4 H$ N) d6 `        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x45 ~3 o3 t' [. }& X% j: O
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4. q2 E" j  ~" E! e  ?
    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。
* O1 K- C6 l( w+ F1 ]    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;$ F. h* b& F; C
    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;
2 B& |/ V( ~2 @# E6 {7 W    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment2 p! @3 u! v( S$ G0 d1 U/ ?1 T
    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;' u8 l9 \  W! f) {. A' Y
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
5 V7 X* p$ w0 A7 c& l  {    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation
/ w- R$ Y3 C' u4 F1 H/ b# z    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控; T! k% x$ M# c  D5 K) i
    return retStat;1 o; \% j! b$ X1 s4 M2 b2 i
}   // <over 2019-0208 aiherong suncun>
) `$ |( F* d; O& y8 x2 M
5 s, K7 a2 S- w3 S& lint CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)5 R% T1 H1 ^( ~+ L4 ^
    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.% y) g3 c$ Y5 p+ `& m
    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state: c; M- d7 }6 a7 D# C
    TxMsg.StdId=0x12;                         // 标准标识符为0
2 ~* A4 m2 E1 H( M) e1 A9 b2 g    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)) Y8 R" x/ I" I' K$ ^) g) \
    TxMsg.IDE=0;                              // 使用扩展标识符% j$ }6 Q/ A2 b7 d% e- o7 s+ u8 t$ t
    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位/ I3 ~" g$ ?% s) N9 y
    TxMsg.DLC=len;                            // 发送两帧信息
  q" J3 b; P/ o! y! d    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息  i- E3 ]' @+ V6 T0 }8 K
    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;/ I' s5 a6 ^" J
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;5 ]% _7 u9 w$ V- U9 _% h
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;: B) O/ n4 z1 Y; a2 T5 y
    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x047 `0 K& N0 }+ z% f
    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04
' Y& L6 Q8 T. D" Z  E          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?
! D$ l4 r  z. [! A; ^8 ~          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);' ^3 {/ I# S- M3 `7 \% O* l0 O
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);
: t$ i! C% d9 b; n             TxMsg.DLC &= (uint8_t)0x0000000F;
$ ^: J, f! P$ e! d8 t* \2 T( t" z          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;
( S5 g$ p* D$ O5 O& @          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;
8 A% |" l  [2 Y/ J: q, I# U, {  Y- w          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR% F! g6 b0 C: G$ j8 r: l) l3 b
                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);; i  e3 B4 L0 }2 ]& \+ M& e( B$ W
          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR! O# [' I; {; J4 d8 H
                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);
- [5 }3 l" j3 b' `2 t7 `          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求
3 X: {% C) i+ @  j' G, v    }1 J  l  I! c4 Q3 w  [0 W2 M) L
    for (i=0;i<0xffff;i++){  //等待发送结束$ u( J6 a* H4 I& @3 M2 f8 K: K5 m
        switch (mailBOX){8 c6 c  I$ K: S3 p! G+ l: O
          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)$ w4 |' u3 T/ ?+ y
          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)
" {$ \  m  n: m% {% h- t          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)3 i" v, ]3 `4 S3 `6 t" T# t; c
          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x00
/ v9 F' l# w" C        }* a) y! G1 |8 P' m$ i5 ^
        switch (sendST) {
5 M& F1 }* @- a9 B          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02( P9 N% u, a( F! i% ]
          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):6 I% b4 s2 B" R4 q% a( i
          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):! @) b0 a; E/ W  B% s
          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed
) {$ q! |5 U* T4 K0 U- F. i          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)4 O$ _7 g# [! z* L
          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
1 b9 R5 H* I1 ^; @3 s3 A          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)! E* o8 A! r3 L+ j
          default:        sendST = 0; break;
  h9 n  @" V% z* `& g, N        }
1 [: `4 L  d# s% }( R3 k; u" Y        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功( S& K. i; _+ m
    }% Q, z7 C0 m  m6 J  l
    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
5 H! l5 w% K% b6 S% i9 u3 z; X5 b                  return 0xABCFACE; // 返回 0xAbcFace - 成功/ U5 }- `) d4 Y7 G% x, a0 c5 Y
}+ b- i9 [# O4 d, |6 n! g4 ~, V

  B* S& C& W0 S, Sint CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;; Q$ F' J3 b  P: E# S. o, G3 S
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度
2 F% F  A: ^4 V8 w# d( T    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||
( }1 d) V* I0 c9 c. U* r4 y" R) @       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:
0 |$ C: e( S' X1 H2 W3 H: s# T        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R  S! M3 `1 r  A( i, ], C
        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);+ d# ~, z* h& b8 Q; X1 r
        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);
& P3 S  q! O$ o        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;3 T7 @+ n  C1 l2 H) x' |/ V
        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;! W7 `. K  f8 O# ^: v6 @
        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8: a! D" |# N2 z
        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R
+ Y% `/ U6 D& |/ A- B7 a5 J        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
" t) S& ]7 T7 V        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);
; }/ d$ l$ H: }; e, I        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);
) Q: a. r8 v" _: H7 B% W/ F0 X) `        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R5 J5 K. E, j  A1 _
        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);" ?" o! P( ~; ]3 I' ~
        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);
1 R8 `$ s* H) K        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);! Y/ s& }2 ?' n% k( _9 D
        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;
: I2 l  \- k/ ]/ t) U& C" z* _% q8 F3 D        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
$ x7 x6 I: v4 I! s9 i% ~        for(i=0;i<RxMsg.DLC;i++)1 S4 p" @3 |5 L, t- ]* H" R
        buf[i]=RxMsg.Data[i];
7 G2 p1 o! U) I$ l        return RxMsg.DLC;
1 w, J+ T0 M; N9 B+ u& S. t$ S: d- A    } else return 0; //无数可收故退出
" a4 |' X+ H% X* s3 \: I}3 e* k5 q1 f  H& \
//-------------------------------------------------- End of AHR_CAN.C ---------------------------------! c, x: V% b0 N0 D
1 l% Z* ?1 R+ |, c& T; ?
//--------------------- AHR_CAN.H ---------------------------------------------------------------------' z) a: z5 q/ O  [0 C2 z, M$ p2 L- C
#ifndef AHR_CANETHUSB_H
! z& {+ F  q/ e7 j( L, J6 T% F, `3 p#define AHR_CANETHUSB_H8 L4 f  a9 }9 s' S/ T
#include "aiherong.h"' f# L% O% f. ~* Y. z; j
#define   CAN_FIFO0            ((uint8_t)0x00)% k$ ^" Y. F6 ~8 P4 M2 \3 M( H# F0 Q
#define   CAN_FIFO1            ((uint8_t)0x01)
: L7 s% o4 e0 ?! c3 L- T' m# ?9 {4 g#define   CANid_Std            ((uint32_t)0x00000000)  ; A3 b- v) U" S  [
#define   CANid_Ext            ((uint32_t)0x00000004)  
% F4 r7 X0 h6 o7 ctypedef struct{    //发送邮箱有3个4 h" F/ p( E2 \! V! L$ E( d
  uint32_t StdId;  //标准ID3 p! w  A! W3 S& A
  uint32_t ExtId;  //扩展ID
" E  g! L) {% h5 E  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符9 F0 X8 u0 r7 t7 j; B( N
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
1 [  u  z* l2 D4 {+ F$ Z9 k  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据2 X" H6 I$ w, f" i9 F0 A5 ?7 J
  uint8_t Data[8]; //  8 位数据
- t) ?4 a6 y( v9 {, ]  E2 N} CAN_TxMsg;
. b+ p* u$ A  q- h" X3 I% ~7 ^typedef struct{    //接收邮箱有2个
5 p5 y* A7 @4 N: U" G9 m# n& F  uint32_t StdId;  //标准ID9 L# ?5 [5 J, [0 l% v
  uint32_t ExtId;  //扩展ID" w% J* A" W# J/ i3 m1 j7 |- s
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符2 _. W# r8 |! \& C: p
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
# t7 q5 ]3 J1 n0 D+ t  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
8 [% |! A8 ?  D+ O, j  uint8_t Data[8]; //  8 位数据
1 W, _9 \3 H0 |3 w  uint8_t FMI;     //过滤器匹配序号(Filter match index)
! O4 s8 ^4 h7 N, K+ [} CAN_RxMsg;! y+ w2 G: \2 b3 D' v' p/ l
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13
8 {( A# K' r/ j  x* |( Wint initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)0 B: d3 g. T$ A' h8 y+ q/ R, }7 C
int CAN_SendMessage(u8* msg,  u8 len);         //发送数据* v! t# j, T3 k8 M& Z) P
int CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据
/ G  ?+ J( L4 a$ b/ I+ u#endif
1 I2 o) E: s* Q//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?
/ J9 ~' T  R4 B& J* G不挣钱的日子跟没头苍蝇一般,己快看不懂世界了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版