📄 hw_serial.c
字号:
* 函数描述: 向serial port发送一个字符
* 入口参数: c -- 待发送的字符
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void serial_putc(const char c)
{
#ifdef DLL
if (c == '\n')
KDrvUartWriteChar('\r');
KDrvUartWriteChar(c);
#else
if (c == '\n')
Uart_WriteChar(DebugPort, '\r');
Uart_WriteChar(DebugPort, c);
#endif
}
/**************************************************************************
* 函数描述: 向serial port发送字符串
* 入口参数: s -- 待发送的字符串
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void serial_puts(const char *s)
{
while (*s)
{
serial_putc(*s++);
}
}
/**************************************************************************
* 函数描述: 从serial port接收字符
* 入口参数: 无
* 出口参数: 无
* 返回值: 接收到的字符
***************************************************************************/
int serial_getc(void)
{
#ifdef DLL
return KDrvUartReadChar();
#else
return Uart_ReadChar(DebugPort);
#endif
}
/**************************************************************************
* 函数描述: serial port FIFO是否有数据
* 入口参数: 无
* 出口参数: 无
* 返回值: 1 -- 表示FIFO有数据
* 0 -- 表示FIFO没有数据
***************************************************************************/
int serial_tstc(void)
{
return Uart_Tstc(DebugPort);
}
/**************************************************************************
* 函数描述: 打印trace
* 入口参数: 可变参数
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void serial_printf(const char *fmt, ...)
{
va_list args;
UINT32 i;
char printbuffer[CFG_PBSIZE];
va_start(args, fmt);
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
i = vsprintf(printbuffer, fmt, args);
va_end(args);
/* Print the string */
serial_puts(printbuffer);
}
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
UINT32 num;
int i, base;
char * str;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'q' for integer fields */
for (str = buf ; *fmt ; ++fmt)
{
if (*fmt != '%')
{
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt)
{
case '-':
flags |= LEFT;
goto repeat;
case '+':
flags |= PLUS;
goto repeat;
case ' ':
flags |= SPACE;
goto repeat;
case '#':
flags |= SPECIAL;
goto repeat;
case '0':
flags |= ZEROPAD;
goto repeat;
}
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*')
{
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0)
{
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.')
{
++fmt;
if (isdigit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*')
{
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'q')
{
qualifier = *fmt;
++fmt;
}
/* default base */
base = 10;
switch (*fmt)
{
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
continue;
case 's':
s = va_arg(args, char *);
if (!s)
s = "<NULL>";
len = strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
continue;
case 'p':
if (field_width == -1)
{
field_width = 2 * sizeof(void *);
flags |= ZEROPAD;
}
str = number(str, (UINT32)va_arg(args, void *), 16, field_width, precision, flags);
continue;
case 'n':
if (qualifier == 'l')
{
INT32 * ip = va_arg(args, INT32*);
*ip = (str - buf);
}
else
{
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
*str++ = '%';
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}
if (qualifier == 'l')
num = va_arg(args, INT32);
else if (qualifier == 'h')
{
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (short) num;
}
else if (flags & SIGN)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
str = number(str, num, base, field_width, precision, flags);
}
*str = '\0';
return str -buf;
}
/**************************************************************************
* 函数描述: 从PC的串口控制台接收用户输入的数据
* 入口参数: fmt -- 可变参数指针
* 出口参数: 无
* 返回值: count -- 接收到的字符数
***************************************************************************/
int serial_scanf(char *fmt, ...)
{
va_list ap;
int count;
va_start(ap, fmt);
count = vfscanf(1, fmt, ap);
va_end(ap);
return (count);
}
/**************************************************************************
* 函数描述: 从PC的串口控制台接收用户输入的数据,供scanf调用
* 入口参数: fp -- 判断条件
* fmt -- 可变参数指针
* ap -- 变参链表变量
* 出口参数: 无
* 返回值: count -- 接收到的字符数
***************************************************************************/
int vfscanf(int fp, char* fmt, va_list ap)
{
int count;
char buf[MAXLN + 1];
int i;
for (i = 0;i < MAXLN;i++)
{
ReInput:
buf[i] = serial_getc();
if ((buf[i] >= 32) && (i < (MAXLN - 1))) //if not press control key
{
serial_printf("%c", buf[i]); //print the press key
continue;
}
if (buf[i] == 8) //if press backspace
{
if (i == 0)
goto ReInput;
i--;
serial_printf("%c", 8); //cursor back
serial_printf("%c", 32); //print space
serial_printf("%c", 8); //cursor back
goto ReInput;
}
if ((buf[i] == 13) || (i == (MAXLN - 1))) //if press enter or equal buf[] size
{
buf[i] = '\0';
serial_printf("\n");
break;
}
//if press other control key
goto ReInput;
}
count = vsscanf(buf, fmt, ap);
return (count);
}
/*************************************************************
* vsscanf(buf,fmt,ap)
*/
int vsscanf(char* buf, char* s, va_list ap)
{
int count, noassign, width, base, lflag;
char *t, tmp[MAXLN];
count = noassign = width = lflag = 0;
while (*s && *buf)
{
// while ((isspace(*s))) s++;
while ((chartypetbl[(int)*s] & (_S | _C))) s++;
if (*s == '%')
{
s++;
for (; *s; s++)
{
if (serial_strchr("dibouxcsefg%", *s))
break;
if (*s == '*')
noassign = 1;
else if (*s == 'l' || *s == 'L')
lflag = 1;
else if (*s >= '1' && *s <= '9')
{
for (t = s; isdigit(*s); s++);
serial_strncpy(tmp, t, s - t);
tmp[s - t] = '\0';
atob((unsigned int*)&width, tmp, 10);
s--;
}
}
if (*s == 's')
{
// while(isspace (*buf)) buf++;
while ((chartypetbl[(int)*buf] & (_S | _C))) buf++;
if (!width)
width = serial_strcspn(buf, ISSPACE);
if (!noassign)
{
serial_strncpy(t = va_arg(ap, char *), buf, width);
t[width] = '\0';
}
buf += width;
}
else if (*s == 'c')
{
if (!width)
width = 1;
if (!noassign)
{
serial_strncpy(t = va_arg(ap, char *), buf, width);
t[width] = '\0';
}
buf += width;
}
else if (serial_strchr("dobxu", *s))
{
// while (isspace (*buf)) buf++;
while ((chartypetbl[(int)*buf] & (_S | _C))) buf++;
if (*s == 'd' || *s == 'u')
base = 10;
else if (*s == 'x')
base = 16;
else if (*s == 'o')
base = 8;
else if (*s == 'b')
base = 2;
if (!width)
{
// if (isspace (*(s + 1)) || *(s + 1) == 0)
if ((chartypetbl[(int)*(s + 1)] & (_S | _C)) || *(s + 1) == 0)
width = serial_strcspn(buf, ISSPACE);
else
width = serial_strchr(buf, *(s + 1)) - buf;
}
serial_strncpy(tmp, buf, width);
tmp[width] = '\0';
buf += width;
if (!noassign)
atob((unsigned int*)va_arg(ap, int), tmp, base);
}
if (!noassign)
count++;
width = noassign = lflag = 0;
s++;
}
else
{
// while (isspace (*buf)) buf++;
while ((chartypetbl[(int)*buf] & (_S | _C))) buf++;
if (*s != *buf)
break;
else
s++, buf++;
}
}
return (count);
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -