Stm32L0串口中断接收使用

最新在做LoRa的项目,使用的是STM32L072和SX1276,需要做一个串口透传模块,刚开始做demo的时候不考虑功耗,所以串口发送和接收直接使用下列函数执行:

		HAL_UART_Transmit(&Sensor_UartHandle,(unsigned char *)&readcommand, sizeof(vcom_read_command_t), VCOM_START_DELAY);
		HAL_UART_Receive(&Sensor_UartHandle,(unsigned char *)read_temp,UART_BUFFER_MAX_LEN, VCOM_RECV_TIMEOUT);

  都涉及到了超时时间,而超时时间依赖的是systick中断,接收发送100字节没问题。

但现在需要做低功耗,那么就不允许systick频繁中断了,于是考虑到串口中断接受,但stm32的库提供的函数让人看不明白:

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

 尝试一个晚上,现在收发没问题了,网上写的步骤不够详细,先将我的做法例举如下:

1.在串口初始化的时候打开串口中断,M0的芯片只有串口中断,不区分发送或者接收中断:

void CommandUartInit(void)
{
  Sensor_UartHandle.Instance         = SENSOR_USARTX;
  Sensor_UartHandle.Init.BaudRate    = 4800;
  Sensor_UartHandle.Init.WordLength  = UART_WORDLENGTH_9B;    /*8-bit data and 1-bit even bit*/
  Sensor_UartHandle.Init.StopBits    = UART_STOPBITS_1;
  Sensor_UartHandle.Init.Parity      = UART_PARITY_EVEN;
  Sensor_UartHandle.Init.HwFlowCtl   = UART_HWCONTROL_NONE;
  Sensor_UartHandle.Init.Mode        = UART_MODE_TX_RX;
  if(HAL_UART_Init(&Sensor_UartHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  NVIC_EnableIRQ(USART2_IRQn);
  NVIC_ClearPendingIRQ(USART2_IRQn);
}

 2.添加中断处理函数,按照stm32文件惯例,中断函数在stm32xxx_it.c里面添加:

void USART2_IRQHandler(void)
{
	HAL_UART_IRQHandler(&Sensor_UartHandle);
}

 这里需要说明的是,串口发送和接受的处理库已经帮我们做好了,全部封装在 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 这个函数里,我们需要做的就是在中断处理函数里面调用这个函数而已,参数填写正确的串口号。

3. 在主循环中调用发送接收函数:

		HAL_UART_Transmit_IT(&Sensor_UartHandle,(unsigned char *)&readcommand, sizeof(vcom_read_command_t));
        do{
			uart_receive_status = HAL_UART_Receive_IT(&Sensor_UartHandle,(unsigned char *)read_temp,UART_BUFFER_MAX_LEN);
			temp_state=HAL_UART_GetState(&Sensor_UartHandle);
			if(temp_state==HAL_UART_STATE_BUSY_RX || temp_state==HAL_UART_STATE_BUSY_TX_RX)
			{
			    receive_timeout ++;
			}
        }while(Sensor_UartHandle.RxXferCount != 0 && receive_timeout < 10000);

 这里有几点需要说明:

1)发送没什么好说的,直接调用HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)就可以将数据发送出去,可以发送任意size的数据。

2)接收函数做的比较恶心,HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size),每调用一次只接收一个字节,自己可以去分析static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)。

3)说一下这几个函数之间的关系:

调用HAL_UART_Receive_IT()相当于开启接收中断--->如果有数据,会触发中断USART2_IRQHandler() ---> HAL_UART_IRQHandler() ---> UART_Receive_IT()

可以看到在HAL_UART_Receive_IT中设置的各种参数,在UART_Receive_IT中都会用到,uhdata = (uint16_t) READ_REG(huart->Instance->RDR);这个就是从串口数据寄存器中获取到的数据。

4)重新说明下,不管是发送数据还是接收数据都会触发中断,进而最终会调用到 UART_Receive_IT()这个函数,在这个函数里面分别对接收和发送做了处理,可以看看源码。

5)为了实现接受任意长度的数据,我定义了一个255字节的数组用于接受,然后加了一个超时时间,网上很多用系统时钟做超时,但我为了做低功耗,没有开启systick中断,所以就直接加了一个u32的变量去计数,超时时间要根据自己接收的最长数据调整。

6)很多人说在接收大数据的时候这个库函数有问题,项目太急,暂时就不研究了,等遇到的时候再研究吧。

时间: 2024-10-20 12:08:46

Stm32L0串口中断接收使用的相关文章

STM32F429基于CUBEMX的串口中断接收

今天要来介绍一下HAL库的串口中断使用方法 首先打开CUBEMX,新建一个STM32工程,博主建立的是F429工程,然后在图形界面中打开一个USART,这里我们使用USART1. 然后进入配置configguration 基本的参数都不用修改,在NVIC中,大概中断使能 然后生成工程即可,打开工程文件.这里要解释一下串口中断接收: 关于串口接收中断 用CUBEMX生成的工程文件中,先开启接收中断使能 __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);并

利用串口空闲中断接收数据

1 void USART2_IRQHandler(void) 2 { 3 // 使能串口空闲中断 4 USART_ITConfig(USART2, USART_IT_IDLE , ENABLE); 5 6 if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET) 7 { 8 9 rx_buf[cnt]=USART_ReceiveData(USART2); 10 rx_rxbuf[cnt] = rx_buf[cnt] ;//把接收到的数组存到备用的数组当中,

stm32RS485串口通信——中断接收发送数据

功能:通过PC机的串口调试助手发送数据给串口A,串口B接收到串口A发送的数据,再由串口B将接收到的数据返回给PC机的串口调试助手. PC->串口A->串口B->PC. 实验平台:stm32f407 /********************************************************************* 本平台具有六个串口: com1  485 com2 com3  232 需一个管脚控制DTU com4 485 com5  调试串口  TTL com6

STM8S和STM8L调试串口中断的注意点

1. STM8L串口中断注意点 在调试PM2.5传感器GP2Y1051的时候,发现在仿真的时候开始能够进行数据的接受,但是如果暂停之后就不能接受数据,其实只是接收了一次完整的数据. 问题程序 解决方法 if(USART_GetITStatus(USART1, USART_IT_RXNE)) { RecevieData = USART_ReceiveData8(USART1); switch(state_machine) 2. STM8S串口中断注意点 征对STM8S003F3或者103系列等单片

串口中断

1 中断图里边,芯片,最右侧是CPU,左边都是寄存器.2 PND寄存器不需要设置,需要判断.3 问题串口0中断有2级中断么? 串口中断28号,但是对应了3个中断源,2,串口错误 1,串口发送, 0 ,串口接收.4 8N1中的N表示无校验.5 当你向串口BUF中写入一个时,不取走的情况下,不能再写.6 代码和栈怎么理解? 4K指SRAM4K的大小. nandflash 256K,SRAM,4K,(SRAM只有4K,但是占用了128的地址,片选0) 4096(4096~3840表示系统栈空间) 38

STM32串口中断的一些资料

在研究STM32串口接收发送中断的时候找到不少不错的资料,现在备份在这里.以供自己查阅,以及方便其他人. TC ====TXE 顺便预告下最近会写个有关串口处理数据的帖子,从查询和中断方面以及数据处理的方式,从队列以及FIFO方面写起. SECTION 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /* 调试STM32串口过程中发现一个奇怪的问题,

【转】搞定单片机多字节串口接收(串口多字节接收发送的高阶研究)

搞定单片机多字节串口接收(串口多字节接收发送的高阶研究) 原文地址:http://bbs.ednchina.com/BLOG_ARTICLE_3007162.HTM 工作了一年多,写了不少单片机串口程序.感觉串口多字节接收部分的逻辑相对于配置寄存器跟串口回复来说,是有点难度的——寄存器配置基本上都是死的,串口回复多字节跟回复一字节只是多了一个循环. 串口接收程序是基于串口中断的,单片机的串口每次接收到一字节数据产生一次中断,然后再读取某个寄存器就可以得到串口接收的数据了.然而在实际应用当中,基本

STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

Ⅰ.写在前面 关注我分享文章的朋友应该知道我在前面讲述过(软件.硬件)I2C主机控制从机EEPROM的例子.在I2C通信主机控制程序是比较常见的一种,可以说在实际项目中,很多应用都会使用到I2C通信.但在实际项目中作为I2C从机的应用相对要少的多,本文主要讲述关于[STM32F10x_硬件I2C主从通信]中STM32作为从机的例子. 在学习本问内容之前,如果对I2C协议还不太了解的朋友请先去了解一下I2C协议,或看我之前关于I2C通信的文章(我微信公众号和博客都有). 关于STM32硬件I2C作

串口中断的问题

关于串口中断 void uart(void) interrupt 4 using 3  {  unsigned char   i,j; .    EA=0;   i=SBUF;  RI=0;     //接收中断标志位          if((i==0x5b)||(i==0xfa))  {      while(!RI);  i=SBUF;  RI=0;    //还要接收数据所以置0          if((i==0x5c)||(i==0xf5))          {