STM32 HAL库 串口中断接收数据包

这篇具有很好参考价值的文章主要介绍了STM32 HAL库 串口中断接收数据包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、CUBEmx配置

1.设置系统时钟,配置SYS,配置时钟树

 ​编辑

 2.配置串口USART1

3.配置NVIC,开启串口中断

​编辑4.点击GENERATE CODE输出文件即可

二、代码部分

0.串口重定向——printf

1.关于舵机

2.开启串口中断函数

3.编写串口回调函数

4.主函数部分

三、实验现象:

四、总结


 文章来源地址https://www.toymoban.com/news/detail-765443.html

        刚从标准库转到HAL学习,最近需要做一个机械臂控制,打算用USART1串口中断的方式控制四个舵机运行,现在记录一下过程,主控使用STM32F103ZET6。(本文只讲中断的接收,舵机控制暂时不涉及)

一、CUBEmx配置

1.设置系统时钟,配置SYS,配置时钟树

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

 

 2.配置串口USART1

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

3.配置NVIC,开启串口中断

这里我将中断的优先级设置为12(单独学习串口中断并不需要修改优先级配置,按照0级即可)

4.点击GENERATE CODE输出文件即可

二、代码部分

我使用CLION进行编写,使用keil的方式也是一样的。

0.串口重定向——printf

在用户自定义区加上如下代码即可使用:

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

1.关于舵机

舵机使用了两个180°舵机和两个270°舵机,由于uint8_t最大到255,所以打算使用两个八位去存储舵机旋转的角度。

数据包采用如下形式,通过定义一个数组去存放数据包

uint8_t Rx_data[5];//数据包加上包头一共5个byte
uint8_t Rx_flag=0;//设置一个中断完成的标志位

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

2.开启串口中断函数

  HAL_UART_Receive_IT(&huart1,(uint8_t*)Rx_data,5);//开启串口接收中断函数

函数的三个参数,第一个指定是USART1的串口中断,第二个参数指定接受数据的位置,第三个指定数据接收的长度,当串口接收到5个字节的数据时,才会触发中断回调函数。 

3.编写串口回调函数

回调函数仅仅负责将接受完成的标志位置1,处理工作再主函数while循环中进行。 

 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance==USART1)//首先判断是否是USART1触发的中断
    {
        Rx_flag=1;
    }
}

4.主函数部分

首先判断标志位,即是否接受完5个字节的数据,判断完成后,先将标志位即Rx_flag清零,否则会一直卡在主循环中,接着开启下一次的串口中断。

 if(Rx_flag==1)
      {
          Rx_flag=0;
          HAL_UART_Receive_IT(&huart1,(uint8_t*)Rx_data,5);
  
       }

接着就是对数据包中的数据进行解析了:

1.首先判断包头包尾是否满足协议规范。然后在处理里面的数据:这里我通过switch语句对舵机的ID进行判断:0x01-0x04代表着四个舵机。

2.关于度数的转换:angle=Rx_data[2] * 256 + Rx_data[3],即高位为Rx_data[2] ,低位为Rx_data[3]。

switch (Rx_data[1]) {
                  case 0x01: {
                      printf("Servo_1 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x02: {
                      printf("Servo_2 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x03: {
                      printf("Servo_3 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x04: {
                      printf("Servo_4 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  default:
                      printf("data_error!");
              }

 3.处理完数据后需要把Rx_data[]中的值全部清零以便下一次的接收:

          for (int i = 0; i < 5; ++i) {
              Rx_data[i]=0;
          }

4.主循环全部函数

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      if(Rx_flag==1)
      {
          Rx_flag=0;
          HAL_UART_Receive_IT(&huart1,(uint8_t*)Rx_data,5);
          if(Rx_data[0]==0xaa&&Rx_data[4]==0xff) {
              switch (Rx_data[1]) {
                  case 0x01: {
                      printf("Servo_1 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x02: {
                      printf("Servo_2 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x03: {
                      printf("Servo_3 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  case 0x04: {
                      printf("Servo_4 turn\r\n");
                      printf("angle=%d\r\n", Rx_data[2] * 256 + Rx_data[3]);
                  }
                      break;
                  default:
                      printf("data_error!");
              }
          }
          else
          {
              printf("Data——error!\r\n");
          }
          for (int i = 0; i < 5; ++i) {
              Rx_data[i]=0;
          }
      }
  }

三、实验现象:

多数厂家的ZET6带有ch340芯片,不需要单独使用usb转串口的工具,直接使用USB连接电脑即可。

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

stm32hal库串口中断发送数据包,stm32,嵌入式硬件,单片机

四、总结

        这仅仅是串口中断接收的部分,关于舵机控制会在下一篇文章给出,第一次写文章,能力不足,有许多改进的地方,希望大家批评指正!

 

 

到了这里,关于STM32 HAL库 串口中断接收数据包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】HAL库——串口中断只接收到两个字符

    环境:STM32CubeMX(6.7.0)+MDK-ARM(V5.36.0.0)+STM32F103C8T6 使用XCOM发送字符串(总共8个字符),单片机进行解析为ModBus协议失败,只接收到前两个字节的数据。 原串口中断回调函数: 去掉串口中断回调函数的printf函数即可 在嵌入式系统中,将printf函数直接放在串口中断服务程序(ISR)中

    2024年01月22日
    浏览(36)
  • 【STM32】HAL库 STM32CubeMX——DMA (串口DMA发送接收)

    软件: STM32CubeMX KEIL5 mcuisp 串口通信助手 硬件: STM32F103C8Tx 杜邦线,面包板,USB转TTL DMA,全称Direct Memory Access,即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。 我们知道系统的运

    2024年02月12日
    浏览(57)
  • STM32F4_HAL库_串口阻塞/中断/DMA三种方式发送数据的配置

    串口阻塞发送的意思就是,发送一段数据,在没有发送完所有数据之前,一直停留在此发送函数(可设定阻塞时间),这个过程中会阻塞别的程序运行; HAL库的配置分为两个层次,一个是HAL库内部调用的、与MCU硬件相关的初始化xxx_MspInit,一个是我们外部调用的初始化xxx_In

    2023年04月25日
    浏览(44)
  • STM32CubeMX-HAL库-UART串口接收中断回调函数代码分析

            CubeMx中HAL库函数的调用不同于库函数调用,在学习CubeMx串口通信时,不理解HAL库中的回调函数是怎么被调用的,于是查看每个的定义,参考其他人写的博客,总算弄明白了HAL库中断调用与库函数不同之处。写下这篇博客一是加深自己的理解,二是希望对不理解HA

    2024年02月02日
    浏览(45)
  • 【STM32】CUBEMX之串口:串口三种模式(轮询模式、中断模式、DMA模式)的配置与使用示例 + 串口重定向 + 使用HAL扩展函数实现不定长数据接收

    目录   总览 使用CUBEMX创建工程的基本配置 CUBEMX中的配置 Keil中的配置 实物连接 串口轮询模式 轮询模式HAL库函数 特点 实验一:发送数据给单片机并让其返回相同值 串口重定向 串口中断模式 在CUBEMX中打开串口中断 中断模式HAL库函数 特点 实验二:使用中断回调完成实验一

    2024年04月10日
    浏览(44)
  • STM32 HAL库串口突然不再接收数据的异常情况

    STM32串口接收分为阻塞式接收和中断式接收。 1、中断+DMA接收 出现突然不再接收数据的异常情况,最有可能的情况为ORE错误和BUSY标志位持续置高。 解决方法:在重新打开中断接收前,使用__HAL_UART_CLEAR_OREFLAG(huart);函数清除ORE错误;如果串口中断重新接收打开频繁且间隔短的话

    2024年02月13日
    浏览(44)
  • stm32使用HAL库配置串口中断收发数据(保姆级教程)

    最近在学习使用hal库,之前都是用标准库来写32代码,所以发个帖子记录一下学习过程,同时也希望能帮助到一些也在学习HAL库的同学。 接下来进入正题 串口中断是指当单片机收到一个串口数据时,单片机会产生一个中断信号,通知处理器中断服务程序去处理这个接收到的数

    2024年02月07日
    浏览(33)
  • HAL库STM32CUBEMX学习记录(一)——USART(串口中断收发数据)

    一、首先使用STM32CUBEMX新建一个工程 二、打开工程文件 1.在usart.c中添加以下代码  2.然后在最后面加入中断回调函数 3.在usart.h文件中加入  4.新建一个cmd.c文件,创建命令check函数 5.在mian函数中的while(1)循环中调用USART1_Check(USART_RX_BUF)函数 6.最后串口初始化函数后打开串口中

    2024年02月16日
    浏览(35)
  • 【STM32笔记】HAL库UART串口配置及重定向(解决接收中断与scanf不能同时工作、重定向卡死、低功耗一直唤醒的问题)

    【STM32】HAL库UART串口配置及重定向(解决接收中断与scanf不能同时工作、重定向卡死、低功耗一直唤醒的问题) 注意:这里用的编译器版本为ARMCC(也就是第5代编译器 而不是AC6) 首先 要使用printf和scanf 必不可少的就是 这里需要做的就是配置单片机的UART 并且使其能够被pri

    2023年04月08日
    浏览(40)
  • 基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据

    ✨申明:本文章仅发表在 CSDN 网站,任何其他网见此内容均为盗链和爬取,请多多尊重和支持原创! 🍁对于文中所提供的相关资源链接将作不定期更换。 📌相关参考《HAL库教程9:串口接收不定长数据》 🎉对于串口接收不定长数据的处理方案网上有很多,个人觉得采用定时

    2024年02月09日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包