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

【经验分享】STMCubeMX5.10版本CAN使用loopback模式自测

[复制链接]
STMCU小助手 发布时间:2022-7-3 16:00
使用芯片:STM32F103C8T6
cube软件版本:5.10
软件包版本为:STM32Cube FW_F1 V1.7.0

一、配置时钟为使用外部晶振,并配置为72M

DPXOW_XWCY6~5{2@@6@VW00.png
8CJFP6GSDY$CCX{NZ{34[8C.png

二、使能 can,并配置参数
设置can波特率为500k,并设置为loopback模式,波特率计算方式为(systime/(pre*(bs1+bs2+sjw))),can时钟为36M,则36/(12*(1+2+3))=500k。

@RN)FK9600GT_B~R05H@6$K.png

三、开启can接收中断

XQF]BS53B8JK8]K}Q$(RIEX.png

四、设置生成代码,在生成的can.c函数中增加过滤器配置代码如下


FD$(BEU3L~X](9N9YO3)B[G.png

CAN_FilterIdHigh和CAN_FilterIdLow组合成一个32位寄存器,用来存储将要过滤的ID

CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow组合成一个32位寄存器,用来表示这个ID的哪些位必须符合(置1),哪些位不关心(置0).
例如要过滤的ID为0x1e000000,则CAN_FilterIdHigh、CAN_FilterIdLow、CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow配置为

  1. uint32_t EXTID = 0x1e000000;
  2. CAN_FilterType.FilterIdHigh=(EXTID<<3)>>16;
  3. CAN_FilterType.FilterIdLow=((EXTID<<3)&0xffff)|CAN_ID_EXT;//只关心扩展帧,标准帧为CAN_ID_STD
  4. CAN_FilterType.FilterMaskIdHigh=0xffff;
  5. CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;//每一位都必须一致,只关心扩展帧,标准帧为CAN_ID_STD
复制代码

以下配置代码,有列表模式和掩码模式,二选一

  1. /* 列表模式只接受0x02200000和0x1e000000 */
  2. void CAN1_IDLISTConfig(void)
  3. {
  4.         uint32_t EXTID = 0x02200000;
  5.         uint32_t EXTID1 = 0x1e000000;
  6.         CAN_FilterTypeDef CAN_FilterType;
  7.         CAN_FilterType.FilterBank=0;
  8.         CAN_FilterType.FilterIdHigh=(EXTID<<3)>>16;
  9.         CAN_FilterType.FilterIdLow=((EXTID<<3)&0xffff)|CAN_ID_EXT;
  10.         CAN_FilterType.FilterMaskIdHigh=0xffff;
  11.         CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;
  12.         CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;
  13.         CAN_FilterType.FilterMode=CAN_FILTERMODE_IDLIST;
  14.         CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
  15.         CAN_FilterType.FilterActivation=ENABLE;
  16.         CAN_FilterType.SlaveStartFilterBank=14;
  17.         if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
  18.         {
  19.                 Error_Handler();
  20.         }
  21.         CAN_FilterType.FilterBank=1;
  22.         CAN_FilterType.FilterIdHigh=(EXTID1<<3)>>16;
  23.         CAN_FilterType.FilterIdLow=((EXTID1<<3)&0xffff)|CAN_ID_EXT;
  24.         CAN_FilterType.FilterMaskIdHigh=0xffff;
  25.         CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;
  26.         CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;
  27.         CAN_FilterType.FilterMode=CAN_FILTERMODE_IDLIST;//列表模式
  28.         CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
  29.         CAN_FilterType.FilterActivation=ENABLE;
  30.         CAN_FilterType.SlaveStartFilterBank=14;
  31.         if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
  32.         {
  33.                 Error_Handler();
  34.         }
  35.         if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
  36.         {
  37.                 Error_Handler();
  38.         }
  39.         if(HAL_CAN_Start(&hcan)!=HAL_OK)
  40.         {
  41.                 Error_Handler();
  42.         }
  43. }
  44. /* 掩码模式全部接收 */
  45. void CAN1_IDMASKConfig(void)
  46. {
  47.            CAN_FilterTypeDef CAN_FilterType;
  48.            CAN_FilterType.FilterBank=0;
  49.            CAN_FilterType.FilterIdHigh=0x0000;
  50.            CAN_FilterType.FilterIdLow=0x0000;
  51.            CAN_FilterType.FilterMaskIdHigh=0x0000;
  52.            CAN_FilterType.FilterMaskIdLow=0x0000;
  53.            CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;
  54.            CAN_FilterType.FilterMode=CAN_FILTERMODE_IDMASK;//掩码模式
  55.            CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
  56.            CAN_FilterType.FilterActivation=ENABLE;
  57.            CAN_FilterType.SlaveStartFilterBank=14;
  58.            if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
  59.            {
  60.                    Error_Handler();
  61.            }
  62.            if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
  63.            {
  64.                    Error_Handler();
  65.            }
  66.            if(HAL_CAN_Start(&hcan)!=HAL_OK)
  67.            {
  68.                    Error_Handler();
  69.            }
  70. }
复制代码

五、增加can发送函数
  1. /***********************************************
  2.     函数功能:can发送数据
  3.     入口参数:
  4.                             ide:        0:标准帧
  5.                                             1:扩展帧
  6.                             id:        帧ID
  7.                             len:        数据长度
  8.                             data:        数据
  9.     返回值:0:成功。1:失败
  10.     ************************************************/
  11.     uint8_t Can_TxMessage(uint8_t ide,uint32_t id,uint8_t len,uint8_t *data)
  12.     {
  13.             uint32_t   TxMailbox;
  14.             CAN_TxHeaderTypeDef CAN_TxHeader;
  15.             HAL_StatusTypeDef   HAL_RetVal;
  16.             uint16_t i=0;
  17.             if(ide == 0)
  18.             {
  19.                     CAN_TxHeader.IDE = CAN_ID_STD;        //标准帧
  20.                     CAN_TxHeader.StdId = id;
  21.             }
  22.             else
  23.             {
  24.                     CAN_TxHeader.IDE = CAN_ID_EXT;                        //扩展帧
  25.                     CAN_TxHeader.ExtId = id;
  26.             }
  27.             CAN_TxHeader.DLC = len;
  28.             CAN_TxHeader.RTR = CAN_RTR_DATA;//数据帧,CAN_RTR_REMOTE遥控帧
  29.             CAN_TxHeader.TransmitGlobalTime = DISABLE;
  30.             while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)
  31.             {
  32.                     i++;
  33.                     if(i>0xfffe)
  34.                             return 1;
  35.             }
  36.             HAL_Delay(500);
  37.             HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&CAN_TxHeader,data,&TxMailbox);
  38.             if(HAL_RetVal != HAL_OK)
  39.                     return 1;
  40.             return 0;
  41.     }
复制代码

六、增加接收中断回调函数
  1. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
  2.     {
  3.             CAN_RxHeaderTypeDef CAN_RxHeader;
  4.             HAL_StatusTypeDef HAL_Retval;
  5.             uint8_t Rx_Data[8];
  6.             uint8_t Data_Len=0;
  7.             uint32_t ID=0;
  8.             uint8_t i;
  9.             HAL_Retval = HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&CAN_RxHeader,Rx_Data);
  10.             if(HAL_Retval == HAL_OK)
  11.             {
  12.                     Data_Len = CAN_RxHeader.DLC;
  13.                     if(CAN_RxHeader.IDE)
  14.                             ID = CAN_RxHeader.ExtId;
  15.                     else
  16.                             ID = CAN_RxHeader.StdId;
  17.                     printf("id:%x\r\n",ID);
  18.                     printf("Data_Len:%d\r\n",Data_Len);
  19.                     for(i=0;i<8;i++)
  20.                             printf("Rx_Data[%d]=%x\r\n",i,Rx_Data<i>);        
  21.             }
  22.     }</i>
复制代码


七,在main.c函数中增加函数,最终如下:

  1. int main(void)
  2.     {
  3.       /* USER CODE BEGIN 1 */
  4.             uint8_t data[8]={1,2,3,4,5,6,7,8};
  5.       /* USER CODE END 1 */

  6.       /* MCU Configuration--------------------------------------------------------*/

  7.       /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  8.       HAL_Init();

  9.       /* USER CODE BEGIN Init */

  10.       /* USER CODE END Init */

  11.       /* Configure the system clock */
  12.       SystemClock_Config();

  13.       /* USER CODE BEGIN SysInit */

  14.       /* USER CODE END SysInit */

  15.       /* Initialize all configured peripherals */
  16.       MX_GPIO_Init();
  17.       MX_CAN_Init();
  18.       MX_USART1_UART_Init();
  19.       /* USER CODE BEGIN 2 */
  20.             CAN1_IDMASKConfig();//过滤器配置
  21.       /* USER CODE END 2 */
  22.       /* Infinite loop */
  23.       /* USER CODE BEGIN WHILE */
  24.       while (1)
  25.       {
  26.         /* USER CODE END WHILE */

  27.         /* USER CODE BEGIN 3 */
  28.               Can_TxMessage(0,0x222,8,data);//CAN发送
  29.               HAL_Delay(1000);
  30.       }
  31.       /* USER CODE END 3 */
  32.     }
复制代码

每隔1S,通过can向标识符为0x222的设备发送一次数据,因为本例程设置的为loopback模式,所以不需要接任何外设即可,通过串口调试助手查看接收到的数据,与发送数据相符



V$YJS[W1Z]9LB(@}N~5F@1H.png
收藏 评论0 发布时间:2022-7-3 16:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版