STM32-hal库学习(4)--usart/uart通信 (单向通信)(同时显示在oled)

发布于:2024-07-01 ⋅ 阅读:(13) ⋅ 点赞:(0)

前言:

关于usart详解:

stm32-USART通信-CSDN博客

因为在oled上显示,我们直接在上一个工程进行修改:

STM32_hal库学习(3)-OLED显示-CSDN博客

其他配置与oled显示工程保持不变,打开oled文件的工程:

配置:

开启USART1:

点击USATR1  ——>设置MODE为异步通信(Asynchronous)  ——>     波特率为115200 Bits/s。传输数据长度为8 Bit。奇偶检验无,停止位1 ,接收和发送都使能 。

然后,NVIC Settings 一栏使能接收中断

时钟树与上个工程保持一致。

选择工程配置:

选上每个功能独立生成.c.h

常用函数:

1、串口发送/接收函数

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送

HAL_UART_Receive_DMA();串口DMA模式接收

串口发送:

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

功能:串口发送指定长度的数据。如果超时没发送完成,则不再发送,返回超时标志(HAL_TIMEOUT)。

参数:

第一个: UART_HandleTypeDef *huart    UATR的别  如 :   UART_HandleTypeDef huart1;   别名就是huart1  
第二个:*pData      需要发送的数据 
第三个:Size    发送的字节数
第四个:Timeout   最大发送时间,发送数据超过该时间退出发送   

例:

  HAL_UART_Transmit(&huart1, (uint8_t *)ymj, 3, 0xffff);   //串口发送三个字节数据,最大传输时间0xffff

中断接收数据:

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

功能:串口中断接收,以中断方式接收指定长度数

        大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断。再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)

2、串口中断函数

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //串口发送一半中断回调函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数
HAL_UART_ErrorCallback();串口接收错误函数

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  

功能:对接收到的数据进行判断和处理  判断是发送中断还是接收中断,然后进行数据的发送和接收,在中断服务函数中使用

3、串口查询函数

HAL_UART_GetState();  判断UART的接收是否结束,或者发送数据是否忙碌

while(HAL_UART_GetState(&huart4) == HAL_UART_STATE_BUSY_TX)   //检测UART发送结束

常用的有:

1.阻塞模式收发数据

        HAL_UART_Transmit():串口发送数据,使用超时管理机制
        HAL_UART_Receive(): 串口接收数据,使用超时管理机制

2.中断模式收发数据
        HAL_UART_Transmit_IT():串口中断模式发送
        HAL_UART_Receive_IT(): 串口中断模式接收

3.DMA模式收发数据
        HAL_UART_Transmit_DMA():串口DMA模式发送
        HAL_UART_Transmit_DMA():串口DMA模式接收

程序实现:

程序参考:

STM32CubeMx+HAL库:USART串口收发数据的三种方式_单片机串口接收方式-CSDN博客

注意,要勾选Use MicroLib(点击魔法棒-Target),如果不点,可能会收不到信息。

1.在usart.c重写(记得包含头文件#include "stdio.h")

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

2.main.c加上()

#include "stdio.h"
#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数 
int value=0;

3.int main加入

HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);

4.while加入

value++;
printf("%d\r\n",value);
OLED_ShowNum(24,4,value,4,24, 0);
HAL_Delay(1000);

5.末尾加上回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  //UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */

	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		memset(RxBuffer,0x00,sizeof(RxBuffer));
		HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
        
	}
	else
	{
		
		RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
            while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
			Uart1_Rx_Cnt = 0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}

最终测试实现:

每秒+1,同时在oled显示

下一篇文章将会写双向通信,实现主从交互,分别为轮询模式、中断模式、dma模式。