×
单片机 > 其他资讯 > 详情

cubemx实现CAN通讯

发布时间:2020-07-10 发布时间:
|

首先要安装cubemx跟Keil5两个编程软件


然后打开cubemx软件,新建一个工程项目:

输入CPU型号:

在右下角双击CPU具体型号

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

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

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

使能看门狗

使能CAN

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

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

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

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

配置接收中断

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

配置定时器中断

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

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

选择生成代码的方式

等待

点击打开项目。代码生成部分完成。

添加一些特殊配置和逻辑代码


添加CAN的配置信息函数


void Can_Config(void)

{

  hcan.pTxMsg = &TxMessage;

  hcan.pRxMsg = &RxMessage;

 

  /*##-1- Configure CAN1 Transmission Massage #####################################*/

  hcan.pTxMsg->StdId = 0x123;

  hcan.pTxMsg->RTR = CAN_RTR_DATA;

  hcan.pTxMsg->IDE = CAN_ID_STD;

  hcan.pTxMsg->DLC = 8;

 

  /*##-2- Configure the CAN1 Filter ###########################################*/

  sFilterConfig.FilterNumber = 0;

  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

  sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;

  sFilterConfig.FilterIdHigh = 0;

  sFilterConfig.FilterIdLow = 0;

  sFilterConfig.FilterMaskIdHigh = 0;

  sFilterConfig.FilterMaskIdLow = 0;

  sFilterConfig.FilterFIFOAssignment = CAN_FIFO0;

  sFilterConfig.FilterActivation = ENABLE;

  sFilterConfig.BankNumber = 14;

  HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

}

 在Main函数中while(1)之前调用一下即可


添加定时器启动函数: HAL_TIM_Base_Start_IT(&htim2);


CAN接收中断启动函数:HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);


/* USER CODE BEGIN 2 */

 

Can_Config();                        //Can配置信息

HAL_TIM_Base_Start_IT(&htim2);       //定时器启动

HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//使能Can接收中断

 

  /* USER CODE END 2 */

 打开stm32f1xx_it.c文件,找到如下函数,


添加接收中断启动函数:HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);


注意:接收中断启动函数使能一次只进一次中断,所以中断退出前要再次使能。


void USB_LP_CAN1_RX0_IRQHandler(void)

{

  /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */

 

  /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */

  HAL_CAN_IRQHandler(&hcan);

  /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */

  HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//ʹÄÜCAN½ÓÊÕ

  /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */

}

添加CAN接收服务函数:HAL_CAN_RxCpltCallback


说明:该函数在stm32f1xx_hal_can.c文件中已经有定义,它的定义方式如下:


__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)


函数前面的__weak关键字意思是如果有同样的定义,先执行没有__weak关键字的函数,所以当我们定义了HAL_CAN_RxCpltCallback函数后,编译器会先编译我们定义的函数,而忽略系统定义的该函数。当我们没有定义该函数时,系统会编译带有__weak关键字的函数。


void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)

{

    unsigned short int speed;

    switch(hcan->pRxMsg->StdId)

    {//根据ID处理数据

        case 0x123://

        /*在此添加数据处理逻辑*/

        break;

        default:

        break;

     }

}

 添加CAN发送函数:


/* USER CODE BEGIN WHILE */

  while (1)

  {

        HAL_IWDG_Refresh(&hiwdg); //喂狗函数

 

        if(Can_Trans_Timer == 0)

        {//每100ms发送一次数据

            Can_Trans_Timer = 100;

            hcan.pTxMsg->StdId = 0x123;

 

            hcan.pTxMsg->Data[0] = 'C';

            hcan.pTxMsg->Data[1] = 'A';

            hcan.pTxMsg->Data[2] = 'N';

            hcan.pTxMsg->Data[3] = ' ';

            hcan.pTxMsg->Data[4] = 'T';

            hcan.pTxMsg->Data[5] = 'E';

            hcan.pTxMsg->Data[6] = 'S';

            hcan.pTxMsg->Data[7] = 'T';

            HAL_CAN_Transmit(&hcan, 200);//发送一帧数据

        }

    }

  /* USER CODE END WHILE */

在定时器函数中添加定时器代码:


void TIM2_IRQHandler(void)

{

  /* USER CODE BEGIN TIM2_IRQn 0 */

  if(Can_Trans_Timer > 0)          Can_Trans_Timer--;

  /* USER CODE END TIM2_IRQn 0 */

  HAL_TIM_IRQHandler(&htim2);

  /* USER CODE BEGIN TIM2_IRQn 1 */

  /* USER CODE END TIM2_IRQn 1 */

}

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


/* USER CODE BEGIN Includes */


添加用户代码


/* USER CODE END Includes */


/* USER CODE BEGIN PFP */


添加用户代码


/* USER CODE END PFP */


/* USER CODE BEGIN 0 */


添加用户代码


/* USER CODE END 0 */

 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
特色C语言平台u3000SoC设计最佳化(一)