精华内容
下载资源
问答
  • HAL库串口中断接收

    千次阅读 2018-11-17 20:02:00
    然后开启串口中断,在中断中接收数据。但是不要在中断中处理数据,中断中尽量少做一些事情 2.编程中用到的函数 (1)HAL库中提供了很多串口操作的函数,有轮询模式收发,中断模式收发和DMA模式收发,我这里用的是...

    1.利用CubeMX配置串口1

    (1)配置串口1波特率为9600,波特率设置的太高有时会收不到消息,我碰到过。然后开启串口中断,在中断中接收数据。但是不要在中断中处理数据,中断中尽量少做一些事情
    1392333-20181117151546465-760941921.jpg

    2.编程中用到的函数


    (1)HAL库中提供了很多串口操作的函数,有轮询模式收发,中断模式收发和DMA模式收发,我这里用的是中断模式
    1392333-20181117152634637-733885637.jpg
    (2)这里用到的三个函数,我说一下他们的意思,其他函数类似
    HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef huart, uint8_t pData, uint16_t Size);
    //该函数功能为开启串口接收中断,并指定存储接收数据的缓存区,设置从串口接收的数据大小。这里要特别注意,该函数只有从串口接收到Size个数据后才会返回,不然会阻塞。
    HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef huart, uint8_t pData, uint16_t Size, uint32_t Timeout);
    //该函数功能为发送数据到指定串口,pData为数据地址,Size为数据大小,Timeout为超时时间。
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
    //该函数为串口接收完数据后的回调函数,在串口中断中,会依次调用以下这些函数:USART1_IRQHandler(),HAL_UART_IRQHandler(&huart1),UART_Receive_IT(),HAL_UART_RxCpltCallback()。回调函数在主函数中可以自己实现,HAL库只有定义,没有具体实现,我们可以在回调函数中做一些处理,来处理我们得到的数据。

    3.代码实现


    (1)这里做一个简单的串口与上位机串口助手通信的实验,将串口助手发送给开发板串口1的数据回发到串口助手。注意,在利用CubeMX生成的代码进行编程时,自己添加的代码一定要加在各种“BEGIN”和“END”之间。
    (2)首先在main中设置全局变量uint8_t RxCounter1=0,RxBuffer1[50]={0},RxTemp1=0,F_Usart1=0;用来保存从串口收到的数据,F_Usart1为接收完成标志,在while中会一直检测它是否变化,然后进行相关操作。RxTemp1为单缓冲区,接收一个字节时可用
    1392333-20181117161400924-742162294.jpg
    (3)在main()函数中while()之前开启串口接收中断,填好相关参数,HAL_UART_Receive_IT(&huart1,&RxTemp1,1);这里这么设置,先把数据保存到RxTemp1,然后再在回调函数中保存到RxBuffer1中,是为了把串口发来的数据完整的存储在RxBuffer1中,方便我进行其他处理
    1392333-20181117193658312-151646064.jpg
    (4)实现回调函数,这里有两种方法,方法一可以保存数据再进行操作,方法二直接发送数据,不进行操作,仔细看图中注释
    1392333-20181117193924518-2055357068.jpg
    (5)在while中的处理
    1392333-20181117200437982-1957774276.jpg

    4.补充说明


    (1)至此,串口实验基本完成。在这里说一下我项目里碰到的另外一个问题,我里面有两个串口通信要处理,先要在程序里发送数据到串口3,然后要把串口3反馈的内容进行一些处理后发送到串口1,这时候需要把开启中断函数里(HAL_UART_Receive_IT(&huart3,&RxBuffer3[RxCounter3++],1);)的数据缓冲区直接设为全局数组,然后回调函数里直接写开启中断的函数即可,不再需要RxTemp1标志位,但是要注意每次程序发送数据后要 延迟200ms,不然数据会收不到。看图中针对串口3的操作即可
    1392333-20181117195002322-88334606.jpg

    1392333-20181117195051999-1217580915.jpg
    1392333-20181117195138369-506610281.jpg

    转载于:https://www.cnblogs.com/yf4695/p/9975230.html

    展开全文
  • stm32 cubemx hal库 串口收发 中断接收 包括 MDK项目 和 stm32的cubemx 项目 使用hal最新的库函数开发 cubemx 4.26.1 有中文注释
  • 在使用过程中几乎不需要去修改HAL库本身代码, 直接使用现有HAL库接口就可以快速方便的开发应用程序, 配合CubMx对开发人员来说实在是太友好了, 今天介绍个自用的串口中断接收的使用方法, 先看下HAL库串口中断接收的...

    STM32的HAL库将底层包装的很完备了, 在使用过程中几乎不需要去修改HAL库本身代码, 直接使用现有HAL库接口就可以快速方便的开发应用程序, 配合CubMx对开发人员来说实在是太友好了, 今天介绍个自用的串口中断接收的使用方法, 先看下HAL库的串口中断接收的序列图:

    从图中可以看出从第 3步到第7步已经形成一个接收闭环了, HAL库的调用方式上图已说明, 需要用户自己去实现的部分就是重写HAL_UART_RxCpltCallback这个函数, 下面介绍下我使用的接收方法.

    基本原理是使用了自定义的队列进行串口数据的接收存储与处理, 下面具体说下:

    重写的回调函数:

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *aHuart)
    {
    	HAL_StatusTypeDef status;
    
    	if (aHuart->Instance == USART1)
    	{
    		UART1_ReceiveByte(m_Uart1_RcvByte);
    		status = HAL_UART_Receive_IT(aHuart, &m_Uart1_RcvByte, 1);
    	}
    }

    在这里使用了一个字节的变量用于串口数据的接收, 具体接收处理在UART1_ReceiveByte()这个函数中处理, 这么处理的好处是可以更灵活的接收不定长的数据, 在UART1_ReceiveByte函数中的处理更像传统的中断处理方式, 直接处理接收到的单字节即可.

    UART1_ReceiveByte函数中我的处理方式是根据对接设备的协议进行一次预处理, 申请一个足够装下一条协议数据的缓存区对接收到的数据进行截取, 然后将截取到的数据推入到指定队列中.

    然后在消息处理循环中去读取队列中的协议数据, 进行二次判断并进行相应的消息处理即可.

    至此, 该串口中断接收数据处理流程就已完成了.

    展开全文
  • STM32 HAL库+串口DMA+空闲中断(IDLE)实现不定长数据接收,可以用来参考学习使用,简单易懂。
  • 简介:STM32与上位机之间用通信协议(自己定义)进行串口通信。怎么判断上位机发过来的指令是正确的,而不是一串乱码?怎么从正确的指令中提取出想要的命令代号,从而实现想要的功能? 方法:读取上位机发来的命令,...
  • [STM32系列]一、HAL库串口中断接收

    千次阅读 2019-09-09 14:41:50
    [STM32系列]一、HAL库串口中断接收1、前言2、回调函数3、HAL库中断接收函数使用 1、前言 HAL即硬件抽象层(英语:Hardware Abstraction Layer),实现了不同硬件的统一接口操作。这就极大的简化了程序员的移植工作...

    [STM32系列]一、HAL库的串口中断任意长度接收

    1、前言

    HAL即硬件抽象层(英语:Hardware Abstraction Layer),实现了不同硬件的统一接口操作。这就极大的简化了程序员的移植工作,搭配STM32CubeMX,使用起来非常方便。

    2、回调函数

    HAL库使用了很多的回调机制,这样写能够更好的实现程序的分层处理,不影响程序的主体框架,方便后期修改移植。

    3、HAL库中断接收函数使用

    使用HAL_UART_Receive_IT函数前,需要使能串口的接收中断,并配置中断优先级。

     /* Peripheral clock enable */
        __HAL_RCC_USART2_CLK_ENABLE();
      
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART2 GPIO Configuration    
        PA2     ------> USART2_TX
        PA3     ------> USART2_RX 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        /* USART2 interrupt Init */
        HAL_NVIC_SetPriority(USART2_IRQn, 1, 1);
        HAL_NVIC_EnableIRQ(USART2_IRQn);
    

    在对应的串口中断函数中需要对应的中断处理

    void USART2_IRQHandler(void)
    {
      /* USER CODE BEGIN USART2_IRQn 0 */
    
      /* USER CODE END USART2_IRQn 0 */
      HAL_UART_IRQHandler(&huart2);
      /* USER CODE BEGIN USART2_IRQn 1 */
    
      /* USER CODE END USART2_IRQn 1 */
    }
    

    这时就可以使用
    HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
    函数接收了,该函数会打开接收中断接收数据,函数的第一个参数指定接收串口的结构体指针,第二个参数为接收数据指针,第三个参数为接收数据长度。该函数没有超时机制,必须要指定接收的数据长度,在数据没有达到接收长度时该函数会一直阻塞,这就要求接收的数据长度必须为已知,在接收不定长度数据时会不适用。
    在使用串口接收Modbus-RTU数据时,需要接收不定长的数据帧,并且要求非阻塞接收。像在标准库中接收数据一样,这里可以通过HAL_UART_Receive_IT接收单个字节的数据,在接收回调函数中加入超时处理即可完成一帧数据的接收。接收流程如下:

    Created with Raphaël 2.2.0 开始 接收一个字节 超时? 帧处理 结束 yes no

    保证数据帧完整的接收,就需要在接收完一个字节数据的时候将计时清零,继续下一次接收,直到超时退出,然后再处理这一帧数据。具体实现内容如下:

    //数据接收结构体
    struct M_Rev{
    	uint8_t revcnt;			//接收计数
    	uint8_t revact;			//开始标志
    	uint8_t oldcnt;			//上次计数
    	uint32_t revtick;		//接收计时
    	uint8_t revbuff[MODBUS_MAX_LEN];		//接收缓存
    }Modbus_Rev;
    
    //接收回调函数
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	if(huart->Instance == USART2)		//判断串口
    	{
    		if(Modbus_Rev.revcnt == 0)		//帧第一个数据
    		{
    			if(Modbus_Rev.revact == 1)	//首次接收
    			{
    				Modbus_Rev.revact = 2;		
    			}
    			else	//非首次接收
    			{
    				Modbus_Rev.revbuff[0] = Modbus_Rev.revbuff[Modbus_Rev.oldcnt];	//上一次接收数据位置
    			}	
    			HAL_TIM_Base_Start_IT(&htim2);	//开启定时器
    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);	//开启指示灯
    		}		
    		Modbus_Rev.revcnt += 1;	//接收计数
    		if(Modbus_Rev.revcnt >= MODBUS_MAX_LEN)	Modbus_Rev.revcnt = MODBUS_MAX_LEN - 1;	
    		
    		Modbus_Rev.revtick = 0;	//计时清0
    		HAL_UART_Receive_IT(huart, &(Modbus_Rev.revbuff[Modbus_Rev.revcnt]), 1);	//接收下一次数据
    	}
    }
    
    //定时器回调函数
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	Modbus_Rev.revtick += 1;				//计时增加
    	if(Modbus_Rev.revtick > MAX_TIM_CNT)	//定时器溢出
    	{
    		Modbus_Rev.revtick =0;				//计时清0
    	}
    	if(Modbus_Rev.revtick >= MODBUS_T35)	//接收超时
    	{
    		if(Modbus_Rev.revact == 2)			//首次接收
    		{
    			Modbus_Rev.revact = 0;			//关闭首次接收
    		}	
    		Modbus_ReciveData(Modbus_Rev.revbuff,Modbus_Rev.revcnt);		//完成一帧接收,处理
    		Modbus_Rev.oldcnt = Modbus_Rev.revcnt;		//保存接受位置
    		Modbus_Rev.revcnt = 0;				//接收计数清0
    		HAL_TIM_Base_Stop_IT(&htim2);	//关闭定时器
    		
    		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);	//关闭指示灯
    	}
    }
    

    其中要注意的一点是,在第二帧接收时,由于接收的地址是上一帧的接收位置 + 1所以需要保存其位置,将其数值赋值到这一帧的第一个字节即可。

    展开全文
  • 关于STM32 HAL库 串口接收中断 串口每次接收到一个数据都会进入中断,而只有huart->RxXferCount减小到0了,才会进入中断回调函数。可以从下图中看出。 所以,中断接收的过程就是 (pTxBuffPtr,TxXferSize 和 ...

    关于STM32 HAL库 串口接收中断

    串口每次接收到一个数据都会进入中断,而只有huart->RxXferCount减小到0了,才会进入中断回调函数。可以从下图中看出。
    在这里插入图片描述
    在这里插入图片描述
    所以,中断接收的过程就是
    在这里插入图片描述
    (pTxBuffPtr,TxXferSize 和 TxXferCount 三个变量分别用来设置串口发送的数据缓存指针,发送的数据量和还剩余的要发送的数据量。
    pRxBuffPtr,RxXferSize 和RxXferCount 则是用来设置接收的数据缓存指针,接收的最大数据量以及还剩余的要接收的数
    据量。)

    过程

    当接收到一个字符之后,在函数
    UART_Receive_IT中会把数据保存在串口句柄的成员变量pRxBuffPtr缓存中,并且使RxXferSize +1,RxXferCount -1,当RxXferCount 减小到0的时候,就会调用接收完成回调函数
    HAL_UART_RxCpltCallback 进行处理。

    1.CUBEMX配置的MX_USART1_UART_Init()中是没有开启中断的,需要加上

    HAL_UART_Receive_IT(&huart1, (u8 *)aRxBuffer, RXBUFFERSIZE);
    

    其中aRxBuffer是我们自己定义的临时缓冲区,如果它的长度RXBUFFERSIZE = 1,则每次进入中断之后,都会进入中断回调函数。
    2.回调函数每调用一次,库的设置会自动将中断关闭,所以需要再次开启,这里我们放在了USART1_IRQHandler(),中断入口函数中。

    3.读取USARTx->SR能避免莫名其妙的错误,所以在中断入口函数中加了

    while(HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY)//等待就绪
    
    展开全文
  • STM32 HAL实现串口中断接收

    千次阅读 2020-03-28 17:20:58
    一、串口设置 1. 异步模式 2. 参数 3. 中断使能 4. 生成代码如下 /* USART6 init function */ static void MX_USART6_UART_Init(void) { huart6.Instance = USART6; huart6.Init.BaudRate = 115200; huart6....
  • STM32F1 1.8.3 版本 1. CUBE配置 打开串口 打开中断 配置优先级 生成工程文件 2. 代码添加 在usart.h中添加: #define USART_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART1_RX 1 //使能
  • STM32使用HAL库串口接收中断

    万次阅读 热门讨论 2019-03-16 22:16:31
    下面讲解使用HAL库配置串口1,使串口1可以使用中断接收字节并原样返回。 1. STM32CubeMX对串口1作如下配置 2. 添加如下代码 ​ uint8_t uart1_rxbuf[10]; // 用于存放接收到的数据 void MX_USART1...
  • hal库实现stm32串口中断接收数据

    千次阅读 2020-12-01 14:14:21
    先设置并开启串口中断接收 该函数功能为开启串口接收中断,并指定存储接收数据的缓存区,设置从串口接收的数据大小。这里要特别注意,该函数只有从串口接收到Size个数据后才会返回,不然会阻塞。 HAL_UART_Receive_...
  • 发送和接收两个函数  /*##-2- Start the transmission process #####################################*/  /* While the UART in reception process, user can transmit data through   "aTxBuffer"...
  • stm32l051_stop.rar

    2020-06-18 15:54:09
    STM32L051使用CUBEMX配置,使用HAL库串口中断接收,使用空闲中断方式接收不定长数据,非DMA方式。同时配置了RTC,并且设置了RTC闹钟为每小时定时触发方式。程序在STM32的Nucleo开发板上实验不丢失字节。
  • CubeMX,HAL库使用串口发送和中断接收一、CubeMX界面配置二、MDK代码 不得不说HAL库和标准相比确实简单多了。。。 一、CubeMX界面配置 选择完 异步通讯模式 后,其余默认即可。 打开串口中断 二、MDK代码 在/* ...
  • 距离上次串口挖的坑,已经过去1年多了,这次带着更加方便的解决方法来了,不用再次初始化串口那么麻烦了,更加省事[>\/<] 本菜鸟用的主控MCU:STM32L031K6UX 直接贴代码,简单粗暴,以后直接加到定时...
  • //HAL库使用的串口接收缓冲 UART_HandleTypeDef UART1_Handler; //UART句柄 int fputc(int ch, FILE *f){ HAL_UART_Transmit (&huart1,(uint8_t *)&ch,1,0xffff); return ch; } int fgetc(FILE *f) { uint8_t ch = ...
  • Mode选择异步模式Asynchronous,查看串口的基础配置-Parameter Settings,保持默认不变。 选择NVIC Settings点击Enabled使能全局中断。 这样整个串口配置就完成了。 二、代码实现 在自动生成代码里点开MX...
  • 本文开发环境: MCU型号:STM32F051R8T6 IDE环境: MDK 5.25 代码生成工具:STM32CubeMx 5.2.0 ...串口接收中断的配置 串口接收DMA线的配置 示例程序及起运行流程 附件:代码工程(MDK) 文章...
  • STM32串口中断接收实验(HAL库

    万次阅读 2018-09-10 20:11:39
    简介:STM32与上位机之间用通信协议(自己定义)进行串口通信。怎么判断上位机发过来的指令是正确的,而不是一串乱码?怎么从正确的指令中提取出想要的命令代号,从而实现想要的功能? 方法:读取上位机发来的命令...
  • HAL库串口中断

    千次阅读 2021-09-27 10:26:31
    一,配置串口初始化 void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; ...
  • STM32f0HAL库,STM32CubeMX创建,串口DMA空闲中断接收fifo数据处理程序,实测可用
  • ST推的HAL库,在整个接收过程中,是没有用到串口接收空闲中断,它的处理有三种,分别是轮询,接收完成中断(每一个字节一次),DMA接收。 整个Hal库接收和发送过程都封装好了,就用最简单的轮询方式看,先看...
  • HAL库中,进入接收中断的方法与标准很不一样,具体方法如下 u8 Res[1] ; //声明一个U8数组 HAL_UART_Receive_IT(&huart1,Res,1); // 初始化中打开串口1接收中断 //重写函数HAL_UART_RxCpltCallback,放在任意...
  • STM32HAL库串口处理---中断收发

    千次阅读 2020-03-05 21:57:39
    STM32HAL库串口处理—中断收发 文章目录STM32HAL库串口处理---中断收发Arduino串口机制的接口函数代码实现编写硬件层MSP支持代码定义新的串口结构体接口函数实现实例化对象`serial_init()``serial_available()``...
  • STM32串口接收中断——基于HAL库

    千次阅读 2019-01-25 21:52:00
    在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考。 1.UART相关的头文件引用错误  由于本人直接使用MDK进行开发,没有使用CubeMX,所以一些初始化需要手动进行。在引用UART相关的头文件时,...
  • 【STM32的HAL库开发】串口中断开发环境在main.c添加代码(1/2)在stm32f4xx_it.c添加代码(2/2)注意附代码 开发环境 cubemx V5.5.0 + MDK Keil V5.29.0.0 + STM32F429NIH 在main.c添加代码(1/2) 在main函数中,初始化...
  • HAL库学习——串口中断一些注意点

    千次阅读 2020-07-24 17:31:00
    最近在使用HAL库串口中断做数据接收时遇到了中断接收标志位开启,但是却收不到数据的问题。作者的代码时是在主程序初始化时使用HAL_UART_Receive_IT函数开启中断每次接收一个字符,由于HAL库的底层机制每接收一个...
  • 代码已完成,待更新到此平台...................
  • STM32CubeMX串口接收数据(中断方式,HAL库

    万次阅读 多人点赞 2018-01-31 16:30:13
    系统:linux mint 18.3 xfce 64bit 软件: STM32CubeMX 4.24 SW4STM32 2.4 ... 开发板芯片:STM32F103RCT6,STM32F407VET6...实现效果:打开两个串口助手窗口,一个是USART1的,一个是USART2的,任意一个串口串口1

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,092
精华内容 1,636
关键字:

hal库串口中断接收