在调试flexcan,看来有点难(已解决)

2020-02-20 20:32发布

本帖最后由 richyhuang 于 2014-12-9 16:44 编辑

位时间定义看的有点晕啊.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
holts2
1楼-- · 2020-02-21 22:32
flexcan是FSL的专用CAN ?
richyhuang
2楼-- · 2020-02-22 04:20
holts2 发表于 2014-12-9 16:15
flexcan是FSL的专用CAN ?

应该是吧,以前用的没有flexcan,但是bit timing的计算方式是一样的.
那个是can2.0的标准
FSL_TICS_Robin
3楼-- · 2020-02-22 10:08
richyhuang 发表于 2014-12-9 16:05
接收错误,

以前用microchip,nxp的都有计算器,现在fsl没有了,要靠自己算,我f......  ...

PE就可以实现自动计算,楼主可以尝试配置一个带PE的工程调用CAN的那个LDD试一下。
holts2
4楼-- · 2020-02-22 12:18
 精彩回答 2  元偷偷看……
zhangchaoying
5楼-- · 2020-02-22 17:47
“位时间”是什么?
richyhuang
6楼-- · 2020-02-22 20:15
FSL_TICS_Robin 发表于 2014-12-9 16:25
PE就可以实现自动计算,楼主可以尝试配置一个带PE的工程调用CAN的那个LDD试一下。 ...

搞定了,根据网友提供的例子,改了一下就可以了.
这里就改了一个定义分频系数的地方就可以了,我现在用的是60M的外设时钟,500K通信
  1. void CAN1_ORed_Message_buffer_IRQHandler(void)
  2. {
  3.         printf("CAN1->IFLAG1 = %08x ", CAN1->IFLAG1);
  4.         CAN1->IFLAG1 |= 0xFFFFFFFF;
  5. }
  6. void CAN1_Bus_Off_IRQHandler(void)
  7. {
  8.         printf("CAN1_Bus_Off_IRQHandler ");       
  9. }
  10. void CAN1_Error_IRQHandler(void)
  11. {
  12.         printf("CAN1_Error_IRQHandler ");
  13. }
  14. void CAN1_Tx_Warning_IRQHandler(void)
  15. {
  16.         printf("CAN1_Tx_Warning_IRQHandler ");
  17. }
  18. void CAN1_Rx_Warning_IRQHandler(void)
  19. {
  20.         printf("CAN1_Tx_Warning_IRQHandler ");
  21. }
  22. void CAN1_Wake_Up_IRQHandler(void)
  23. {
  24.         printf("CAN1_Tx_Warning_IRQHandler ");
  25. }

  26. //tower上面使用can1
  27. int CANx_init(uint8_t CANChannel,uint32_t baudrateKHz,uint8_t selfLoop,uint8_t idMask)
  28. {
  29.     int i;
  30.     CAN_Type *CANx;

  31.     if (CANChannel == 0)
  32.         CANx = CAN0;
  33.     else if (CANChannel == 1)
  34.         CANx = CAN1;
  35.        
  36.     //使能FlexCAN外部时钟
  37. //    OSC1->CR |= OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK;
  38.     SIM->SCGC3 |= SIM_SCGC3_FLEXCAN1_MASK;//使能CAN1的时钟模块

  39.     NVIC_EnableIRQ(CAN1_ORed_Message_buffer_IRQn);
  40.         NVIC_EnableIRQ(CAN1_Bus_Off_IRQn);
  41.         NVIC_EnableIRQ(CAN1_Error_IRQn);
  42.         NVIC_EnableIRQ(CAN1_Tx_Warning_IRQn);
  43.         NVIC_EnableIRQ(CAN1_Rx_Warning_IRQn);
  44.         NVIC_EnableIRQ(CAN1_Wake_Up_IRQn);
  45.     //(p281.pin out)
  46.         if((uint32_t)CANx == (uint32_t)CAN1_BASE)
  47.         {
  48.                 PORTC->PCR[16] = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //上拉
  49.                 PORTC->PCR[17] = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //上拉
  50.         }else if((uint32_t)CANx == (uint32_t)CAN0_BASE)
  51.         {
  52.                
  53.         }else{
  54.                 return 2;
  55.         }
  56.     //选择时钟源,外设时钟60MHz,振荡器时钟:50MHz
  57.     CANx->CTRL1 |= CAN_CTRL1_CLKSRC_MASK;//选择内部时钟

  58.     CANx->MCR |= CAN_MCR_FRZ_MASK;  //使能冻结模式
  59.     CANx->MCR &= ~CAN_MCR_MDIS_MASK;//使能CAN模块
  60.     //确认已退出冻结模式
  61.     while ((CAN_MCR_LPMACK_MASK & CANx->MCR));

  62.     //软件复位
  63.     CANx->MCR ^= CAN_MCR_SOFTRST_MASK;
  64.     //等待复位完成
  65.     while (CAN_MCR_SOFTRST_MASK & CANx->MCR);
  66.     //等待进入冻结模式
  67.     while (!(CAN_MCR_FRZACK_MASK & CANx->MCR));

  68.     //将16个邮箱缓冲区内容清0
  69.     for (i=0;i<16;i++)
  70.     {
  71.         CANx->MB[i].CS = 0x00000000;
  72.         CANx->MB[i].ID = 0x00000000;
  73.         CANx->MB[i].WORD0 = 0x00000000;
  74.         CANx->MB[i].WORD1 = 0x00000000;
  75.     }

  76.     //接收邮箱过滤IDE比较,RTR不比较
  77.     CANx->CTRL2 &= ~CAN_CTRL2_EACEN_MASK;
  78.     //远程请求帧产生
  79.     CANx->CTRL2 &= ~CAN_CTRL2_RRS_MASK;
  80.     //邮箱首先从接收FIFO队列匹配然后再在邮箱中匹配
  81.     CANx->CTRL2 &= ~CAN_CTRL2_MRP_MASK;

  82.     //使用一个32位过滤器
  83.     CANx->MCR |= (CANx->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0);
  84.     //设置波特率
  85.     if (SetCANBand(CANChannel,baudrateKHz) == 1)//若设置错误
  86.         return 1;

  87.     //模式选择:回环模式或正常模式
  88.     if (1==selfLoop)
  89.         CANx->CTRL1 |= CAN_CTRL1_LPB_MASK;        //使用回环模式
  90. //        CANx->CTRL1 |= CAN_CTRL1_LOM_MASK;                 //使用监听模式
  91.     //初始化掩码寄存器
  92.     if (1==idMask)//屏蔽ID
  93.     {
  94.         CANx->RXMGMASK = 0x1FFFFFFF;
  95.         CANx->RX14MASK = 0x1FFFFFFF;
  96.         CANx->RX15MASK = 0x1FFFFFFF;
  97.     }
  98.     else//不屏蔽ID
  99.     {
  100.         CANx->RXMGMASK = 0x0;
  101.         CANx->RX14MASK = 0x0;
  102.         CANx->RX15MASK = 0x0;
  103.     }

  104.     //如果单独掩码功能使能,为每个队列初始化单独的掩码寄存器
  105.     if (CANx->MCR & CAN_MCR_IRMQ_MASK)
  106.         for (i = 0; i < NUMBER_OF_MB ; i++)
  107.             CANx->RXIMR[i] = 0x1FFFFFFFL;

  108.     //只有在冻结模式下才能配置,配置完推出冻结模式
  109.     CANx->MCR &= ~(CAN_MCR_HALT_MASK);
  110.     //等待直到退出冻结模式
  111.     while ( CANx->MCR & CAN_MCR_FRZACK_MASK);
  112.     //等到不在冻结模式,休眠模式或者停止模式
  113.     while ((CANx->MCR & CAN_MCR_NOTRDY_MASK));
  114.        
  115.         CANEnableRXBuff(1,//uint8_t CANChannel,
  116.                                         0,//uint16_t iMB,
  117.                                         1//uint32_t id)
  118.         );
  119.         CAN1->IMASK1 |= CAN_IMASK1_BUFLM(0x1ul);
  120.         return 0;
  121. }

  122. //============================================================================
  123. //函数名称:CANSendData
  124. //函数返回:0:成功,1:失败
  125. //参数说明:
  126. //         CANChannel:模块号
  127. //                iMB:缓冲区号
  128. //                               id: ID号
  129. //                           length:数据长度
  130. //                           Data[8]:发送数据缓冲区
  131. //功能概要:发送数据
  132. //============================================================================
  133. int CANSendData(uint8_t CANChannel,uint16_t iMB, uint32_t id,uint8_t length,uint8_t Data[])
  134. {
  135.     int16_t  i,wno,bno;
  136.     uint32_t word[2] = {0};
  137.     CAN_Type *CANx;

  138.     if (CANChannel == 0)
  139.         CANx = CAN0;
  140.     else if (CANChannel == 1)
  141.         CANx = CAN1;

  142.     //缓冲区和数据长度设置错误
  143.     if (iMB >= NUMBER_OF_MB || length >8)
  144.         return 1; //超出范围

  145.     //转换8个字节转换成32位的word存储
  146.     wno = (length-1)>>2;//是否超过4字节
  147.     bno = (length-1)%4; //
  148.     if (wno > 0)        //长度大于4(即发送数据超过4字节)
  149.     {
  150.         word[0] = (
  151.                       (Data[0]<<24)
  152.                       | (Data[1]<<16)
  153.                       | (Data[2]<< 8)
  154.                       |  Data[3]
  155.                   );
  156.     }
  157.     for (i=0;i<=bno;i++)
  158.         word[wno] |= Data[(wno<<2)+i] << (24-(i<<3));

  159.     ///////////////////////////////////////////////////////
  160.     // ID 格式
  161.     // B31 30 29 28 27 26 ... 11 10 9 8 7 6 5 4 3 2 1 0
  162.     // |        |         |                                                                          |
  163.     // |    |    |------------------------------------|
  164.     // |        |                                        |--> 29 位 ID
  165.     // |        |
  166.     // |    |--> RTR  1: 远程帧, 0: 数据帧
  167.     // |
  168.     // |-------> IDE 1 : 扩展ID, 0: 标准ID
  169.     ///////////////////////////////////////////////////////

  170.     //通过id判断帧类型——扩展帧
  171.     wno = (id &  CAN_MSG_IDE_MASK)>>CAN_MSG_IDE_BIT_NO;  //IDE
  172.     //通过id判断帧类型——远程帧
  173.     bno = (id &  CAN_MSG_TYPE_MASK)>>CAN_MSG_TYPE_BIT_NO;//RTR

  174.     //获得ID位数
  175.     i =  wno? 0: FLEXCAN_MB_ID_STD_BIT_NO;

  176.     //以下四步骤为发送过程
  177.     CANx->MB[iMB].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE)//缓冲区写激活代码
  178.                        | (wno<<FLEXCAN_MB_CS_IDE_BIT_NO)//缓冲区写IDE位
  179.                        | (bno<<FLEXCAN_MB_CS_RTR_BIT_NO)//缓冲区写RTR位
  180.                        | FLEXCAN_MB_CS_LENGTH(length);  //缓冲区写数据长度

  181.     //缓冲区写ID
  182.     CANx->MB[iMB].ID = (1 << FLEXCAN_MB_ID_PRIO_BIT_NO)
  183.                        | ((id & ~(CAN_MSG_IDE_MASK|CAN_MSG_TYPE_MASK))<<i);

  184.     //缓冲区写内容
  185.     CANx->MB[iMB].WORD0 = word[0];
  186.     CANx->MB[iMB].WORD1 = word[1];

  187.     //延迟
  188.     for (i = 0;i < 100;i++);

  189.     //通过制定的发送代码开始发送
  190.     CANx->MB[iMB].CS = (CANx->MB[iMB].CS & ~(FLEXCAN_MB_CS_CODE_MASK))
  191.                        | FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)//写激活代码
  192.                        | FLEXCAN_MB_CS_LENGTH(length);//缓冲区写数据长度

  193.     //限时等待发送完成(如果使用中断则限时等待语句可删除)
  194.     i=0;
  195.     while (!(CANx->IFLAG1 & (1<<iMB)))
  196.     {
  197.         if ((i++)>0x1000)
  198.             return 1;
  199.     }
  200.     //清报文缓冲区中断标志
  201.     CANx->IFLAG1 = (1<<iMB);
  202.     return 0;
  203. }

  204. //============================================================================
  205. //函数名称:CANEnableRXBuff
  206. //函数返回:无
  207. //参数说明: CANChannel:CAN模块号
  208. //                 iMB:缓冲区号
  209. //                  id:id号
  210. //功能概要:使能接收缓冲区
  211. //============================================================================
  212. void CANEnableRXBuff(uint8_t CANChannel,uint16_t iMB, uint32_t id)
  213. {
  214.     uint32_t id2;
  215.     uint32_t cs = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY);
  216.     CAN_Type *CANx;

  217.     if (CANChannel == 0)
  218.         CANx = CAN0;
  219.     else if (CANChannel == 1)
  220.         CANx = CAN1;

  221.     //将MB配置为非激活状态
  222.     CANx->MB[iMB].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_INACTIVE);

  223.     //取出29位单独的ID
  224.     id2 = id & ~(CAN_MSG_IDE_MASK | CAN_MSG_TYPE_MASK);
  225.     if (id & CAN_MSG_IDE_MASK)//扩展帧
  226.     {
  227.         CANx->MB[iMB].ID = id2;
  228.         cs |= FLEXCAN_MB_CS_IDE;//置位IDE位
  229.     }
  230.     else//标准帧
  231.     {
  232.         CANx->MB[iMB].ID = id2<<FLEXCAN_MB_ID_STD_BIT_NO;
  233.     }

  234.     //激活接收缓冲区,code写0100
  235.     CANx->MB[iMB].CS = cs;
  236. }

  237. //============================================================================
  238. //函数名称:CANRecData
  239. //函数返回:0:成功,1:失败
  240. //参数说明:CANChannel:CAN模块号
  241. //                iMB:缓冲区号
  242. //                               id: ID号
  243. //                           lenght:数据长度
  244. //                          Data[8]: 和接收数据缓冲区
  245. //功能概要:接收数据
  246. //============================================================================
  247. uint8_t CANRecData(uint8_t CANChannel,uint16_t iMB, uint32_t *id,uint8_t *Datalenght,uint8_t Data[])
  248. {
  249.     int8_t   i,wno,bno;
  250.     uint16_t code;
  251.     uint8_t  *pMBData;
  252.     int16_t  length;
  253.     int8_t   format;
  254.     uint8_t *pBytes = Data;
  255.     CAN_Type *CANx;

  256.     if (CANChannel == 0)
  257.         CANx = CAN0;
  258.     else if (CANChannel == 1)
  259.         CANx = CAN1;

  260.     // 锁定MB
  261.     code = FLEXCAN_get_code(CANx->MB[iMB].CS);

  262.     if (code != 0x02)//缓冲区没有接收到数据,返回错误
  263.     {
  264.         *Datalenght = 0;
  265.         return 1;
  266.     }
  267.     length = FLEXCAN_get_length(CANx->MB[iMB].CS);

  268.     if (length <1)//接收到的数据长度小于1,返回错误
  269.     {
  270.         *Datalenght = 0;
  271.         return 1;
  272.     }

  273.     //判断是标准帧还是扩展帧
  274.     format = (CANx->MB[iMB].CS & FLEXCAN_MB_CS_IDE)? 1:0;
  275.     *id = (CANx->MB[iMB].ID & FLEXCAN_MB_ID_EXT_MASK);

  276.     if (!format)
  277.     {
  278.         *id >>= FLEXCAN_MB_ID_STD_BIT_NO; // 获得标准帧号
  279.     }
  280.     else
  281.     {
  282.         *id |= CAN_MSG_IDE_MASK; //标记扩展的ID
  283.     }

  284.     format = (CANx->MB[iMB].CS & FLEXCAN_MB_CS_RTR)? 1:0;
  285.     if (format)
  286.     {
  287.         *id |= CAN_MSG_TYPE_MASK; //标记为远程帧类型
  288.     }
  289.     //读取报文数据
  290.     wno = (length-1)>>2;
  291.     bno = length-1;
  292.     if (wno>0)
  293.     {
  294.         (*(uint32_t*)pBytes) = CANx->MB[iMB].WORD0;
  295.         swap_4bytes(pBytes);
  296.         bno -= 4;
  297.         pMBData = (uint8_t*)&CANx->MB[iMB].WORD1+3;
  298.     }
  299.     else
  300.     {
  301.         pMBData = (uint8_t*)&CANx->MB[iMB].WORD0+3;
  302.     }

  303.     for (i=0; i <= bno; i++)
  304.         pBytes[i+(wno<<2)] = *pMBData--;

  305.     *Datalenght = length;
  306.     return 0;
  307. }

  308. //============================================================================
  309. //函数名称:EnableCANInterrupt
  310. //函数返回:无
  311. //参数说明:
  312. //          CANChannel:CAN模块号
  313. //                 iMB:缓冲区号
  314. //功能概要:使能缓冲区接收和发送中断
  315. //============================================================================
  316. void EnableCANInterrupt(uint8_t CANChannel,uint16_t iMB)
  317. {
  318.     CAN_Type *CANx;

  319.     if (CANChannel == 0)
  320.         CANx = CAN0;
  321.     else if (CANChannel == 1)
  322.         CANx = CAN1;

  323.     CANx->IMASK1 = (1<<iMB);
  324. }

  325. //============================================================================
  326. //函数名称:DisableCANInterrupt
  327. //函数返回:无
  328. //参数说明:
  329. //         CANChannel:CAN模块号
  330. //                iMB:缓冲区号
  331. //功能概要:禁止缓冲区接收和发送中断
  332. //============================================================================
  333. void DisableCANInterrupt(uint8_t CANChannel,uint16_t iMB)
  334. {
  335.     CAN_Type *CANx;

  336.     if (CANChannel == 0)
  337.         CANx = CAN0;
  338.     else if (CANChannel == 1)
  339.         CANx = CAN1;

  340.     CANx->IMASK1 &= ~CAN_IMASK1_BUFLM(iMB);
  341. }

  342. //============================================================================
  343. //函数名称:CANClearFlag
  344. //函数返回:无
  345. //参数说明:
  346. //        CANChannel:CAN模块号
  347. //               iMB:缓冲区号
  348. //功能概要:清缓冲区中断标志
  349. //============================================================================
  350. void CANClearFlag(uint8_t CANChannel,uint16_t iMB)
  351. {
  352.     CAN_Type *CANx;

  353.     if (CANChannel == 0)
  354.         CANx = CAN0;
  355.     else if (CANChannel == 1)
  356.         CANx = CAN1;

  357.     CANx->IFLAG1 = (1<<iMB);
  358. }
  359. //============================================================================
  360. //函数名称:CANGetFlag
  361. //函数返回:无
  362. //参数说明:
  363. //         CANChannel:CAN模块号
  364. //                iMB:缓冲区号
  365. //功能概要:获得缓冲区中断标志
  366. //============================================================================
  367. uint32_t CANGetFlag(uint8_t CANChannel,uint16_t iMB)
  368. {
  369.     CAN_Type *CANx;

  370.     if (CANChannel == 0)
  371.         CANx = CAN0;
  372.     else if (CANChannel == 1)
  373.         CANx = CAN1;

  374.     return (CANx->IFLAG1 & (1<<iMB));
  375. }
  376. //===========================内部函数=========================================
  377. //============================================================================
  378. //函数名称:SetCANBand
  379. //函数返回:0:配置成功 1:配置成功
  380. //参数说明:无
  381. //功能概要:设置CAN的波特率
  382. //============================================================================
  383. int SetCANBand(uint8_t CANChannel,uint32_t baudrateKHz)
  384. {
  385.     CAN_Type *CANx;

  386.     if (CANChannel == 0)
  387.         CANx = CAN0;
  388.     else if (CANChannel == 1)
  389.         CANx = CAN1;
  390.     switch (baudrateKHz)
  391.     {
  392.     case (33):        // 33.33K
  393.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  394.         {
  395.             // 48M/120= 400k sclock, 12Tq
  396.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  397.             // RJW = 3, PSEG1 = 4, PSEG2 = 4,PRESDIV = 120
  398.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  399.                            | CAN_CTRL1_RJW(2)
  400.                            | CAN_CTRL1_PSEG1(3)
  401.                            | CAN_CTRL1_PSEG2(3)
  402.                            | CAN_CTRL1_PRESDIV(119));
  403.         }
  404.         else
  405.         {
  406.             // 12M/20= 600k sclock, 18Tq
  407.             // PROPSEG = 1, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  408.             // RJW = 4, PSEG1 = 8, PSEG2 = 8,PRESDIV = 20
  409.             CANx->CTRL1 = (0  | CAN_CTRL1_PROPSEG(0)
  410.                            | CAN_CTRL1_PROPSEG(3)
  411.                            | CAN_CTRL1_PSEG1(7)
  412.                            | CAN_CTRL1_PSEG2(7)
  413.                            | CAN_CTRL1_PRESDIV(19));
  414.         }
  415.         break;
  416.     case (83):        // 83.33K
  417.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  418.         {
  419.             // 48M/48= 1M sclock, 12Tq
  420.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  421.             // RJW = 3, PSEG1 = 4, PSEG2 = 4,PRESDIV = 48
  422.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  423.                            | CAN_CTRL1_RJW(2)
  424.                            | CAN_CTRL1_PSEG1(3)
  425.                            | CAN_CTRL1_PSEG2(3)
  426.                            | CAN_CTRL1_PRESDIV(47));
  427.         }
  428.         else
  429.         {
  430.             // 12M/12= 1M sclock, 12Tq
  431.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  432.             // RJW = 3, PSEG1 = 4, PSEG2 = 4,PRESDIV = 12
  433.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  434.                            | CAN_CTRL1_RJW(2)
  435.                            | CAN_CTRL1_PSEG1(3)
  436.                            | CAN_CTRL1_PSEG2(3)
  437.                            | CAN_CTRL1_PRESDIV(11));
  438.         }
  439.         break;
  440.     case (50):
  441.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  442.         {
  443.             // 48M/80= 0.6M sclock, 12Tq
  444.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  445.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 40
  446.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  447.                            | CAN_CTRL1_RJW(1)
  448.                            | CAN_CTRL1_PSEG1(3)
  449.                            | CAN_CTRL1_PSEG2(3)
  450.                            | CAN_CTRL1_PRESDIV(79));
  451.         }
  452.         else
  453.         {
  454.             // 12M/20= 0.6M sclock, 12Tq
  455.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  456.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 20
  457.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  458.                            | CAN_CTRL1_RJW(2)
  459.                            | CAN_CTRL1_PSEG1(3)
  460.                            | CAN_CTRL1_PSEG2(3)
  461.                            | CAN_CTRL1_PRESDIV(19));
  462.         }
  463.         break;
  464.     case (100):
  465.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  466.         {
  467.             // 48M/40= 1.2M sclock, 12Tq
  468.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  469.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 40
  470.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  471.                            | CAN_CTRL1_RJW(2)
  472.                            | CAN_CTRL1_PSEG1(3)
  473.                            | CAN_CTRL1_PSEG2(3)
  474.                            | CAN_CTRL1_PRESDIV(39));
  475.         }
  476.         else
  477.         {
  478.             // 12M/10= 1.2M sclock, 12Tq
  479.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  480.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 10
  481.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  482.                            | CAN_CTRL1_RJW(2)
  483.                            | CAN_CTRL1_PSEG1(3)
  484.                            | CAN_CTRL1_PSEG2(3)
  485.                            | CAN_CTRL1_PRESDIV(9));
  486.         }
  487.         break;
  488.     case (125):
  489.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  490.         {
  491.             // 48M/32= 1.5M sclock, 12Tq
  492.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  493.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 32
  494.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  495.                            | CAN_CTRL1_RJW(2)
  496.                            | CAN_CTRL1_PSEG1(3)
  497.                            | CAN_CTRL1_PSEG2(3)
  498.                            | CAN_CTRL1_PRESDIV(31));
  499.         }
  500.         else
  501.         {
  502.             // 12M/8= 1.5M sclock, 12Tq
  503.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  504.             // RJW = 3, PSEG1 = 4, PSEG2 = 4, PRESDIV = 8
  505.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  506.                            | CAN_CTRL1_RJW(2)
  507.                            | CAN_CTRL1_PSEG1(3)
  508.                            | CAN_CTRL1_PSEG2(3)
  509.                            | CAN_CTRL1_PRESDIV(7));
  510.         }
  511.         break;
  512.     case (250):
  513.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  514.         {
  515.             // 48M/16= 3M sclock, 12Tq
  516.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  517.             // RJW = 2, PSEG1 = 4, PSEG2 = 4, PRESDIV = 16
  518.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  519.                            | CAN_CTRL1_RJW(1)
  520.                            | CAN_CTRL1_PSEG1(3)
  521.                            | CAN_CTRL1_PSEG2(3)
  522.                            | CAN_CTRL1_PRESDIV(15));
  523.         }
  524.         else
  525.         {
  526.             // 12M/4= 3M sclock, 12Tq
  527.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  528.             // RJW = 2, PSEG1 = 4, PSEG2 = 4, PRESDIV = 4
  529.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  530.                            | CAN_CTRL1_RJW(1)
  531.                            | CAN_CTRL1_PSEG1(3)
  532.                            | CAN_CTRL1_PSEG2(3)
  533.                            | CAN_CTRL1_PRESDIV(3));
  534.         }
  535.         break;
  536.     case (500):
  537.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  538.         {
  539.             // 60M/10=6M sclock, 12Tq
  540.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  541.             // RJW = 2, PSEG1 = 4, PSEG2 = 4, PRESDIV = 6
  542.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  543.                            | CAN_CTRL1_RJW(1)
  544.                            | CAN_CTRL1_PSEG1(3)
  545.                            | CAN_CTRL1_PSEG2(3)
  546.                            | CAN_CTRL1_PRESDIV(9));
  547.         }
  548.         else
  549.         {
  550.             // 12M/2=6M sclock, 12Tq
  551.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  552.             // RJW = 2, PSEG1 = 4, PSEG2 = 4, PRESDIV = 2
  553.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  554.                            | CAN_CTRL1_RJW(1)
  555.                            | CAN_CTRL1_PSEG1(3)
  556.                            | CAN_CTRL1_PSEG2(3)
  557.                            | CAN_CTRL1_PRESDIV(1));
  558.         }
  559.         break;
  560.     case (1000):
  561.         if (CANx->CTRL1 & CAN_CTRL1_CLKSRC_MASK)
  562.         {
  563.             // 48M/6=8M sclock
  564.             // PROPSEG = 4, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  565.             // RJW = 1, PSEG1 = 1, PSEG2 = 2, PRESCALER = 6
  566.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(3)
  567.                            | CAN_CTRL1_RJW(0)
  568.                            | CAN_CTRL1_PSEG1(0)
  569.                            | CAN_CTRL1_PSEG2(1)
  570.                            | CAN_CTRL1_PRESDIV(5));
  571.         }
  572.         else
  573.         {
  574.             // 12M/1=12M sclock,12Tq
  575.             // PROPSEG = 3, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 1
  576.             // RJW = 4, PSEG1 = 4, PSEG2 = 4, PRESCALER = 1
  577.             CANx->CTRL1 = (0 | CAN_CTRL1_PROPSEG(2)
  578.                            | CAN_CTRL1_RJW(3)
  579.                            | CAN_CTRL1_PSEG1(3)
  580.                            | CAN_CTRL1_PSEG2(3)
  581.                            | CAN_CTRL1_PRESDIV(0));
  582.         }
  583.         break;
  584.     default:
  585.         return 1;
  586.     }
  587.     return 0;
  588. }
复制代码

一周热门 更多>