STM32 USART与USB接收不定数据方法,标准库、HAL库都适用

发布者:meirong最新更新时间:2025-02-19 来源: cnblogs关键字:STM32  USART  标准库  HAL库 手机看文章 扫描二维码
随时随地手机看文章

很多时候,我们使用串口或USB接收数据时,往往不知道PC端会发多长的数据下来,

为了解决这个不定数据接收问题,在此各提供一个解决思路。


串口数据不定接收:

由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,

由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。


IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一

次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以

叫做一包数据。


还有一个RXNE中断,当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就

会产生IDLE中断。比如给单片机一次性发送8个字节,就会产生8次RXNE中断,1次IDLE中断。


这里只写RXNE中断例子,IDLE中断的类似,只是寄存器地址不同,各位可以查手册编写。


eg:

  在中断服务函数里添加一下代码,函数外部定义 buff[ ] 和 i=0 ; 我这里使用的是串口1:

  if(UASART_GetITStatus(UASART1, UASART_IT_RXNE != RESET)) //接收一个字节判断

  {

    buff [i++] = UASART1->DR;       //把接收到的字节保存到数组后,数组下标自加1

  }


就这么几句代码就可以实现了,buff[ ],就是接收到的数据,i-1 就是数据长度了

=======================================================================

USB不定数据接收:

        usb不定数据接收,利用了定时器作为校验来接收,这个方法通用性强,适用于uasart也适用于usb,还使用于hal库。不过这个方法有一个局限性,就是PC端发送数据过来的时间间隔不可以太短,否则会出现误判情况。


定时器方法的原理是:先定时一个时间间隔合适的时间,一般几毫秒就可以了,然后在接收服务函数里把接收到的数据存到buff[ ],i++,接着定时器计数值清0,打开定时器,如果数据没接受完,每次接收都清空了定时器计数器,使得定时器无法进入定时器中断。如果数据接收完成了,则过不会清空定时器计数器,进入定时器中断,此时则判断数据已经接收完成,可以在定时器中断中取出数据和数据长度。


eg:

这里我是用HAL库作为例子,在usbd_cdc_if.c文件中找到USB接收中断服务函数,在里面

修改代码即可。

  

 

  

  

  

 

因为usb发送,每发送最大包是64个字节,而且usb接收可以自己算出接收长度,不过超过64字节就会出错,所以我这里进行了一个最大包处理。


关键字:STM32  USART  标准库  HAL库 引用地址:STM32 USART与USB接收不定数据方法,标准库、HAL库都适用

上一篇:STM32 的 printf() 函数串口重定向(HAL库标准库都适用)
下一篇:STM32CubeMX学习笔记(17)——电源管理(PWR)低功耗待机模式

推荐阅读最新更新时间:2026-03-20 10:47

STM32 USARTUSB接收不定数据方法,标准库HAL库都适用
很多时候,我们使用串口或USB接收数据时,往往不知道PC端会发多长的数据下来, 为了解决这个不定数据接收问题,在此各提供一个解决思路。 串口数据不定接收: 由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据, 由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。 IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一 次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以 叫做一包数据。 还有一个RXNE中断,当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就 会产生IDLE中断。比如给单片机一次性发送8个字
[单片机]
<font color='red'>STM32</font> <font color='red'>USART</font>与<font color='red'>USB</font><font color='red'>接收</font><font color='red'>不定</font><font color='red'>数据</font>方法,<font color='red'>标准库</font>、<font color='red'>HAL库</font>都适用
STM32 HAL库学习系列第10篇---串口空闲中断接收不定数据
串口重定向配置: 可以直接复制使用 /************************************************* * 函数功能: 重定向c库函数printf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } /** * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 *
[单片机]
嵌入式STM32开发方式的本质区别:寄存器、标准库HAL库对比(嵌入式初级开发者必读)
作为嵌入式初级开发者,理解STM32的三种开发方式(寄存器、标准库、HAL库)的本质区别及其适用场景,是掌握STM32开发的关键。以下是专业且通俗的对比分析: 1. 寄存器开发(Register-Level) 本质 直接通过读写硬件寄存器控制外设,开发者需手动配置每一个寄存器的位字段,完全掌控底层硬件。 代码示例 // 配置GPIOA的Pin0为输出模式 RCC- APB2ENR |= 1 2; // 使能GPIOA时钟 GPIOA- CRL &= ~(0x0F 0); // 清除Pin0原有配置 GPIOA- CRL |= 0x03 0; // 推挽输出,50MHz速度 GPIOA- ODR |= 1
[单片机]
STM32标准库改为HAL库的程序实现
标准库占绝大多数,自己买的板子跟的资料也一般是标准库,HAL库很少,不过要是使用STM32CubeMx配置,那么就是使用的HAL库了,而参考资料是标准库的,就没有办法用。 注意: 1. 标准库与HAL库不兼容,不要想着直接拿来用了,比如标准库使用#include stm32f10x.h ,HAL库使用#include stm32f1xx_hal.h 要让标准库程序使用HAL库时也可以正常运行得到想要的结果,有以下几种方法: 一、 将标准库程序中的每个函数内的代码修改为使用HAL库且同样效果的代码, 比如标准库中配置GPIO的代码直接就可以用STM32CubeMx配置为相同效果 二、根据标准库程序整个程序运行的原理使用HAL库
[单片机]
STM32标准库HAL库特点与应用
新手在入门STM32的时候,一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配置寄存器进行开发。 对于刚入门的朋友可能没法直观了解这些不同开发发方式彼此之间的区别,本文试图以一种非常直白的方式,用自己的理解去将这些东西表述出来。 配置寄存器 不少先学了51的朋友可能会知道,会有一小部分人或是教程是通过汇编语言直接操作寄存器实现功能的,这种方法到了STM32就变得不太容易行得通了。 因为STM32的寄存器数量是51单片机的十数倍,如此多的寄存器根本无法全部记忆,开发时需要经常的翻查芯片的数据手册,此时直接操作寄存器就变得非常的费力了。也有人喜欢去直接操作寄存器,因为这样更接近原理,代码更少,知其然也知其所以然。
[单片机]
<font color='red'>STM32</font><font color='red'>标准库</font>、<font color='red'>HAL库</font>特点与应用
STM32的SPI1、SPI2、SPI3初始化及RF1101的应用(标准库HAL库
——基于STM32F103RCT6 ---- 标准库: 说明:相关文件共有两个:bsp_spi_cc1101.h;bsp_spi_cc1101.c;以SPI2为例。 1、“bsp_spi_cc1101.h”中的参数定义: #ifndef _BSP_SPI_1101_H_ #define _BSP_SPI_1101_H_ #include stdio.h #include stm32f10x.h #include misc.h #include os_cfg_app.h #include os.h #include core_cm3.h #include bsp.h #include stm32f10x_s
[单片机]
HAL库教程9:串口接收不定数据
  串口收到的两组数据之间,往往会有一定的时间间隔。可以判断这个间隔,来实现无需结束符,无需指定长度,串口可接收不定长数据的功能。如果串口在一定的时间内没有收到新的数据,可以认为一组数据已经接收完毕了。思路是用定时器来设置一个“闹钟”,连续的一段时间没有收到新的数据,闹钟响起,就把已经收到的数据打包,做相应处理。 定时器溢出时间配置   首先修改定时器的溢出时间。本文规定使用5ms的间隔。在某些通信协议中,会规定间隔时间。例如Modbus规定两组数据之间要间隔3.5字符。   实际上,间隔的时间常常与通信的波特率是相关的。在9600波特率下,一个字节的数据共 起始+8数据+结束=10位,一位是104us,所以一个字节的数据是1
[单片机]
STM32串口通信:修改标准库的printf通过USART打印
USART1需要事先进行较为麻烦配置,配置之后发现即使用HAL函数发送语句还要事先以字符串方式定义,实在是麻烦,虽然后面另外自己写了一个简单的库来操作串口,但看到了更简单的方法,修改标准库中printf相关的两个函数,达到通过printf来串口输出的效果。 (在配置完要使用的串口后) 先在main.c中加上 #include stdio.h 然后重定向两个函数,这里指定的是USART1接口,PA9和PA10,其他USART或者UART自行修改即可 int fputc(int ch, FILE *f) { USART1- DR=(uint8_t)ch; while((USART1- SR&0X40)==0); return ch
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved