找回密码
 立即注册

只需一步,快速开始

搜索

【FM33LG0系列开发板测评】CAN

0
回复
4666
查看
[复制链接]

166

主题

343

帖子

3076

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3076
QQ
2022-1-7 16:38:55 显示全部楼层 |阅读模式
【FM33LG0系列开发板测评】CAN


原帖地址:【FM33LG0系列开发板测评】06.CAN - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

1、简介
FM33LG048带有一路CNA(控制器区域网络)接口,支持CAN 2.0A和CAN 2.0B标准,支持11位的标准ID和29位的扩展ID;最高传输速率可以达到1Mbps,同时具有2个发送FIFO、2个接收FIFO和4个接收滤波器;在总线错误或者传输仲裁失败的情况下,还支持自动重发的功能。

FM33LG0xx DEMO V1.1开发板上将FM33LG048的CAN接口通过排针的形式接出来了,分别是PD10(CAN_RX)、PE9(CAN_TX),对应开发板上的J17这个接口;

FM33LG048的CAN时钟源有多种选择:RCHF、XTHF、PLL、APBCLK;选择哪一个时钟源是可以通过软件来配置的;为了提高通讯速率的精准度,使用的时钟频率需要满足ISO11898-1规定的容差范围,本例程中使用了XTHF外部晶振作为CAN的时钟源,所以在初始化CAN配置参数的时候,需要先配置XTHF使能。


2、软件功能
使用XTHF外部晶振作为CAN的时钟源,将CAN的通讯速率配置为100kbps,程序中每间隔500ms向CAN总线上发送一条测试数据;开启CAN接收中断,在有接收到新数据时,通过串口打印出CAN收到的数据信息;


3、实现代码

  1. /*******************************************************************************
  2. * @file    CAN.c
  3. * @author  King
  4. * @version V1.00
  5. * @date 27-Nov-2021
  6. * @brief ......
  7. *******************************************************************************/


  8. /* Define to prevent recursive inclusion -------------------------------------*/
  9. #define __CAN_C__


  10. /* Includes ------------------------------------------------------------------*/
  11. #include "CAN.h"


  12. #if CAN_ENABLE


  13. /* Private typedef -----------------------------------------------------------*/
  14. /* Private define ------------------------------------------------------------*/
  15. /* Private macro -------------------------------------------------------------*/
  16. /* Private variables ---------------------------------------------------------*/
  17. /* Private function prototypes -----------------------------------------------*/
  18. /* Private functions ---------------------------------------------------------*/


  19. /* Exported variables --------------------------------------------------------*/
  20. /* Exported function prototypes ----------------------------------------------*/


  21. /*******************************************************************************
  22. * @brief      
  23. * @param      
  24. * @retval      
  25. * @attention *******************************************************************************/
  26. void CAN_Configure(void)
  27. {
  28.     FL_GPIO_InitTypeDef      GPIO_InitStruct;
  29.     FL_CAN_InitTypeDef       CAN_InitStruct;
  30.     FL_CAN_FilterInitTypeDef CAN_FilterInitStruct;

  31.     //---Enable XTHF For CAN Clock Source
  32.     FL_GPIO_StructInit(&GPIO_InitStruct);
  33.     GPIO_InitStruct.pin        = FL_GPIO_PIN_2 | FL_GPIO_PIN_3;
  34.     GPIO_InitStruct.mode       = FL_GPIO_MODE_ANALOG;
  35.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  36.     FL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  37.     FL_CMU_XTHF_Enable();
  38.     FL_CMU_XTHF_WriteDriverStrength(0x1F);
  39.     FL_DelayMs(3);


  40.     FL_GPIO_StructInit(&GPIO_InitStruct);
  41.     GPIO_InitStruct.pin        = FL_GPIO_PIN_9;
  42.     GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
  43.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  44.     GPIO_InitStruct.pull       = FL_ENABLE;
  45.     FL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  46.     FL_GPIO_StructInit(&GPIO_InitStruct);
  47.     GPIO_InitStruct.pin        = FL_GPIO_PIN_10;
  48.     GPIO_InitStruct.mode       = FL_GPIO_MODE_DIGITAL;
  49.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  50.     GPIO_InitStruct.pull       = FL_ENABLE;
  51.     FL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  52.     /* CAN Baudrate = CAN_CLK / (BRP + 1) / (TS1 + TS2 + 1) */
  53.     FL_CAN_StructInit(&CAN_InitStruct);
  54.     CAN_InitStruct.mode        = FL_CAN_MODE_NORMAL;
  55.     CAN_InitStruct.BRP         = 7;
  56.     CAN_InitStruct.clockSource = FL_CMU_CAN_CLK_SOURCE_XTHF;
  57.     CAN_InitStruct.SJW         = FL_CAN_SJW_1Tq;
  58.     CAN_InitStruct.TS1         = FL_CAN_TS1_5Tq;
  59.     CAN_InitStruct.TS2         = FL_CAN_TS2_4Tq;
  60.     FL_CAN_Init(CAN, &CAN_InitStruct);

  61.     FL_CAN_StructFilterInit(&CAN_FilterInitStruct);
  62.     CAN_FilterInitStruct.filterIdStandard = 0x6AD;
  63.     CAN_FilterInitStruct.filterIdSRR      = 0;
  64.     CAN_FilterInitStruct.filterIdIDE      = 0;
  65.     CAN_FilterInitStruct.filterIdRTR      = 0;

  66.     CAN_FilterInitStruct.filterMaskIdHigh = 0x7FF;
  67.     CAN_FilterInitStruct.filterMaskIdSRR  = 0x01;
  68.     CAN_FilterInitStruct.filterMaskIdIDE  = 0x01;
  69.     CAN_FilterInitStruct.filterMaskIdRTR  = 0x01;
  70.     CAN_FilterInitStruct.filterEn         = FL_ENABLE;
  71.     FL_CAN_FilterInit(CAN, &CAN_FilterInitStruct, FL_CAN_FILTER1);

  72.     FL_CAN_ClearFlag_CRXOK(CAN);
  73.     FL_CAN_EnableIT_RXOK(CAN);

  74.     NVIC_DisableIRQ(CAN_IRQn);
  75.     NVIC_SetPriority(CAN_IRQn, 2);
  76.     NVIC_EnableIRQ(CAN_IRQn);

  77.     TASK_Append(TASK_ID_CAN, CAN_Handler, 500);
  78. }


  79. /*******************************************************************************
  80. * @brief      
  81. * @param      
  82. * @retval      
  83. * @attention   
  84. *******************************************************************************/
  85. void FL_CAN_FIFO_Write(uint32_t ID, uint32_t Length, uint32_t Data1, uint32_t Data2)
  86. {
  87.     uint32_t Timeout = 5;

  88.     while((FL_CAN_IsActiveFlag_TXBuffFull(CAN) != FL_RESET) & Timeout)
  89.     {
  90.         Timeout--;
  91.         FL_DelayMs(1);
  92.     }

  93.     FL_CAN_WriteTXMessageID(CAN, ID);
  94.     FL_CAN_WriteTXMessageLength(CAN, Length);
  95.     FL_CAN_WriteTXMessageWord1(CAN, Data1);
  96.     FL_CAN_WriteTXMessageWord2(CAN, Data2);
  97. }


  98. /*******************************************************************************
  99. * @brief      
  100. * @param      
  101. * @retval      
  102. * @attention   
  103. *******************************************************************************/
  104. void FL_CAN_HPBUF_Write(uint32_t ID, uint32_t Length, uint32_t Data1, uint32_t Data2)
  105. {
  106.     uint32_t Timeout = 5;

  107.     while((FL_CAN_IsActiveFlag_TXHighPriorBuffFull(CAN) != FL_RESET) & Timeout)
  108.     {
  109.         Timeout--;
  110.         FL_DelayMs(1);
  111.     }

  112.     FL_CAN_WriteHighPriorTXMessageID(CAN, ID);
  113.     FL_CAN_WriteHighPriorMessageLength(CAN, Length);
  114.     FL_CAN_WriteHighPriorMessageWord1(CAN, Data1);
  115.     FL_CAN_WriteHighPriorMessageWord2(CAN, Data2);
  116. }


  117. /*******************************************************************************
  118. * @brief      
  119. * @param      
  120. * @retval      
  121. * @attention   
  122. *******************************************************************************/
  123. void FL_CAN_Receive(void)
  124. {
  125.     uint32_t Data1 = 0;
  126.     uint32_t Data2 = 0;

  127.     CAN_MSG_TypeDef RxMessage;

  128.     RxMessage.StdId = FL_CAN_ReadRXMessageID(CAN);
  129.     RxMessage.DLC   = FL_CAN_ReadRXMessageLength(CAN);

  130.     Data1 = FL_CAN_ReadRXMessageWord1(CAN);
  131.     Data2 = FL_CAN_ReadRXMessageWord2(CAN);

  132.     RxMessage.Data[0] = (uint8_t)(Data1 >> 0x00) & 0xFF;
  133.     RxMessage.Data[1] = (uint8_t)(Data1 >> 0x08) & 0xFF;
  134.     RxMessage.Data[2] = (uint8_t)(Data1 >> 0x10) & 0xFF;
  135.     RxMessage.Data[3] = (uint8_t)(Data1 >> 0x18) & 0xFF;
  136.     RxMessage.Data[4] = (uint8_t)(Data2 >> 0x00) & 0xFF;
  137.     RxMessage.Data[5] = (uint8_t)(Data2 >> 0x08) & 0xFF;
  138.     RxMessage.Data[6] = (uint8_t)(Data2 >> 0x10) & 0xFF;
  139.     RxMessage.Data[7] = (uint8_t)(Data2 >> 0x18) & 0xFF;

  140.     printf("\r\nCAN Receive : 0x%x, %d, ", RxMessage.StdId, RxMessage.DLC);

  141.     for(uint32_t i = 0; i < 8; i++)
  142.     {
  143.         printf("%02x ", RxMessage.Data);

  144.     }

  145.     printf("\r\n");
  146. }


  147. /*******************************************************************************
  148. * @brief      
  149. * @param      
  150. * @retval      
  151. * @attention   
  152. *******************************************************************************/
  153. void FL_CAN_Transmit(uint32_t FrameFormat, CAN_MSG_TypeDef *TxMessage)
  154. {
  155.     uint32_t ID     = 0;
  156.     uint32_t Length = 0;
  157.     uint32_t Data1 = 0;
  158.     uint32_t Data2 = 0;

  159.     if(FrameFormat == FL_CAN_FORMAT_STANDARD_DATA)
  160.     {
  161.         ID = TxMessage->StdId & 0x7FF;
  162.     }

  163.     else if(FrameFormat == FL_CAN_FORMAT_STANDARD_REMOTE)
  164.     {
  165.         ID = (TxMessage->StdId & 0x7FF) | (1 << 11);
  166.     }

  167.     else if(FrameFormat == FL_CAN_FORMAT_EXTEND_DATA)
  168.     {
  169.         ID = ((TxMessage->ExtId & 0x3FFFF) << 13) |
  170.              ((uint32_t)1 << 12)                  |
  171.              ((uint32_t)1 << 11)                  |
  172.              ((TxMessage->ExtId & 0x1FFC0000) >> 18);
  173.     }

  174.     else if(FrameFormat == FL_CAN_FORMAT_EXTEND_REMOTE)
  175.     {
  176.         ID = ((TxMessage->ExtId & 0x3FFFF) << 13) |
  177.              ((uint32_t)1 << 12)                  |
  178.              ((uint32_t)1 << 31)                  |
  179.              ((TxMessage->ExtId & 0x1FFC0000) >> 18);
  180.     }


  181.     Length = TxMessage->DLC;

  182.     Data1 = ((uint32_t)TxMessage->Data[3] << 0x18) |
  183.             ((uint32_t)TxMessage->Data[2] << 0x10) |
  184.             ((uint32_t)TxMessage->Data[1] << 0x08) |
  185.             ((uint32_t)TxMessage->Data[0] << 0x00);

  186.     Data2 = ((uint32_t)TxMessage->Data[7] << 0x18) |
  187.             ((uint32_t)TxMessage->Data[6] << 0x10) |
  188.             ((uint32_t)TxMessage->Data[5] << 0x08) |
  189.             ((uint32_t)TxMessage->Data[4] << 0x00);

  190. #if 1
  191.     FL_CAN_FIFO_Write(ID, Length, Data1, Data2);
  192. #else
  193.     FL_CAN_HPBUF_Write(ID, Length, Data1, Data2);
  194. #endif
  195. }


  196. /*******************************************************************************
  197. * @brief      
  198. * @param      
  199. * @retval      
  200. * @attention   
  201. *******************************************************************************/
  202. void CAN_Handler(void)
  203. {
  204.     CAN_MSG_TypeDef TxMessage;

  205.     TxMessage.StdId = 0x6AD;
  206.     TxMessage.DLC   = 8;

  207.     for(uint8_t i = 0; i < TxMessage.DLC; i++)
  208.     {
  209.         TxMessage.Data = i;
  210.     }

  211.     FL_CAN_Transmit(FL_CAN_FORMAT_STANDARD_DATA, &TxMessage);
  212. }


  213. /*******************************************************************************
  214. * @brief      
  215. * @param      
  216. * @retval      
  217. * @attention   
  218. *******************************************************************************/
  219. void CAN_IRQHandler(void)
  220. {
  221.     if((FL_ENABLE == FL_CAN_IsEnabledIT_RXOK(CAN)) &&
  222.        (FL_SET    == FL_CAN_IsActiveFlag_RXOK(CAN)))
  223.     {
  224.         FL_CAN_Receive();
  225.         FL_CAN_ClearFlag_CRXOK(CAN);
  226.     }
  227. }


  228. #endif


  229. /******************* (C) COPYRIGHT 2021 *************************END OF FILE***/

复制代码

4、调试运行

由于开发板本身没有带有CAN收发器,所以我们在进行CAN实验的时候,需要外接一个CAN收发模块;本实验选用的VP230这个芯片,支持与MCU相同的3.3V工作电压;另外再连接一个CAN调试工具,与PC端的软件进行配合,查看CAN总线上传输的数据、或者是向CAN总线上发送测试数据等操作。

4.1.硬件连线

3333.jpg

4.2.监测数据

1111.png

4.3.接收数据

2222.png

5、工程源码

Project_CAN.zip (382.16 KB, 下载次数: 206)

回复

使用道具 举报

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

返回顶部