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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!
. w8 H9 A, u* T; f参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点" Y0 p) e/ c. I5 \

! P8 R0 P- s7 _. E$ b+ N
/ {9 Z" F3 k4 i) s3 Z# V3 c8 N  e1 S7 |9 P1 z
//---------------------------- AHR_CAN.C --------------------------------------------------------------
! C2 Y9 d: E5 o#include "AHR_CAN.H"
, N) W; C& J5 g) |7 z; ]int CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208 * y# F. r% u5 Y. L9 o
//------------------------------------------------------------------------------------------------------ Y! q6 m" D* M3 ~  U% G
//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
8 V1 D# S! _8 @- x$ O3 |//参数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/ A% X! u' V/ c$ V, ^, k
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]
) w6 g. E6 I$ n- s3 g- _# ~2 G//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址
' W, Q. Y/ J( \8 h9 D//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)0 k, A0 ~  J7 i  s$ F: w
//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器)3 n8 V' p7 k$ h/ `  c
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal
6 `' ]/ w* k; [) C  ^- Q; W//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack
# R2 E5 G1 n/ U. n: n//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])
( u- p) y0 F- T$ p, u% l+ y) A7 \//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;
' L) n6 N9 I' Y' T//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式
. c" n1 ]" I: E' L; J//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth)2 o- ~9 w4 U! t  H' I8 v
// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限
1 v$ \! [+ _2 E' Z2 R: ?: d// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)
6 }* t! M! F: e  v7 e// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)  N5 d1 N8 C  _6 h5 Y
// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);
% `; g' C8 g" ~// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK1 h7 m( F6 e- V/ p9 d
//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
" r% C5 i. g. v. h( {$ Y! r4 p//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位8 S, R( j( _* i+ r5 l) |' I3 N
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理
- D2 s& w7 k/ m2 g% S' X//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
. C+ Y$ K# h$ V7 s//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)  x: M0 W9 L4 S$ ~& _8 d5 C  ~
//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);6 D: u* X' v2 ?- V$ R
//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps4 F1 d, s: g% h# G
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps( k8 i% E4 X/ F
//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回
9 W, Y- a! g0 f( `2 @6 N//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元: l7 y; d: h/ Q5 A, {0 k# w# C
//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元9 ?0 F' C5 r* c% `; f
//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK1 W% Q' W4 S5 e$ b# G9 e& j
//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );: @/ u3 I: e( n$ _2 V* w& Y" G5 M
//-----------------------------------------------------------------------------------------------------
7 m( V: w/ n- g1 E& F2 L( {int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208
, l$ Z! F# r0 q) u5 `. m6 |    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq
  F7 H- v. x% W$ y% p    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1$ K6 v# |6 Z% e4 z
    switch(0xffff&idCANcfg){5 w/ H% Q. C' I3 @8 |1 |
        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出1 W; S/ H4 ^% p6 P) U; `2 g
              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);
7 ~7 R/ M/ l) H& M1 E1 N# M3 o  j              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);
" m+ s% R# _- U2 a/ t8 j              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU. H' C+ I$ U3 {
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入
: E  v% _# i: Y2 X1 P& g        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出
+ k6 @+ p8 t/ `* t4 H              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **
) y( {# l/ a4 y, v              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;$ q* F& \, r& |! d
              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU  ^& g, ~5 {; o; c4 `: N9 u0 e; }
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU
2 k3 J0 ^/ o9 p* k  [: p        default:     break; //保留: 为了更多的CAN  P  ^/ f7 Q9 \; L# R; o. T0 l
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完& j6 G3 @8 [) y& s5 O* L
    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
1 m/ [0 C5 O. \% N$ n: L2 `    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作5 l1 L) m6 b$ X$ a
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;5 H8 V  g& ?; F
    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK
4 S1 {" l& l8 E2 \    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:& d4 A2 e" q/ w0 i, n5 q+ \# |& }
        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值
& u8 v) c/ T$ W; G+ P        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48. w3 |1 }8 T  J: I8 n. f
        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定% E, T& Y0 h, b2 {4 K0 s6 [
        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化
3 }' T0 a; N. |8 @        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
- Y- X8 c1 G  j* `        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.+ ^+ K/ k5 `8 j# C  U
        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!0 I0 d) E0 ^/ n9 f
    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初
& s. S7 S$ D0 Y* g    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;
6 K5 N- @$ r. C3 R8 _6 w) C    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)& u- h: f3 w% w1 i- G
    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对2 w( c5 T/ b- I/ T7 B( h- h
    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1: [7 x& l$ y4 t2 v! p
        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;  u( O/ _$ C0 o; f
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//
( V0 G$ A6 ^- N* Y, z7 R# C; w        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));
# e5 @4 ~. `0 ?  p5 ~& H2 F# U    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh. D9 p& ?$ K; C( A4 s
    if (((cfgCAN >> 26)&0x01)==1){
1 K/ i6 X' `4 c" v/ U+ b8 p        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;
7 t" l& S1 H& l        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4) c3 E4 K8 A2 \/ E* b5 q# L* {* D, f) a
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4
9 m+ Q' m3 a% V, U/ B. O4 P    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。/ ]/ ~8 `3 K2 {6 s! o- m  T% ?
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;
$ y7 A9 ?. p7 ]" I+ C    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;
" ?/ e8 o4 J: |- U    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment, E! J' x# X: R. h
    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;8 h5 I# z5 _6 ~
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
4 ?1 w, z3 T) u( l    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation( Y( g% [1 r! U% P0 `) {8 J
    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控
# x. o5 D+ B* L3 `; R; u2 t    return retStat;
5 ?" t: K2 O1 ]# H; A  R+ c}   // <over 2019-0208 aiherong suncun>
- r) V, G& W/ \& n3 Z* y2 `6 h( I
int CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧). d7 \" n9 b! n% m, O3 r7 I! p# H
    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.
+ V- D% h% y- ]% ~! ~    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state
4 q2 x0 I5 s) S- U9 I; S    TxMsg.StdId=0x12;                         // 标准标识符为08 ^; L- l4 ]1 ]
    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)
  i  F2 P* p0 ^3 S    TxMsg.IDE=0;                              // 使用扩展标识符# g+ C& o$ Q/ U; }( D! X0 Y. X
    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位
1 Z+ a) I1 j/ V  Q! ?! s8 F. o    TxMsg.DLC=len;                            // 发送两帧信息/ D% C) ], F$ U  T1 X+ a& h, K: B3 @* l
    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息
! J: W) j2 Y2 u' v0 [    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;
2 P7 m: K; F; E7 x! o7 |/ m' I    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;
: `/ Z" c" {0 L4 d    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;
3 b9 A; L+ ]" G) R5 I+ u! x    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x04
& ]0 V1 n" [* b( k& o* L: U    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04
, ]$ J2 E  E9 _4 b9 W, b: u) ?/ H          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?; v; G  G3 Z5 Y. n& F- h
          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);! W! O! e: \; `3 _6 R
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);- J& v# l9 Z' @3 K
             TxMsg.DLC &= (uint8_t)0x0000000F;) p4 X9 p6 B. b! J
          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;, Q! y, l' U9 ?
          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;+ x+ l! i, r) x- j
          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR  V, ~' p& J% z1 X% N: Q
                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);
1 X$ T; ?) ^+ G! l. [          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR0 h7 W0 _- M4 D8 q
                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);
( t5 `+ Q" |" P# L2 I% W          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求* p8 |' I& ?0 S
    }1 T8 Q! \" F1 d4 W6 b$ g
    for (i=0;i<0xffff;i++){  //等待发送结束
5 C7 e3 @$ j; n2 |        switch (mailBOX){
. W, B( `5 `! B# ^          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0)
" J: `. Q8 ^' X2 F9 r7 z7 N          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)
7 J* `6 r' ]; f" u% ]) T9 f          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)
. n. Q7 [: k8 T7 ^% Y          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x009 u# o9 H7 R8 C; b4 G) G
        }
8 m$ W1 g, V$ _# p        switch (sendST) {: {2 _% c  t7 j3 h
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
" Y, x/ \4 f% `          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):
/ k4 W4 h6 S# i2 M' _" L          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):
. j" i' k0 h; O8 |! q          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed* ]) g0 D. ~, i/ u6 Z0 k; Q* r/ o% g
          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)
" r" P, ~3 L3 [& Y& `' }          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
7 o( a5 H  {. _8 X' u3 k' w4 J          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)% Z3 o$ Z) b; a0 K
          default:        sendST = 0; break;5 _7 l* D0 |6 w1 D+ G, b; q
        }
2 C- W! c" G6 I% H4 {        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功/ K& n9 {) q5 j; j5 z
    }9 @+ D1 f' T# O# i7 j0 ?
    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
. R' S7 T& r. e9 M* O9 g* r' q                  return 0xABCFACE; // 返回 0xAbcFace - 成功' W' q- Q( i6 t/ P4 p
}* G* V" G$ z, b& n- |, b$ U5 a

; q2 {. N  e. S$ v( W4 P; b$ L0 y  ~int CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;- e7 ]" ^* Z4 H9 S0 {. b  `
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度
" c, w! r% R9 r* k' _/ y4 C& m+ K    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||, V3 u$ u7 S: w, N9 m
       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:9 u* M6 W' L2 A" H
        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R
; S1 z2 f: Z& ^  _- o5 e8 I7 }        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);
% j) c/ y2 R$ A: |* |2 p        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);3 D4 |. i4 U) v, p. y+ Z7 p5 x8 S
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;8 p# G: c% o( B6 k$ T* z
        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;
& ^2 E- r* b6 P' {5 U5 ^( t        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 82 t. O5 m3 ^8 T$ M3 q7 |
        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R8 g2 r0 V4 O" i. C& [" n3 v
        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);# J" I% h% T7 `
        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);) }- o& c+ Z' K9 T, D& l, H
        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);( x* |( p1 Q! A) s- t% W8 `
        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R
: i, h( N1 q. a' w        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);
6 z9 A/ \- [+ V0 u: }2 S        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);+ g& V; v* b! w6 _2 l$ S7 q
        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);. G# g# w8 H  A
        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;
* _5 \9 @' [) ~1 a# k) E        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
1 R; u7 Z. \% k+ l$ J        for(i=0;i<RxMsg.DLC;i++)' O( a+ }: \) T* Z
        buf[i]=RxMsg.Data[i];  u! Y0 k6 B# r
        return RxMsg.DLC;
3 h5 z) v/ D; m( M    } else return 0; //无数可收故退出0 y- n0 r5 K/ T% U% b7 D2 s" I& `, u
}
( V; H/ |- D) v//-------------------------------------------------- End of AHR_CAN.C ---------------------------------$ F  G8 S1 j$ B0 I
/ J9 ^" L" p3 v0 a' G
//--------------------- AHR_CAN.H ---------------------------------------------------------------------. Q: j) h" b5 Q$ k+ M
#ifndef AHR_CANETHUSB_H
+ R  _7 o2 S% f8 g6 P( F#define AHR_CANETHUSB_H
6 F& F$ [& t5 T8 e#include "aiherong.h"
, u; D( N! x0 l8 ?7 E& K#define   CAN_FIFO0            ((uint8_t)0x00)! D5 [0 p3 Q1 P" L6 ^; b8 m$ o
#define   CAN_FIFO1            ((uint8_t)0x01)
8 V3 ]9 i  X  M+ Y# w#define   CANid_Std            ((uint32_t)0x00000000)  
3 G4 B5 H2 S/ t: b/ {0 ]% k* C0 j#define   CANid_Ext            ((uint32_t)0x00000004)  8 u5 s" j4 a9 j8 M8 }$ U3 W
typedef struct{    //发送邮箱有3个
# p. j8 B1 ]- @/ {" U  uint32_t StdId;  //标准ID9 q$ @- X! o( Z8 K# q5 Z
  uint32_t ExtId;  //扩展ID4 L# q3 S/ Q9 F) y7 V
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符; s# `5 m' i/ F* `# b( S0 P  y
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
" T4 p/ X3 Y# B7 ~  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
  I+ C( t% N$ S& W0 D7 g! E  uint8_t Data[8]; //  8 位数据, r5 ]1 u4 S7 v- Q) y8 W- W
} CAN_TxMsg;) ^# X7 }6 y$ p) y/ k+ x8 t
typedef struct{    //接收邮箱有2个
/ R: q- |1 a/ x5 E3 o  uint32_t StdId;  //标准ID# W$ ?- t% Y9 H3 F( y
  uint32_t ExtId;  //扩展ID5 ]/ B5 M; T5 g8 L6 O: [+ v
  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
6 p' G* X5 N) ^7 g5 D  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
# x; f% c8 B- ?5 z: r: D& ~  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据4 F7 }8 |  b1 l1 K4 J, X
  uint8_t Data[8]; //  8 位数据
/ i5 ~! [' Y: t9 e  uint8_t FMI;     //过滤器匹配序号(Filter match index)
/ b/ ^) n; b, X% w& I} CAN_RxMsg;. y8 D2 P; ?) x3 U& c( Q
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB130 F1 }; S4 K6 z4 N' |. _
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
* x. ]! A- _3 r- Xint CAN_SendMessage(u8* msg,  u8 len);         //发送数据9 c1 ]* ]0 s- s0 A8 T% G
int CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据; F) @' C6 E( D0 [9 T
#endif
1 B* o+ u1 {9 z; F//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?6 y9 E, |6 x( H! C/ v
不挣钱的日子跟没头苍蝇一般,己快看不懂世界了

所属标签

相似分享

官网相关资源

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