You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
321 lines
8.1 KiB
321 lines
8.1 KiB
/*********************************************************
|
|
*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
|
|
|
|
|