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

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

[复制链接]
aiherong 发布时间:2019-3-25 20:25
下面的CAN初始化函数感觉应该是覆盖了所有CAN功能设置(若有遗漏提醒我,我加进去),无死角!; g/ v1 M& [& U
参数一定让你有些难受,但我觉得总比实现不了什么,过不去坎要好点
; w% E" F1 O1 Q% G- N. z- @4 M( v6 o+ V# S+ F" e' B( w7 f; l

/ u' f  g3 P9 x+ B' \+ W6 V* I6 _
, N8 A9 w' f# \0 @% a: i& u//---------------------------- AHR_CAN.C --------------------------------------------------------------' g/ J! ^* l6 l) L! I2 f" b8 ]
#include "AHR_CAN.H"
% J! r) B9 Q3 }0 Nint CANx_BASE = (unsigned int)0x40006400; //CAN1_BASE:0x40006400;CAN2_BASE:0x40006800;    2019-0208
/ h; e+ q8 j$ p/ ^% @" q//-----------------------------------------------------------------------------------------------------. h# {5 W' J! p
//CAN初始化全功能函数: unsigned int regCAN_MCR=0x00010002,regCAN_MSR=0x00000C02,regCAN_BTR=0x01230000;
5 m, Q2 w1 N' X$ K8 S4 r6 n3 Q  i- e9 _//参数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~07 z  E. }' p) O/ ?: o3 x1 U) F" e
//*-过滤器的 BTR_SILM&LBKM 激活*关联,模式*位宽 SJW[1:0],-- TS2[2:0]时间段TS1[3:0],Number* ◆_BRP[9:0]
, |% o( x( T0 [( c, {; Q5 H( b//    0x200: FMR (过滤器主控寄存器)   0x240: 过滤器组寄存器的起始地址1 f, G; x0 r/ [! ~& P
//    0x204: FM1R(过滤器模式寄存器)   0x214:FFA1R(过滤器FIFO关联寄存器)
8 J/ u) [4 K, V& u' O//    0x20C: FS1R(过滤器位宽寄存器)   0x21C: FA1R(过滤器激活寄存器). M9 X2 e) Y9 n/ T- p, r
//    31: SILM 静默模式(调试)(SilentMode) 0-正常状态;1-静默模式。         // 0-CAN_Mode_Normal& @; W) ?4 ?* q2 a& U' r9 a+ U- X
//    30: LBKM 环回模式(调试)(LoopBackMode(debug)) 0-禁止;1-允许环回模式。// 1-CAN_Mode_LoopBack7 |. ?+ J, N+ u9 k  I7 F
//    29: FACTi 软置1-激活相应过滤器。仅当该位=0或CAN_FMR_FINIT=1后才能修改相应过滤器组i(CAN_FiR[0:1])$ z/ J, v4 S' j8 i5 j8 e% p
//    28: 关联:报文在通过了某过滤器的过滤后,将被存放到其关联的FIFO中。0-过滤器被关联到FIFO0;1-FIFO1;) c+ }9 P- ~6 s
//    27: 0-过滤器组i的2个32位寄存器工作在标识符屏蔽位模式;1-过滤器组i的2个32位REG工作在标识符列表模式- k" I0 p) [9 W$ G" D4 ]& P" U& @. N' j
//    26: 位宽:0-过滤器位宽为2个16位;1-过滤器位宽为单个32位   v--(reSynchronizationJumpWidth). l) ~$ a- S2 G! s' O
// 25~24: SJW[1:0] 重新同步跳跃宽度:为了重新同步,CAN硬件在每位中可延缩n个时间单元的上限
* Y5 @" O' A) P( n7 p6 T// 22~20: TS2[2:0] 时间段2(TimeSegment2) 定义时间段2占用多少时间单元       tBS2 = tCAN x (TS2[2:0] + 1)2 q+ b! ?8 b* _2 e8 \
// 19~16: TS1[3:0] 时间段1(TimeSegment1) 定义时间段1占用多少时间单元       tBS1 = tCAN x (TS1[3:0] + 1)) H" j. ~6 A* {0 M! D% S
// 15~10: 过滤器寄存器组x的组号(下面用变量i表示);8 `- n5 y* q+ ?  H3 r$ i2 |
// 09~00: BRP[9:0] (Baud Rate Prescaler) 该位域定义了时间单元(tq)的时间长度tq = ( BRP[9:0] + 1) x tPCLK% z- \1 P: |5 q; Q$ K0 K
//参数idCANcfg位图: 23    22    21    20  ,  19     18    17    16   //该参数若未设置则缺省:0xFFFFFF13
# z& w! ^2 e4 b* G- ~0 M//                  TTCM  ABOM  AWUM  NART , RFLM  TXFP  保留高电位9 n' s0 g- ?8 V( C
//    07_.CAN_TTCM=0;非时间触发通信模式//06_.CAN_ABOM=0;软件自动离线管理4 w4 G/ U6 H" k$ V
//    05_.CAN_AWUM=0; 睡眠由软件唤醒;1-测报文硬件唤醒//04_.CAN_NART=1-允许重传直到成功; 0-只传一次!
1 L1 p+ J$ a8 q% w* N$ p8 ]//    03_.CAN_RFLM=0; 报文新覆盖旧的;1-锁一后文全丢;// 02_.CAN_TXFP=0;发送次序按(0-标识符;1-请求号)( I/ }2 ?9 {7 [" e  z( `
//  例如:initCANx_Mode(1,二进制[0010,0100,0111,1000,nnnn,nn00,0000,0100]=0x24780004,0,0);( k9 \! n  o2 {5 v& V
//if(initCANx_Mode(1,0x24780004,0,0)==0xABCFACE) LCD_ShowString(10,99,99,30,16,"InitCAN OK!");//500Kbps- B* ^1 K' V& i& P" V
//原函数配置:CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,1);so波特率为: 42M/((6+7+1)*6)=500Kbps
' y- J5 g" P5 T9 A//CANx->BTR:"modeCAN<<30": 模式由SILM和LBKM两位决定: 0-正常;1-正常+环回;2-静默;3-静默+环回# V+ B& Q& p- {% x3 O) I, P. q9 T
//      "tsjw<<24":重新同步跳跃宽度(2位)Tsjw =tsjw+1个时间单位 //"tBS2<<20":时间段2占用多少时间单元
2 g! D# f# x, e' `$ ]. t//          v--  分频系数 Fdiv = brp + 1                       //"tBS1<<16":时间段1占用多少时间单元
9 O- C. V5 S) u: p& j& K' j/ @$ ~//  "brp-1"(Baud Rate Prescaler)定义: 时间单元tq = ( BRP[9:0] + 1) * tPCLK
4 S  ]( c1 B( {//Fpclk1初始化为42M    波特率 = Fpclk1/( ( tbs1 + 1 + tbs2 + 1 + 1 ) * brp );3 X1 z" B  N* F# C9 K; n
//-----------------------------------------------------------------------------------------------------8 C) K7 U9 X: a$ D* a+ ~" f
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk){ //艾和荣  定稿: 2019-0208
  x  H7 \  a. L9 M+ O) B7 H' _  r# f    int waitAck=0x00,retStat=0xBADFACE;   //tsjw:重新同步跳跃时间单元.范围: CAN_SJW_1tq~4tq
$ Z9 F& E; Z" r2 y    uint32_t  fltNumBitPos=0,  i;         //brp :波特率分频器.  范围: 1~1024;  tq = (brp) * tpclk1
- k; Z) }2 u8 o" @" ^' a* h" m    switch(0xffff&idCANcfg){
$ G! t3 M8 Z$ r6 @! z9 }9 c6 S5 F        case 1: CANx_BASE = (unsigned int)0x40006400; // GPIOA12 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出
- e# {; a! X# S- J5 {9 _              *(unsigned int*)0x4002101C|=0x02000000; //2-CAN1;RCC_APB1PeriphClockCmd(RCC...ph_CAN1,1);
! A+ _1 ?" G9 s8 u+ v" f1 |: d1 y              *(unsigned int*)0x40021018|=0x00000004; //4-A口;1-AFIO;//RCC_APB2PClkCmd(RCC.ph_GPIOA,1);" |6 x# y. ~1 I( z
              *(unsigned int*)0x40010804&=0xFFFF8FFF; //位带何异?? GPIOA11<=GPIO_Mode_IPU  x, O: L. P2 f- y/ H1 f( h
              *(unsigned int*)0x40010804|=0x000B8000; break;//     GPIOA11<=GPIO_Mode_IPU 8-上拉输入
. o7 I9 |6 R0 V) C" R1 M        case 2: CANx_BASE = (unsigned int)0x40006800; // GPIOB13 <=GPIO_Mode_AF_PP B-50MHz复用推挽输出
2 Z! K+ Q, B% e/ `# c8 [              *(unsigned int*)0x4002101C|=0x04000000; //4-CAN2;             ** 只有互联型才有CAN2 **
1 Q. y" V5 M- b4 b; d  B' _" K              *(unsigned int*)0x40021018|=0x00000008; //8-GPIOB;1-AFIO;7 d: ^: g) d  `0 A( B: ~
              *(unsigned int*)0x40010C04&=0xFFF8FFFF;            //GPIOB12 <= GPIO_Mode_IPU: e* Q  {8 }  {7 x: b7 p
              *(unsigned int*)0x40010C04|=0x00B80000; break;//     GPIOB12 <= GPIO_Mode_IPU" h' F% m1 z, ]# g$ J$ {7 W1 v3 r  {
        default:     break; //保留: 为了更多的CAN  f5 O+ {# o& \) J% I# J/ e
    }                      //v--while:等<INAK==1且waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=1-正初;0-初完, F$ v4 d2 j: v9 L
    *(unsigned int*)(CANx_BASE+0x00)&=~0x02;//■CANx->MCR &=(~(uint32_t)CAN_MCR_SLEEP); <0-唤醒>;1-睡眠
. S, \. k2 o6 \    *(unsigned int*)(CANx_BASE+0x00)|= 0x01;//■CANx->MCR |= CAN_MCR_INRQ ;<申请初始化> <1-初始>;0-工作' T" c. A9 \$ k7 [0 `7 h) w9 M1 {
    while((((*(unsigned int*)(CANx_BASE+0x04))&1)!=1)&&(waitAck!=0xffff)) waitAck++;
. n0 `8 Y+ X) F' W    if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==0) retStat=0xBADFACE; //0xBADFACE-错误;0xACCFACE-OK! [( H# R! r" y* b& E
    else{                                        //当 CAN_4:MSR_0:INAK=1说明正在初始化,则:) f8 {9 U1 {" \( D1 N. ?; E7 m
        if((0xffff0000&idCANcfg)==0) i= 0xFFFFFF13;  else   i = 0xFFFFFF00|(idCANcfg>>16); //MCR设置值" Y2 x9 D, Y6 A
        *(unsigned int*)(CANx_BASE+0x00) &= i; //■功能扩展设置       初稿:2019-0202 10:48
$ l) u% J2 m, H, n        *(unsigned int*)(CANx_BASE+0x1C) =(cfgCAN&0xC37F03FF)-1;//■MSK:0xC37F03FF 由cfgCAN个性次序决定
  g; ~. Y# D$ J. M9 g        *(unsigned int*)(CANx_BASE+0x00) &= 0xFFFFFFFE;         //■清CAN_0:MCR_0:INRQ=0以退出初始化. N; N! I( o+ H1 K% s& g5 @4 I- n( [
        for(waitAck = 0;(((*(unsigned int*)(CANx_BASE+0x04))&1)==1)&&(waitAck!=0xffff);waitAck++){;}
8 Z: R( `. [1 Q% w2 r! V6 M* V        if (((*(unsigned int*)(CANx_BASE+0x04))&0x01)==1) retStat = 0xBADFACE;  // 0xBADFACE:约定失败.
; L& z! ~" k* @; v; x        else                                              retStat = 0xABCFACE;  // 0xABCFACE:约定成功!1 R! |1 w) l( w+ F9 E# q
    }  //以下CAN_FilterInit(&sCF);   等<INAK==0并waitAck==0xFFFF>胜出■CANx_4:MSR_0:INAK=0-初完;1-正初
" Y6 {0 O$ `& Q% L) z: P, p    i = (cfgCAN >> 10)&0x3F;   fltNumBitPos = ((uint32_t)1) << i;
4 G  O) ^* q' Y    *(unsigned int*)(CANx_BASE+0x200) |= 0x01;//过滤器正在初始化 CAN1->FMR|=FMR_FINIT;(FMR_FINIT=0x01)
' z3 f& K+ ^* r; c3 `6 O3 w! o9 G    *(unsigned int*)(CANx_BASE+0x21C) &=~(uint32_t)fltNumBitPos;//FA1R:只有0-禁用(1-激活)fltNumBitPos对
" r5 O: [! A& E  ^6 |7 ^    if (((cfgCAN >> 26)&0x01)==0){               // 0-Scale=16位;  ^-应的过滤组才能对该组初始化!化后置1
- G2 O5 n4 I+ K6 J7 m        *(unsigned int*)(CANx_BASE+0x20C)&= ~(uint32_t)fltNumBitPos; //位宽 CAN1->FS1R&=~fltNumBitPos;, o/ A) s, M( d
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=(0xFFFF&CFidMsk)<<16|(0xFFFF&CFid);//; A) G2 y. X$ p, L3 n
        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=(0xFFFF0000&CFidMsk)|(0xFFFF&(CFid>>16));- c5 f2 k* q0 p; ?6 U% F) B
    } //位宽=32在下;16在上3行:FR0:MaskIdLow|IdLow;FR1偏移4:MaskIdHigh|IdHigh4 H8 J9 ]! G6 N; H1 |
    if (((cfgCAN >> 26)&0x01)==1){
' K- a2 o5 m& \, I        *(unsigned int*)(CANx_BASE+0x20C)|= fltNumBitPos;     //CAN1->FS1R &= ~(uint32_t)fltNumBitPos;
+ P: \6 P& D) U, \4 d* c        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x00)=CFid; //每组FR0+FR1各32位故*8,FR0与FR1偏移0x4
7 S0 U1 J3 L3 l$ ]3 t) Y        *(unsigned int*)(CANx_BASE+0x240+(i*0x08)+0x04)=CFidMsk;//每组FR1再加偏移故+4
2 W" F1 L6 ?: P" ?1 D    }     //0x204:FM1R=0表示过滤器组x(x=0~13|27)的2个32位寄存器工作在标识符屏蔽位模式;=1:列表模式。7 _3 a9 _( c$ [& ?
    if (((cfgCAN >> 27)&0x01)==0) *(unsigned int*)(CANx_BASE+0x204)&=~(uint32_t)fltNumBitPos;
% q' C+ U' L  J6 q) F    else                          *(unsigned int*)(CANx_BASE+0x204)|= (uint32_t)fltNumBitPos;
7 r0 d, K2 u2 U    //下面的0和1表示:CAN_Filter_FIFO1=1;CAN_Filter_FIFO0=0;  >>27:Mode  >>28:CF_FIFOAssignment
0 F0 b" O& l2 f8 ~( j: h2 |6 s8 |' i; n/ }    if (((cfgCAN >> 28)&0x01)==0) *(unsigned int*)(CANx_BASE+0x214)&=~(uint32_t)fltNumBitPos;& L" a3 B( Y. ~
    else                          *(unsigned int*)(CANx_BASE+0x214)|= (uint32_t)fltNumBitPos;
5 u8 }% `5 V" y" o    if (((cfgCAN >> 29)&0x01)==1) *(unsigned int*)(CANx_BASE+0x21C)|= fltNumBitPos; // 29:CF_Activation
6 e0 x1 G4 V* E  L0 Y    *(unsigned int*)(CANx_BASE+0x200) &=~0x01; //过滤器初始化完毕(CANx_200:FMR_0:FINIT=0)FMR:过滤器主控
3 G: J; _# C$ y& H2 f6 j2 d    return retStat;3 k, o7 v4 r' A$ o) w! o3 w+ `
}   // <over 2019-0208 aiherong suncun>
* E+ y( w' q& N- U1 A; L
/ V- F: A. A9 \$ sint CAN_SendMessage(u8* msg,u8 len){  //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
3 c2 L) X, e# R; V1 J    CAN_TxMsg TxMsg;                  //参数:len - 数据长度(最大为8);msg - 数据指针,最大为8个字节.
, O5 J# }0 @) a/ Z8 J* R* q    u8 mailBOX = 0; u16 i = 0;  uint32_t sendST = 0; // send state1 j+ P" W! }; D# \' R
    TxMsg.StdId=0x12;                         // 标准标识符为01 d! m' C' U% H3 B1 [
    TxMsg.ExtId=0x12;                         // 设置扩展标示符(29位)
' r+ L6 Z$ c( W! H1 U    TxMsg.IDE=0;                              // 使用扩展标识符
9 f' G* N! |8 n! k4 E6 t, k    TxMsg.RTR=0;                              // 消息类型为数据帧,一帧8位
0 o, F- }8 _6 V! ~/ O    TxMsg.DLC=len;                            // 发送两帧信息" V, D7 F) A& ]- c9 H
    for(i=0;i<len;i++)  TxMsg.Data[i]=msg[i]; // 第一帧信息
' k; Z/ X9 P6 }" |7 e: o    if      (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME0) == CAN_TSR_TME0) mailBOX = 0;, T1 ^# A( r7 r! W
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME1) == CAN_TSR_TME1) mailBOX = 1;% k. c1 r6 i- n9 _: ~& p
    else if (((*(unsigned int*)(CANx_BASE+0x08))&CAN_TSR_TME2) == CAN_TSR_TME2) mailBOX = 2;0 a$ p, `9 W% x! u" P
    else    mailBOX  = 4;  // #define CAN_TxStatus_NoMailBox  0x046 ?; [$ ^3 \' |; r; g8 X
    if     (mailBOX != 4){ // #define CAN_TxStatus_NoMailBox  0x04; g& f; `* a- ~9 B7 k/ Y
          (*(unsigned int*)(CANx_BASE+0x180))&=0x01;//sTxMailBox[mailBOX].TIR&=(~)TMIDxR_TXRQ;发完硬清?- K2 `: Z/ p4 D2 H3 C
          if(TxMsg.IDE==CANid_Std)(*(unsigned int*)(CANx_BASE+0x180))|=((TxMsg.StdId)<<21)|(TxMsg.RTR);; u2 C8 F* x% M1 C: s+ P
          else        (*(unsigned int*)(CANx_BASE+0x180))|=(TxMsg.IDE)|((TxMsg.ExtId)<< 3)|(TxMsg.RTR);
  `" R7 C; m1 {1 a% @- N7 c, r9 s             TxMsg.DLC &= (uint8_t)0x0000000F;
; N' A/ v* W3 C" }7 ]* |          (*(unsigned int*)(CANx_BASE+0x184))&= (uint32_t)0xFFFFFFF0;; G8 c7 d/ Y7 g0 N  L+ B/ q5 S8 ?
          (*(unsigned int*)(CANx_BASE+0x184))|= TxMsg.DLC;
2 n0 r  ^5 F7 o+ ]          (*(unsigned int*)(CANx_BASE+0x18C))= ((uint32_t)TxMsg.Data[7]<<24| //sTxMailBox[mailBOX].TDHR
5 o  c# a, c6 A2 H; Q& \                    (uint32_t)TxMsg.Data[6]<<16|(uint32_t)TxMsg.Data[5]<< 8|(uint32_t)TxMsg.Data[4]);4 t/ o# i7 w1 X7 m8 _1 E+ f2 g
          (*(unsigned int*)(CANx_BASE+0x188))= ((uint32_t)TxMsg.Data[3]<<24| //sTxMailBox[mailBOX].TDLR
4 B- O- w4 i7 [  f+ Q                    (uint32_t)TxMsg.Data[2]<<16|(uint32_t)TxMsg.Data[1]<< 8|(uint32_t)TxMsg.Data[0]);8 i6 o1 i+ z9 k3 t* E* i
          (*(unsigned int*)(CANx_BASE+0x180))|=0x01;//sTxMailBox[mailBOX].TIR|=TMIDxR_TXRQ;发送数据请求
( E9 W8 C: W# U    }4 ~' Q8 E; f- ?, s0 K
    for (i=0;i<0xffff;i++){  //等待发送结束
2 U6 U( \; \% E9 q9 F+ O7 I, R        switch (mailBOX){
9 U$ T! j2 G6 ]& `0 c          case 0:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x04000003;break;//&(TSR_RQCP0|_TXOK0|_TME0), W; t+ I/ c* n
          case 1:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x08000300;break;//&(TSR_RQCP1|_TXOK1|_TME1)
! d* I& S  B" }0 R+ v          case 2:sendST=(*(unsigned int*)(CANx_BASE+0x08))&0x10030000;break;//&(TSR_RQCP2|_TXOK2|_TME2)
! z- z( ^: D% m          default:sendST = 0x00;        break; //#define CAN_TxStatus_Failed  0x001 `8 _6 z4 j- A# x
        }
$ W4 w2 R4 _% I: T" r, o0 _. y: O        switch (sendST) {/ b& A9 d( L% T  i
          case 0x00000000:sendST = 2; break;  //#define CAN_TxStatus_Pending 0x02
, D) ~; v3 _. J; }; u4 j& {          case 0x04000001:                    //case (CAN_TSR_RQCP0|CAN_TSR_TME0):
3 K+ y8 \2 r, d( }. ~          case 0x08000100:                    //case (CAN_TSR_RQCP1|CAN_TSR_TME1):
- _7 ~! i- B+ `          case 0x10010000:sendST = 0; break;  //case (CAN_TSR_RQCP2|CAN_TSR_TME2): CAN_TxStatus_Failed
2 K! Q  V. N% j1 L2 w          case 0x04000003:                    //case (CAN_TSR_RQCP0|CAN_TSR_TXOK0|CAN_TSR_TME0)
3 I6 V7 p* l2 {7 s+ o' s, H2 ^          case 0x08000300:                    //case (CAN_TSR_RQCP1|CAN_TSR_TXOK1|CAN_TSR_TME1)
0 t  l- z; f% r$ I7 P          case 0x10030000:sendST = 1; break;  //case 说明:仅当"位TSR_TXOKn=1"才算成功(CAN_TxStatus_Ok)
! ~1 J4 }- `) Y( Z7 B9 T, ^          default:        sendST = 0; break;
6 n* s" N' S- z, @        }4 t+ K% \, p/ E8 Q: y$ z
        if ((sendST==0x01)&&(i<0xffff)) return 0xAbcFace;//#define CAN_TxStatus_Ok  0x01  返回成功, j# P0 }% t4 C* P, U. o5 Y0 M, g
    }
1 W% Q% H! a( Q9 v9 c9 k$ t    if(i>=0xffff) return 0xBadFace; // 返回 0xBadFace - 失败
5 S) k4 s! \& @* j. o4 _                  return 0xABCFACE; // 返回 0xAbcFace - 成功
2 o# d+ [' C- N5 l. l; ?$ F}
& A/ [) ~7 i1 s: r  |2 P8 [' d/ n3 g9 r  f& F3 X9 N
int CAN_RecvMessage(u8 *buf,int fifoNO){      //can口接收数据查询 参数:buf-数据缓存区;fifoNO-0或1;9 N- j6 A" I& M  y4 E. P! ]7 {, q
    CAN_RxMsg RxMsg;    u32 i;                // 20190202 0点   //返回值:0-没收到数; x-接收的数据长度$ S3 i1 Z' b/ }% g3 A0 C
    if((fifoNO==0)&&((*(unsigned int*)(CANx_BASE+0x0C)&0x03)!=0)||/ R5 J9 x- T* ^( d% D
       (fifoNO==1)&&((*(unsigned int*)(CANx_BASE+0x10)&0x03)!=0)){  // 以下仅FIFO0,未包含FIFO1:1 b8 Y1 b6 `  D" i+ N
        RxMsg.IDE=0x04&(*(unsigned int*)(CANx_BASE+0x1B0));//->sFIFOMailBox[fifoNO].RIR;即:FIFO0_RI0R2 r2 O' T) A6 C# K  p+ j! J0 B# t
        if(RxMsg.IDE==CANid_Std)  RxMsg.StdId=0x000007FF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >> 21);5 H3 G; ]* N8 M: q9 m9 _
        else                      RxMsg.ExtId=0x1FFFFFFF & ((*(unsigned int*)(CANx_BASE+0x1B0)) >>  3);% |* r( d$ g5 M
        RxMsg.RTR    = 0x02& (*(unsigned int*)(CANx_BASE+0x1B0));  //CANx->sFIFOMailBox[fifoNO].RIR;
7 _# X/ E0 e5 \4 ]* }7 T4 l; N, P        RxMsg.DLC    = 0x0F& (*(unsigned int*)(CANx_BASE+0x1B4));  //CANx->sFIFOMailBox[fifoNO].RDTR;0 ~/ g7 V9 k$ v( b% O$ ~
        RxMsg.FMI    = 0xFF&((*(unsigned int*)(CANx_BASE+0x1B4))>> 8);   //即:FIFO0_RDT0R >> 8# ]) h8 Z. p  _$ p/ f
        RxMsg.Data[0]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1B8));        //即:FIFO0_RDL0R
$ ^/ d# B' r, Z. W1 L        RxMsg.Data[1]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>> 8);
% c9 b1 S/ P9 S: t        RxMsg.Data[2]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>16);
* }, A# A6 e& g, m2 K' D( R0 u        RxMsg.Data[3]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1B8))>>24);9 m3 c, J+ p0 {+ m
        RxMsg.Data[4]= 0xFF& (*(unsigned int*)(CANx_BASE+0x1BC));        //即:FIFO0_RDH0R/ O/ Z) H; v% E; s
        RxMsg.Data[5]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>> 8);
9 d% K# m( t' T( n        RxMsg.Data[6]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>16);/ N5 L' k+ m! y
        RxMsg.Data[7]= 0xFF&((*(unsigned int*)(CANx_BASE+0x1BC))>>24);
; }; x$ B, f1 T2 P4 q        if (fifoNO == CAN_FIFO0) *(unsigned int*)(CANx_BASE+0x0C)|=0x20;//CANx->RF0R |= CAN_RF0R_RFOM0;
! m$ r5 L3 p/ r' R        else                     *(unsigned int*)(CANx_BASE+0x10)|=0x20;//CANx->RF1R |= CAN_RF1R_RFOM1;
0 i1 `; p5 K7 b$ `% ]        for(i=0;i<RxMsg.DLC;i++)
- l) q  z# W  V: O        buf[i]=RxMsg.Data[i];
6 c2 Z# v( I0 Q% S        return RxMsg.DLC;, O- b0 u$ V& F1 c0 v7 _
    } else return 0; //无数可收故退出
. H- n9 S( |7 Q- K3 l7 T+ H/ W8 x}
* m3 O" `" {2 t//-------------------------------------------------- End of AHR_CAN.C ---------------------------------
' m2 [4 z- k  Q1 i1 }
% N3 R$ e6 e5 R, e8 o //--------------------- AHR_CAN.H ---------------------------------------------------------------------$ ^9 @: X9 `1 |) N4 I7 L+ x
#ifndef AHR_CANETHUSB_H. @4 d- U+ w' R% C) m4 @, z
#define AHR_CANETHUSB_H
" ]9 P( [& i* a9 O  t3 x#include "aiherong.h"0 i/ @; o4 W4 l- a0 M) l6 X
#define   CAN_FIFO0            ((uint8_t)0x00)
1 ?5 T4 r! B- d$ j#define   CAN_FIFO1            ((uint8_t)0x01)
  ^! \8 p+ y7 ?3 O$ A; x8 |: y#define   CANid_Std            ((uint32_t)0x00000000)  
/ u% O/ B% f' b7 B#define   CANid_Ext            ((uint32_t)0x00000004)  : Q, C) P1 N8 F3 v$ I; K2 r1 _$ Y1 j
typedef struct{    //发送邮箱有3个
* U" f9 o" M$ u) _4 b6 K" T, V, E  uint32_t StdId;  //标准ID5 L( z/ {/ W- D' I7 p4 M1 ~
  uint32_t ExtId;  //扩展ID
  A+ r- u0 D5 d* i" u  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符
+ J% O* |8 I$ l% p1 ]1 j  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
7 X/ t8 P' k- Z1 @; i  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
1 d. r& p2 S0 b  uint8_t Data[8]; //  8 位数据' X& B9 `1 O( K# `' \: j4 w
} CAN_TxMsg;2 [$ C" z" X' \
typedef struct{    //接收邮箱有2个: C8 G+ T3 A* D6 `9 z! p+ B' U/ T6 i
  uint32_t StdId;  //标准ID' ^2 I. W) B3 \1 t/ U
  uint32_t ExtId;  //扩展ID
+ a3 [2 c5 w( |& |  uint8_t IDE;     //  标识符选择 (Identifier extension)        0-标准符;1-扩展符/ R, N  p# E' q3 D+ O, t" Z
  uint8_t RTR;     //远程发送请求 (Remote transmission request) 0-数据帧;1-远程帧
2 A0 @; n, H, B7 |' U* E) _  uint8_t DLC;     //发送数据长度 (Data length code)决定1个报文包含0~8几个字节数据
. L- @7 W9 q0 g6 i  uint8_t Data[8]; //  8 位数据  Q& N3 H; I( Y* H& m) U. F. H; N5 x& o
  uint8_t FMI;     //过滤器匹配序号(Filter match index)
, y5 u; c; I! u. g} CAN_RxMsg;; Y2 g9 m5 S8 o4 v: a' Y3 @# C7 |
        //CAN初始化 缺省映射F1:CAN1_RXA11;CAN1_TXA12;F105&107&F2&F4:CAN2_RXB12;CAN2_TXB13' z5 G7 y1 \# S7 u
int initCANx_Mode(int idCANcfg,int cfgCAN,int CFid,int CFidMsk);//(参数1高16位可设置且仅F103后才有CAN2)
1 ?! B$ o7 W; K! e1 q  V' N; c. f* `int CAN_SendMessage(u8* msg,  u8 len);         //发送数据
& M2 }9 J- B( pint CAN_RecvMessage(u8 *buf,int fifoNO);       //接收数据* i" a  J6 V2 _! r- q3 \& A! O6 v
#endif8 }4 d7 @. d. L. {( h
//-------------------------------------------------- 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
承蒙坛主光顾!不知论坛里有没有我能干的活?
" R/ L; Y% h9 F- d+ o/ d2 C不挣钱的日子跟没头苍蝇一般,己快看不懂世界了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版