使用STM32G4 ----串口发送数据USART_TX的使用

一.引脚的配置

  • 串口对应的引脚
PA10 ---------- USART1_RX 串口一接收引脚 用于接收数据
PA9 ---------- USART1_TX 串口一发送引脚 用于发送数据
PA8 ---------- USART1_CK “串口一同步引脚” 存在同步发送数据的功能(该引脚需要同步收发数据时使用,串口一般使用异步收发数据,不用同步收发数据)
  • 电路原理图

`

`

  • STM32Cube配置

`

二.USART函数的用法

1.串口发送/接收函数


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

  • sprintf(字符串格式化)打印函数的用法
sprintf函数的格式:int sprintf( char *buffer, const char *format [, argument,...] );

除了前两个参数固定外,可选参数可以是任意个。buffer是字符数组名;format是格式化字符串
1.首先在主函数下添加#include "stdio.h"才能调用 sprintf函数
2.使用例子:
	int counter = 0;
	char str[40];
	sprintf(str,%04d:Hello,world.\r\n”, counter);
  • printf()实现串口重定向:
    在 stm32f4xx_hal.c 中重写fget和fput函数
​​printf函数调用的是c库中的fputc函数。因此我们如果重新写了fputc函数,就可以改变printf函数的功能,可以向串口打印输出。
 
/**
  * 函数功能: 重定向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
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}
} 
  • HAL_USART_Transmit(串口发送函数)用法

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

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

例子:
		HAL_USART_Transmit(&husart1,(unsigned char *)str, strlen(str), 50);
		参数1:指针 串口1
		参数2:要发送的字符数组
		参数3:字符数组中内容的长度
		参数4:超时时间 ms
		
	注:使用strlen函数需要添加#include "string.h"才能调用
  • HAL_UART_Receive(串口接收函数)用法
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

	参数同HAL_USART_Transmit();

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_IRQHandler(串口中断处理)函数的用法
	HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  
	
	功能:对接收到的数据进行判断和处理  判断是发送中断还是接收中断,然后进行数据的发送和接收,在中断服务函数中使用

如果接收数据,则会进行接收中断处理函数

 /* UART in mode Receiver ---------------------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  { 
    UART_Receive_IT(huart);
  }

如果发送数据,则会进行发送中断处理函数

  /* UART in mode Transmitter ------------------------------------------------*/
  if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
  {
    UART_Transmit_IT(huart);
    return;
  }
  • 串口接收中断回调函数
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的示例代码,可以在STM32G4HAL库中使用空闲中断接收不定长数据,并将数据保存到数组中: ```c #include "main.h" #include "stm32g4xx_hal.h" #define BUFFER_SIZE 100 UART_HandleTypeDef huart2; uint8_t rx_buffer[BUFFER_SIZE]; uint8_t rx_data = 0; uint16_t rx_index = 0; uint8_t data_received = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); while (1) { if (data_received == 1) { data_received = 0; // Do something with the received data // ... // Clear the buffer rx_index = 0; memset(rx_buffer, 0, sizeof(rx_buffer)); } } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart2) { if (rx_index < BUFFER_SIZE) { rx_buffer[rx_index++] = rx_data; HAL_UART_Receive_IT(&huart2, &rx_data, 1); } else { // Error: buffer overflow rx_index = 0; memset(rx_buffer, 0, sizeof(rx_buffer)); } } } void HAL_UART_IDLECallback(UART_HandleTypeDef *huart) { if (huart == &huart2) { data_received = 1; } } void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } HAL_UART_Receive_IT(&huart2, &rx_data, 1); } void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); 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_LOW; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 16; RCC_OscInitStruct.PLL.PLLN = 192; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { Error_Handler(); } } ``` 在上面的代码中,我们使用了`HAL_UART_Receive_IT()`函数来启动串口接收中断,并使用空闲中断回调函数`HAL_UART_IDLECallback()`来处理接收到的数据。当空闲中断被触发时,我们将`data_received`标志设置为1,以指示有新的数据已经接收完毕。在主循环中,我们检查`data_received`标志是否被设置为1,如果是,则处理接收到的数据,并清空接收缓冲区。 需要注意的是,在`HAL_UART_RxCpltCallback()`回调函数中,我们使用了递归调用`HAL_UART_Receive_IT()`函数来连续接收串口数据。如果接收到的数据超过了缓冲区的大小,我们会清空缓冲区并返回错误,以避免数据丢失。 希望这个示例代码可以帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值