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

【经验分享】STM32-CubeMX-实现CAN通讯

[复制链接]
STMCU小助手 发布时间:2022-6-26 11:29
  首先要安装cubemx跟Keil5两个编程软件,然后打开cubemx软件,新建一个工程项目:

微信图片_20220626112734.jpg

    输入CPU型号:

微信图片_20220626112737.jpg

    在右下角双击CPU具体型号:

微信图片_20220626112740.jpg

    稍等片刻会打开如下对话框:

微信图片_20220626112750.jpg

    首先要配置系统的调试方式:我们选择SW方式,

微信图片_20220626112755.jpg

    然后配置晶振源,这里选择的是外部晶振,8M,

微信图片_20220626112758.jpg

    使能看门狗,

微信图片_20220626112805.jpg

    使能CAN,

微信图片_20220626112810.jpg

    使能TIM2时钟源,采用内部时钟,

微信图片_20220626112817.jpg

    配置完成后可以看到单片机管脚已经做了配置。

微信图片_20220626112826.png

    切换到Clock Configuration选项卡,配置时钟周期,这里配置为8M

微信图片_20220626112835.png

    切换到Configuration选项卡,进入CAN配置选项配置波特率如下为500Kbps。

微信图片_20220626112838.png

    配置接收中断。

微信图片_20220626112842.png

    配置定时器如下为1ms定时器。

微信图片_20220626112845.png

    配置定时器中断

微信图片_20220626112847.png

    配置完成后点击保存,然后点击如下按钮,生成代码

微信图片_20220626112850.png

    填写工程名称,路径,编程软件等等

微信图片_20220626112853.png

    选择生成代码的方式

微信图片_20220626112857.png

    等待……
    之后点击打开项目。代码生成部分完成。

微信图片_20220626112901.png

    添加一些特殊配置和逻辑代码,添加CAN的配置信息函数。
  1. void Can_Config(void)
  2. {
  3.   hcan.pTxMsg = &TxMessage;
  4.   hcan.pRxMsg = &RxMessage;

  5.   /*##-1- Configure CAN1 Transmission Massage #####################################*/
  6.   hcan.pTxMsg->StdId = 0x123;
  7.   hcan.pTxMsg->RTR = CAN_RTR_DATA;
  8.   hcan.pTxMsg->IDE = CAN_ID_STD;
  9.   hcan.pTxMsg->DLC = 8;

  10.   /*##-2- Configure the CAN1 Filter ###########################################*/
  11.   sFilterConfig.FilterNumber = 0;
  12.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  13.   sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
  14.   sFilterConfig.FilterIdHigh = 0;
  15.   sFilterConfig.FilterIdLow = 0;
  16.   sFilterConfig.FilterMaskIdHigh = 0;
  17.   sFilterConfig.FilterMaskIdLow = 0;
  18.   sFilterConfig.FilterFIFOAssignment = CAN_FIFO0;
  19.   sFilterConfig.FilterActivation = ENABLE;
  20.   sFilterConfig.BankNumber = 14;
  21.   HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
  22. }
复制代码

在Main函数中while(1)之前调用一下即可,添加定时器启动函数:
  1. HAL_TIM_Base_Start_IT(&htim2);
复制代码

    CAN接收中断启动函数:
  1. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
  2. /* USER CODE BEGIN 2 */

  3. Can_Config();                        //Can配置信息
  4. HAL_TIM_Base_Start_IT(&htim2);       //定时器启动
  5. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//使能Can接收中断

  6.   /* USER CODE END 2 */
复制代码

    打开stm32f1xx_it.c文件,找到如下函数,添加接收中断启动函数:
  1. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
复制代码

    注意:接收中断启动函数使能一次只进一次中断,所以中断退出前要再次使能。
  1. void USB_LP_CAN1_RX0_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */

  4.   /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */
  5.   HAL_CAN_IRQHandler(&hcan);
  6.   /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
  7.   HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//ʹÄÜCAN½ÓÊÕ
  8.   /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
  9. }
复制代码

添加CAN接收服务函数:
  1. HAL_CAN_RxCpltCallback
复制代码

    说明:该函数在stm32f1xx_hal_can.c文件中已经有定义,它的定义方式如下:
  1. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
复制代码

    函数前面的__weak关键字意思是如果有同样的定义,先执行没有__weak关键字的函数,所以当我们定义了HAL_CAN_RxCpltCallback函数后,编译器会先编译我们定义的函数,而忽略系统定义的该函数。当我们没有定义该函数时,系统会编译带有__weak关键字的函数。
  1. void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  2. {
  3.     unsigned short int speed;
  4.     switch(hcan->pRxMsg->StdId)
  5.     {//根据ID处理数据
  6.         case 0x123://
  7.         /*在此添加数据处理逻辑*/
  8.         break;
  9.         default:
  10.         break;
  11.      }
  12. }
复制代码

添加CAN发送函数:
  1. /* USER CODE BEGIN WHILE */
  2.   while (1)
  3.   {
  4.         HAL_IWDG_Refresh(&hiwdg); //喂狗函数

  5.         if(Can_Trans_Timer == 0)
  6.         {//每100ms发送一次数据
  7.             Can_Trans_Timer = 100;


  8.             hcan.pTxMsg->StdId = 0x123;

  9.             hcan.pTxMsg->Data[0] = 'C';
  10.             hcan.pTxMsg->Data[1] = 'A';
  11.             hcan.pTxMsg->Data[2] = 'N';
  12.             hcan.pTxMsg->Data[3] = ' ';
  13.             hcan.pTxMsg->Data[4] = 'T';
  14.             hcan.pTxMsg->Data[5] = 'E';
  15.             hcan.pTxMsg->Data[6] = 'S';
  16.             hcan.pTxMsg->Data[7] = 'T';


  17.             HAL_CAN_Transmit(&hcan, 200);//发送一帧数据
  18.         }
  19.     }
  20.   /* USER CODE END WHILE */
复制代码

在定时器函数中添加定时器代码:
  1. void TIM2_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN TIM2_IRQn 0 */
  4.   if(Can_Trans_Timer > 0)          Can_Trans_Timer--;
  5.   /* USER CODE END TIM2_IRQn 0 */
  6.   HAL_TIM_IRQHandler(&htim2);
  7.   /* USER CODE BEGIN TIM2_IRQn 1 */


  8.   /* USER CODE END TIM2_IRQn 1 */
  9. }
复制代码

    说明:在往工程中添加代码时要注意,不要任意往里面添加代码,要在注释着USER CODE BEGIN的地方添加代码,这样在重新生成代码时才不至于将已经写好的代码覆盖掉,如下
  1. /* USER CODE BEGIN Includes */
复制代码

收藏 评论0 发布时间:2022-6-26 11:29

举报

0个回答

所属标签

相似分享

官网相关资源

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