[Kinetis] MPC5604B的CAN总线通信

[复制链接]
 楼主| ccw1986 发表于 2015-12-29 21:03 | 显示全部楼层 |阅读模式
  1. /* main.c: FlexCAN program */
  2. /* Description: Transmit one message from FlexCAN 0 buf. 0 to FlexCAN C buf. 1
  3. (从 FlexCAN 0 buf. 0 传递一个消息到FlexCAN C buf. 1)*/  

  4. /* Rev 0.1 Jan 16, 2006 S.Mihalik, Copyright Freescale, 2006. All Rights Reserved */



  5. /* Rev 0.2 Jun 6 2006 SM - changed Flexcan A to C & enabled 64 msg buffers */

  6. /* Rev 0.3 Jun 15 2006 SM - 1. Made globals uninitialized */
  7. /*                          2. RecieveMsg function:  read CANx_TIMER, removed setting buffer's CODE*/
  8. /*                          3. added idle loop code for smoother Nexus trace */
  9. /*                          4. modified for newer Freescale header files (r 16) */

  10. /* Rev 0.4 Aug 11 2006 SM - Removed redundant CAN_A.MCR init */

  11. /* Rev 0.5 Jan 31 2007 SM - Removed other redundant CAN_C.MCR init */

  12. /* Rev 0.6 Mar 08 2007 SM - Corrected init of MBs- cleared 64 MBs, instead of 63 */

  13. /* Rev 0.7 Jul 20 2007 SM - Changes for MPC5510 */

  14. /* Rev 0.8 May 15 2008 SM - Changes for new header file symbols */

  15. /* Rev 0.9 May 22 2009 SM - Changes for MPC56xxB/P/S */

  16. /* Rev 1.0 Jul 10 2009 SM - Simplified, cleared CAN Msg Buf flag by writing to reg */


 楼主| ccw1986 发表于 2015-12-29 21:04 | 显示全部楼层
  1. /*   not bit, increased Tx pads slew rate(转换率), changed RxCODE, RxLENGTH, dummy data(虚拟数据) types*/
  2. /*   & init receiving CAN first to allow CAN bus sync time before receiving 1st msg*/
  3. /* Rev 1.1 Mar 14 2010 SM - modified initModesAndClock, updated header file */
  4. /*  NOTE!! structure canbuf_t in header file modified to allow byte addressing*/
  5. /*Chapter 22*/
  6. #include "MPC5604B_M27V.h" /* Use proper include file */

  7. uint32_t  RxCODE;              /* Received message buffer code */
  8. uint32_t  RxID;                 /* Received message ID */
  9. uint32_t  RxLENGTH;            /* Recieved message number of data bytes */
  10. uint8_t   RxDATA[8];            /* Received message data string*/
  11. uint32_t  RxTIMESTAMP;          /* Received message time */   
 楼主| ccw1986 发表于 2015-12-29 21:05 | 显示全部楼层
  1. void initModesAndClks(void)   /*系统初始化*/
  2. {
  3.   ME.MER.R = 0x0000001D;          /* Enable DRUN, RUN0, SAFE, RESET modes */
  4.                                   /* Initialize PLL before turning it on: (初始化锁相环)*/
  5. /* Use 1 of the next 2 lines depending on crystal frequency: */
  6. //锁相环时钟没问题
  7.   CGM.FMPLL_CR.R = 0x02400100;     
  8.   //0x02400100                   /* 8 MHz xtal: Set PLL0 to 64 MHz */  
  9.   /*CGM.FMPLL_CR.R = 0x12400100;*/  /* 40 MHz xtal: Set PLL0 to 64 MHz */   
  10.   ME.RUN[0].R = 0x001F0074;       /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL */


  11. //  ME.DRUN.R=0x001F0010;


  12. // ME.RUNPC[0].R = 0x000000FE;           /* Peri. Cfg. 1 settings: only run in RUN0 mode */
  13.   ME.RUNPC[0].R = 0x00000010;
 楼主| ccw1986 发表于 2015-12-29 21:06 | 显示全部楼层
  1. /*要什么功能就在PCTL中配置相应的序号*/
  2. /*选择FlexCAN0和FlexCAN1控制*/
  3.   ME.PCTL[16].R = 0x01;           /* P143   MPC56xxB/P/S FlexCAN0: select ME.RUNPC[1] */      
  4.   //要和RUNPC保持一致
  5.   ME.PCTL[17].R = 0x01;           /* MPC56xxB/S FlexCAN1:  select ME.RUNPC[1] */      
  6. /*选择SIUL控制*/
  7.   ME.PCTL[68].R = 0x01;           /* MPC56xxB/S SIUL:  select ME.RUNPC[1] */      
  8. /*此处未进行端口引脚配置*/

  9. //  ME.PCTL[96].R=0x00;
  10.                                   /* Mode Transition to enter RUN0 mode: */
  11.   ME.MCTL.R = 0x40005AF0;         /* Enter RUN0 Mode & Key */
  12.   ME.MCTL.R = 0x4000A50F;         /* Enter RUN0 Mode & Inverted Key */  
  13.   while (ME.GS.B.S_MTRANS) {}     /* Wait for mode transition to complete */   
  14.                                   /* Note: could wait here using timer and/or I_TC IRQ */
  15.   while(ME.GS.B.S_CURRENTMODE != 4) {} /* Verify RUN0 is the current mode */
  16. }
 楼主| ccw1986 发表于 2015-12-29 21:07 | 显示全部楼层
  1. void initPeriClkGen(void)    /*??*/
  2. //??????????
  3. {
  4.   CGM.SC_DC[1].R = 0x80;     /* MPC56xxB/S: Enable peri set 2 sysclk divided by 1 */



  5.   CGM.OC_EN.R= 1;
  6.   CGM.OCDS_SC.R= 0x22000000;



  7. }
 楼主| ccw1986 发表于 2015-12-29 21:08 | 显示全部楼层
  1. void disableWatchdog(void)
  2. {
  3.   SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */
  4.   SWT.SR.R = 0x0000d928;
  5.   SWT.CR.R = 0x8000010A;     /* Clear watchdog enable (WEN) */
  6. }        
 楼主| ccw1986 发表于 2015-12-29 21:08 | 显示全部楼层
  1. void initCAN_1 (void)      /*初始化CAN_1*/
  2. {
  3.   uint8_t   i;

  4.   CAN_1.MCR.R = 0x5000003F;       /* Put in Freeze Mode & enable all 64 msg bufs *//*Module Configuration Register----MCR 模式配置寄存器*/
  5.   CAN_1.CR.R = 0x04DB2006;        /* Configure for 8MHz OSC, 100KHz bit time *//*Control Register---CR 控制寄存器*/
  6.   //0x04DB0006
  7.   for (i=0; i<64; i++)
  8.   {
  9.     CAN_1.BUF[i].CS.B.CODE = 0;   /* Inactivate all message buffers */     /*Message Buffer--64个信息缓冲寄存器*/
  10.   }
 楼主| ccw1986 发表于 2015-12-29 21:09 | 显示全部楼层
  1. /*P433*/




  2.   CAN_1.IMRL.B.BUF04M=1;





  3.   CAN_1.BUF[4].CS.B.IDE = 0;      /* MB 4 will look for a standard ID */       /*IDE=0表示Frame format(帧格式) is standard*/
  4.   CAN_1.BUF[4].ID.B.STD_ID = 555; /* MB 4 will look for ID = 555 */            /*ID(帧标识符)*/
  5.   CAN_1.BUF[4].CS.B.CODE = 4;     /* MB 4 set to RX EMPTY */                   /*CODE=0x0100表示EMPTY: MB is active and empty.*/
  6. //  CAN_1.RXGMASK.R = 0x1FFFFF10;   /* Global acceptance mask */                 /*Rx Global Mask Register---RXGMASK*/
  7.   SIU.PCR[42].R = 0x0624;         /* MPC56xxB: Config port C10 as CAN1TX, open drain */
  8.   SIU.PCR[35].R = 0x0103;         /* MPC56xxB: Configure port C3 as CAN1RX */      /*CAN_1的收发送*/
  9.   SIU.PSMI[0].R = 0x00;           /* MPC56xxB: Select PCR 35 for CAN1RX Input */   /*P346*//*因为可以作为CAN1Rx的引脚有三个(PC3 PC11 PF15)这里选择PC3以后,要注释 SIU.PSMI[0].R = 0x00;表明选择的是PC3*/
  10.   CAN_1.MCR.R = 0x0000003F;       /* Negate FlexCAN 1 halt state for  64 MB */
  11. }
 楼主| ccw1986 发表于 2015-12-29 21:10 | 显示全部楼层
  1. oid initCAN_0 (void)     /*初始化CAN_0*/
  2. {
  3.   uint8_t   i;

  4.   CAN_0.MCR.R = 0x5000003F;       /* Put in Freeze Mode & enable all 64 msg bufs */   /*Freeze Mode(It is enabled when the FRZ bit in the MCR is asserted.)*/



  5.   CAN_0.CR.R = 0x04DB0006;        /* Configure for 8MHz OSC, 100KHz bit time */
  6.   /*怎么配置波特率*/


  7.   for (i=0; i<64; i++)
  8.   {
  9.     CAN_0.BUF[i].CS.B.CODE = 0;   /* Inactivate all message buffers */
  10.   }
 楼主| ccw1986 发表于 2015-12-29 21:11 | 显示全部楼层
  1. CAN_0.IMRL.B.BUF00M=1;
  2.   CAN_0.BUF[0].CS.B.IDE = 0;           /* Use standard ID length */  /*IDE=0表示Frame format(帧格式) is standard*/
  3.   CAN_0.BUF[0].ID.B.STD_ID = 555;      /* Transmit ID is 555 */    /*ID(帧标识符)*/
  4.   CAN_0.BUF[0].CS.B.RTR = 0;           /* Data frame, not remote Tx request frame */  /*RTR=0表示Indicates the current MB has a Data Frame to be transmitted(表明当前信息缓冲寄存器将要发送)*/ /*RTR=Remote Transmission Request(远程发送请求)*/
  5. //  CAN_0.RXGMASK.R = 0x1FFFFFFF;  


  6.   CAN_0.BUF[0].CS.B.CODE = 8;     /* Message Buffer 0 set to TX INACTIVE */    /*CODE=0x1000表示INACTIVE: MB does not participate in the arbitration process.*/
  7.   SIU.PCR[16].R = 0x0624;         /* MPC56xxB: Config port B0 as CAN0TX, open drain */
  8.   SIU.PCR[17].R = 0x0103;        /* MPC56xxB: Configure port B1 as CAN0RX */    /*CAN_0的收发送*/
  9.   CAN_0.MCR.R = 0x0000003F;       /* Negate FlexCAN 0 halt state for 64 MB */
  10. }
 楼主| ccw1986 发表于 2015-12-29 21:12 | 显示全部楼层
  1. /*发送端配置相对简单(或许在信息发送函数中进行了设置),只对TX设置为Inactive,而接收端设置比较复杂,比如帧和MB的设置*/
  2. void TransmitMsg (void)     /*发送信息函数*/
  3. {
  4.   uint8_t        i;
  5.                                    /* Assumption:  Message buffer CODE is INACTIVE */
  6.   const uint8_t TxData[] = {"Hello"};  /* Transmit string*/  
  7.   CAN_0.BUF[0].CS.B.IDE = 0;           /* Use standard ID length */  /*IDE=0表示Frame format(帧格式) is standard*/
  8.   CAN_0.BUF[0].ID.B.STD_ID = 555;      /* Transmit ID is 555 */    /*ID(帧标识符)*/
  9.   CAN_0.BUF[0].CS.B.RTR = 0;           /* Data frame, not remote Tx request frame */  /*RTR=0表示Indicates the current MB has a Data Frame to be transmitted(表明当前信息缓冲寄存器将要发送)*/ /*RTR=Remote Transmission Request(远程发送请求)*/
  10.   CAN_0.BUF[0].CS.B.LENGTH = sizeof(TxData) -1 ; /* # bytes to transmit w/o null */
  11.   for (i=0; i<sizeof(TxData); i++)
  12.   {
  13.     CAN_0.BUF[0].DATA.B[i] = TxData[i];      /* Data to be transmitted */  /*DATA表示数据段*/
  14.   }
  15.   CAN_0.BUF[0].CS.B.SRR = 1;           /* Tx frame (not req'd for standard frame)*/  /*SRR=1表示 Recessive value is compulsory for transmission in Extended Format frames(在扩展帧格式下隐形值被强制发送)*/
  16.   CAN_0.BUF[0].CS.B.CODE =0xC;         /* Activate msg. buf. to transmit data frame */ /*RTR=0且CODE=1时Transmit data frame unconditionally once. After transmission, the
  17. MB automatically returns to the INACTIVE state.(发送结束后,MB自动返回到非活跃状态)*/
  18. }
 楼主| ccw1986 发表于 2015-12-29 21:13 | 显示全部楼层
  1. /*发送CAN_0选择缓冲寄存器BUF[0],接收CAN_1选择缓冲寄存器BUF[1]*/
  2. void RecieveMsg (void)      /*接收信息函数*/
  3. {  
  4.   uint8_t j;
  5.   uint32_t dummy;

  6.   while (CAN_1.IFRL.B.BUF04I == 0) {}; /* Wait for CAN 1 MB 4 flag */  /*等待标志位*/
  7.   RxCODE   = CAN_1.BUF[4].CS.B.CODE;    /* Read CODE, ID, LENGTH, DATA, TIMESTAMP(读取CAN_1的CODE和ID以及Length,Data,Timestamp等参数) */
  8.   RxID     = CAN_1.BUF[4].ID.B.STD_ID;
  9.   RxLENGTH = CAN_1.BUF[4].CS.B.LENGTH;
  10.   for (j=0; j<RxLENGTH; j++)
  11.   {
  12.     RxDATA[j] = CAN_1.BUF[4].DATA.B[j];
  13.   }
  14.   RxTIMESTAMP = CAN_1.BUF[4].CS.B.TIMESTAMP;
  15.   dummy = CAN_1.TIMER.R;                /* Read TIMER to unlock message buffers */   
  16.   CAN_1.IFRL.R = 0x00000010;            /* Clear CAN 1 MB 4 flag */
  17. }
 楼主| ccw1986 发表于 2015-12-29 21:14 | 显示全部楼层
  1. //void delay_ms(int x)
  2. //{
  3. //        int a,b;
  4. //        for(a=x;a>0;a--)
  5. //                for(b=16000;b>0;b--) ;
  6. //}



  7. void main(void)
  8. {

  9.   volatile uint32_t IdleCtr = 0;


  10. //  delay_ms(1000);

  11.   initModesAndClks();      /* Initialize mode entries */
  12.   initPeriClkGen();        /* Initialize peripheral clock generation for DSPIs */
  13.   disableWatchdog();       /* Disable watchdog */
  14.   initCAN_1();             /* Initialize FLEXCAN 1 & one of its buffers for receive*/
  15.   initCAN_0();             /* Initialize FlexCAN 0 & one of its buffers for transmit*/
  16. // TransmitMsg();           /* Transmit one message from a FlexCAN 0 buffer */     
  17. //  RecieveMsg();            /* Wait for the message to be recieved at FlexCAN 1 */
  18.   while (1)
  19.   {            
  20.        IdleCtr++;    /* Idle loop: increment counter */  
  21.        TransmitMsg();           /* Transmit one message from a FlexCAN 0 buffer */     
  22.        RecieveMsg();            /* Wait for the message to be recieved at FlexCAN 1 */           
  23.   }
  24. }
 楼主| ccw1986 发表于 2015-12-29 21:16 | 显示全部楼层
这个是在找的例程的基础上有部分我修改了,在网上看到帖子说配SBC,不明白什么意思,请前辈给予指点

CAN模块原理图




                    

您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

925

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部