在 ARM 单片机上实现一个简单的 printf 函数,可以通过自定义 putchar 或 fputc 函数来重定向输出。以下是一个简单的实现示例,假设你将输出重定向到串口(UART)。
1. 实现 putchar 函数
首先,实现一个简单的 putchar 函数,用于将字符发送到串口。
#include "stm32f4xx_hal.h" // 根据你的芯片型号包含对应的 HAL 库
// 实现 putchar 函数
int putchar(int ch) {
// 发送字符到串口
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
2. 实现简单的 printf 函数
接下来,实现一个简单的 printf 函数,支持基本的格式(如 %d, %s, %c, %x 等)。
#include <stdarg.h> // 用于可变参数处理
// 简单的 printf 函数实现
void my_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt); // 初始化可变参数列表
while (*fmt) {
if (*fmt == '%') {
fmt++; // 跳过 '%'
switch (*fmt) {
case 'd': { // 处理整数
int val = va_arg(args, int);
if (val < 0) {
putchar('-');
val = -val;
}
char buffer[10];
int i = 0;
do {
buffer[i++] = (val % 10) + '0';
val /= 10;
} while (val > 0);
while (i > 0) {
putchar(buffer[--i]);
}
break;
}
case 's': { // 处理字符串
char *str = va_arg(args, char *);
while (*str) {
putchar(*str++);
}
break;
}
case 'c': { // 处理字符
char ch = va_arg(args, int);
putchar(ch);
break;
}
case 'x': { // 处理十六进制
unsigned int val = va_arg(args, unsigned int);
char buffer[8];
int i = 0;
do {
int digit = val % 16;
buffer[i++] = (digit < 10) ? (digit + '0') : (digit - 10 + 'A');
val /= 16;
} while (val > 0);
while (i < 8) {
buffer[i++] = '0'; // 补齐 8 位
}
while (i > 0) {
putchar(buffer[--i]);
}
break;
}
default:
putchar(*fmt); // 未知格式,直接输出
break;
}
} else {
putchar(*fmt); // 普通字符,直接输出
}
fmt++; // 移动到下一个字符
}
va_end(args); // 结束可变参数处理
}
3. 使用示例
在你的主程序中,可以像标准 printf 一样使用 my_printf 函数。
int main(void) {
// 初始化 HAL 库和串口
HAL_Init();
SystemClock_Config();
MX_USART2_UART_Init();
// 使用自定义的 printf 函数
my_printf("Hello, World!\n");
my_printf("Integer: %d\n", 1234);
my_printf("String: %s\n", "ARM Cortex-M");
my_printf("Character: %c\n", 'A');
my_printf("Hexadecimal: 0x%x\n", 0xABCD);
while (1) {
// 主循环
}
}
4. 代码说明
putchar: 将字符发送到串口。
my_printf: 支持 %d(整数)、%s(字符串)、%c(字符)和 %x(十六进制)等基本格式。
可变参数处理: 使用 va_list、va_start、va_arg 和 va_end 处理可变参数。
|