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

STM32-CubeMX-实现CAN通讯

[复制链接]
STMCU 发布时间:2020-10-19 13:07
STM32-CubeMX-实现CAN通讯


首先要安装cubemx跟Keil5两个编程软件,然后打开cubemx软件,新建一个工程项目:
11.png
    输入CPU型号:
12.png
    在右下角双击CPU具体型号:
13.png
    稍等片刻会打开如下对话框:
14.png
    首先要配置系统的调试方式:我们选择SW方式,
15.png
    然后配置晶振源,这里选择的是外部晶振,8M,
16.png
    使能看门狗,
17.png
    使能CAN,
18.png
    使能TIM2时钟源,采用内部时钟,
19.png
    配置完成后可以看到单片机管脚已经做了配置。
20.png
    切换到Clock Configuration选项卡,配置时钟周期,这里配置为8M
21.png
    切换到Configuration选项卡,进入CAN配置选项配置波特率如下为500Kbps。
22.png
    配置接收中断。
23.png
    配置定时器如下为1ms定时器。
24.png
    配置定时器中断
25.png
    配置完成后点击保存,然后点击如下按钮,生成代码
26.png
    填写工程名称,路径,编程软件等等
27.png
    选择生成代码的方式
28.png
    等待……
    之后点击打开项目。代码生成部分完成。
29.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 */
复制代码














收藏 3 评论1 发布时间:2020-10-19 13:07

举报

1个回答
g921002 回答时间:2020-10-20 22:50:40
新版的HAL已經不是這樣寫了。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版