stm32中scanf函数的用法
时间: 2025-01-01 13:23:17 浏览: 8
### STM32 中 `scanf` 函数的使用
在嵌入式开发环境中,标准 C 库中的 I/O 函数如 `printf` 和 `scanf` 并不直接适用于微控制器平台。对于 STM32 来说,要实现在调试过程中利用这些函数来读取数据,则需借助于 ITM (Instrumentation Trace Macrocell) 或者通过 USART 实现串口通信。
#### 利用 ITM 进行 `scanf`
为了能够像桌面应用程序那样方便地调用 `scanf` 获取用户输入,在基于 ARM Cortex-M 的设备上通常会启用 SWO 输出并配置 ITM 跟踪宏单元来进行半主机操作[^1]:
```c
#include "stm32f4xx_hal.h"
#include <stdio.h>
// 配置 ITM 用于 printf/scanf 功能
void SystemInit(void){
// ...其他初始化...
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
ITM->TCR |= ITM_TCR_ITMENA_Msk;
}
int __io_putchar(int ch) {
ITM_SendChar(ch);
return ch;
}
int __io_getchar() {
int c = getchar();
while(c == EOF);
return c;
}
```
上述代码片段展示了如何重新定义 `_write` 及 `_read` 函数以便让 `printf` 和 `scanf` 正常工作。需要注意的是,这里假设已经正确设置了 ST-LINK/VISUALIZE 工具链以捕获来自目标板的信息流。
#### 使用 USART 模拟 `scanf`
另一种常见的方式是通过 UART 接收命令字符串,并解析成相应的数值或字符序列。下面给出了一段简单例子说明怎样接收整数型参数[^3]:
```c
UART_HandleTypeDef huart1;
/* 初始化 UART */
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief Receives an integer value from the user over serial port.
* Blocks until a valid number is received or timeout occurs.
*
* @param[out] pValue Pointer to store the parsed integer result.
* @retval Status of reception process.
*/
uint8_t getIntegerFromUser(int* pValue)
{
char buffer[32];
uint8_t status = ERROR;
memset(buffer, '\0', sizeof(buffer));
// Wait for data available on RX line with some reasonable time limit
if(HAL_UART_Receive(&huart1, (uint8_t*)buffer, sizeof(buffer)-1, 1000)!= HAL_OK)
goto exit_label;
sscanf((const char *)buffer,"%d",pValue);
status = SUCCESS;
exit_label:
return status;
}
```
这段代码实现了基本的数据交换机制——即等待直到接收到完整的数字表达式为止;之后再尝试将其转换为目标类型的变量存储起来供后续处理逻辑调用。
阅读全文