|
|
/*********************************************************
*Copyright (C), 2015, Shanghai Eastsoft Microelectronics Co., Ltd. *文件名: lib_printf.c *作 者: AE Team *版 本: V1.01 *日 期: 2021/06/09 *描 述: Printf功能库函数 *备 注: 本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。 **********************************************************/ #include "lib_printf.h"
#include <stdarg.h>
/***************************************************************
函数名:fputc 描 述:重定向c库函数printf到UART 输入值:。。。 输出值:。。。 返回值:。。。 ***************************************************************/ /*使用printf()函数需要调用微库:Use MicroLIB*/ int fputc(int ch, FILE *f) { //return ch;
uint32_t count = 0; FlagStatus status = RESET;
#if defined __PRINTF_USE_UART3__
UART_SendByte(UART3, (unsigned char) ch);
do { status = UART_GetFlagStatus(UART3, UART_FLAG_TB); count++; } while ((status == RESET) && (count != 0x1CE2));
UART_ClearITPendingBit(UART3, UART_FLAG_TC);
if (count == 0x1CE2) return -1;
#elif defined __PRINTF_USE_UART2__
UART_SendByte(UART2, (unsigned char) ch);
do { status = UART_GetFlagStatus(UART2, UART_FLAG_TC); count++; } while ((status == RESET) && (count != 0x1CE2));
UART_ClearITPendingBit(UART2, UART_FLAG_TC);
if (count == 0x1CE2) return -1;
#elif defined __PRINTF_USE_UART1__
UART_SendByte(UART1, (unsigned char) ch);
do { status = UART_GetFlagStatus(UART1, UART_FLAG_TC); count++; } while ((status == RESET) && (count != 0x1CE2));
UART_ClearITPendingBit(UART1, UART_FLAG_TC);
if (count == 0x1CE2) return -1;
#else
UART_SendByte(UART0, (unsigned char) ch);
do { status = UART_GetFlagStatus(UART0, UART_FLAG_TC); count++; } while ((status == RESET) && (count != 0x1CE2));
UART_ClearITPendingBit(UART0, UART_FLAG_TC);
if (count == 0x1CE2) return -1;
#endif
return (ch); }
#ifdef __clang__ /* 当使用的是idesigner编译器时,则不调用微库 */
/***************************************************************
函数名:itoa 描 述:将整形数据转换成字符串 输入值:radix =10 表示10进制,其他结果为0 value 要转换的整形数 buf 转换后的字符串 radix = 10 返回值:无 ***************************************************************/ static char *itoa(int value, char *string, int radix) { int i, d; int flag = 0; char *ptr = string;
/* This implementation only works for decimal numbers. */ if (radix != 10) { *ptr = 0; return string; }
if (!value) { *ptr++ = 0x30; *ptr = 0; return string; }
/* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-';
/* Make the value positive. */ value *= -1; }
for (i = 10000; i > 0; i /= 10) { d = value / i;
if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } }
/* Null terminate the string. */ *ptr = 0;
return string; }
/***************************************************************
描 述: 当使用idesigner时调用,格式化输出,类似于C库中的printf,但这里没有用到C库 输入值: UARTx 串口通道, Data 要发送到串口的内容的指针 ... 其他参数 返回值: 无 典型应用:UART_printf("\r\n this is a demo \r\n" ); UART_printf( "\r\n %d \r\n", i ); UART_printf( "\r\n %s \r\n", j ); ***************************************************************/ /* 未调用C库的时候可以使用此函数代替C库中的printf,但功能无printf全,
只支持\r \n %d %s */ ErrorStatus UART_printf(uint8_t *Data, ...) { UART_TypeDef *UARTx; const char *s; int d; char buf[16];
uint32_t Count = 0; ErrorStatus RET = SUCCESS; FlagStatus Status = RESET; va_list ap;
/**
** **使用宏定义选择使用哪一个串口 ** ***/ #if defined __PRINTF_USE_UART3__
UARTx = UART3;
#elif defined __PRINTF_USE_UART2__
UARTx = UART2;
#elif defined __PRINTF_USE_UART1__
UARTx = UART1;
#else
UARTx = UART0;
#endif
va_start(ap, Data);
while (*Data != 0) /* 判断是否到达字符串结束符 */ { if (*Data == 0x5c) /* '\' */ { switch (*++Data) { case 'r': /* 回车符 */ Count = 0; UART_SendByte(UARTx, 0x0d);
do { Status = UART_GetFlagStatus(UARTx, UART_FLAG_TB); Count++; } while ((Status == RESET) && (Count != 0x1CE2));
if (Count == 0x1CE2) RET = ERROR;
++Data; break;
case 'n': /* 换行符 */ Count = 0; UART_SendByte(UARTx, 0x0a);
do { Status = UART_GetFlagStatus(UARTx, UART_FLAG_TB); Count++; } while ((Status == RESET) && (Count != 0x1CE2));
if (Count == 0x1CE2) RET = ERROR;
++Data; break;
default: ++Data; break; } } else if (*Data == '%') { switch (*++Data) { case 's': /* 字符串 */ s = va_arg(ap, const char *);
for (; *s; s++) { Count = 0; UART_SendByte(UARTx, *s);
do { Status = UART_GetFlagStatus(UARTx, UART_FLAG_TB); Count++; } while ((Status == RESET) && (Count != 0x1CE2));
if (Count == 0x1CE2) RET = ERROR; }
++Data; break;
case 'd': /* 十进制 */ d = va_arg(ap, int); itoa(d, buf, 10);
for (s = buf; *s; s++) { Count = 0; UART_SendByte(UARTx, *s);
do { Status = UART_GetFlagStatus(UARTx, UART_FLAG_TB); Count++; } while ((Status == RESET) && (Count != 0x1CE2));
if (Count == 0x1CE2) RET = ERROR; }
++Data; break;
default: ++Data; break; } } else { Count = 0; UART_SendByte(UARTx, *Data++);
do { Status = UART_GetFlagStatus(UARTx, UART_FLAG_TB); Count++; } while ((Status == RESET) && (Count != 0x1CE2));
if (Count == 0x1CE2) RET = ERROR; } }
return RET; }
#endif
|