📄 uart.c
字号:
/**************************************************************************************************
*
* Copyright (c) 2001 - 2003 Winbond Electronics Corp. All rights reserved.
*
* FILENAME
* uart.c
*
* VERSION
* 1.0
*
* DESCRIPTION
* This file contains the uart initial routine and Tx/Rx functions.
*
* DATA STRUCTURES
* None
*
* FUNCTIONS
* 1. UART_SetBaudRate()
* 2. UART_Initialize()
* 3. UART_getchar()
* 4. UART_putchar()
* 5. UART_PutString()
* 6. PutRepChar()
* 7. PutStringReverse()
* 8. PutNumber()
* 9. FormatItem()
* 10. UART_printf()
* 11. HexDumpBuffer()
*
* HISTORY
* 04/14/2003 Ver 1.0 Created by PC30 YCHuang
*
* 04/18/2003 Modified by PC30 MNCheng
* REMARK
* None
*
*************************************************************************************************/
#include "740defs.h"
#define FALSE 0
#define TRUE 1
#define vaStart(list, param) list = (char *)((int)¶m + sizeof(param))
#define vaArg(list, type) ((type *)(list += sizeof(type)))[-1]
void UART_SetBaudRate(uint32 baud_rate)
{
uint32 baud_value;
/* First, compute the baudrate divisor. */
baud_value = (EXT_CLOCK_RATE / (baud_rate * 16));
if ((EXT_CLOCK_RATE % (baud_rate * 16)) > ((baud_rate * 16) / 2))
baud_value++;
baud_value -= 2;
/* Set the divisor latch bit. */
UART_LCR = 0x80;
/* First write the LSB of the baud rate divisor. */
UART_LSB = (uint8) baud_value;
/* Now write the MSB of the baud rate divisor. */
UART_MSB = (uint8) (baud_value >> 8);
/* Now that the baud rate has been set turn off Divisor Latch
to reference data in line control */
UART_LCR &= 0x7F;
}
int UART_Initialize(uint32 baud_rate)
{
/* Reset the TX/RX FIFOs */
UART_FCR = 0x06;
/* Setup baud rate */
UART_SetBaudRate(baud_rate);
/* Setup none parity, 8 data bits, and 1 stop bits */
UART_LCR = 0x03;
/* Timeout if more than ??? bits xfer time */
UART_TOR = (0x80+0x20);
/* Setup Fifo trigger level and enable FIFO */
UART_FCR = 0xC7;
return 0;
}
char UART_getchar()
{
/* Wait until the RX FIFO data ready */
while (!(UART_LSR & 0x1));
/* Transmit the character */
return (UART_RX);
}
void UART_putchar(char ch)
{
/* Wait until the transmitter buffer is empty */
while (!(UART_LSR & 0x20));
/* Transmit the character */
UART_TX = ch;
if (ch == '\n')
{
/* Wait until the transmitter buffer is empty */
while (!(UART_LSR & 0x20));
UART_TX = '\r';
}
}
void UART_PutString(char *string)
{
while (*string != '\0')
{
UART_putchar(*string);
string++;
}
}
void PutRepChar(char c, int count)
{
while (count--)
UART_putchar(c);
}
void PutStringReverse(char *s, int index)
{
while ((index--) > 0)
UART_putchar(s[index]);
}
void PutNumber(int value, int radix, int width, char fill)
{
char buffer[40];
int bi = 0;
uint32 uvalue;
uint16 digit;
uint16 left = FALSE;
uint16 negative = FALSE;
if (fill == 0)
fill = ' ';
if (width < 0)
{
width = -width;
left = TRUE;
}
if (width < 0 || width > 80)
width = 0;
if (radix < 0)
{
radix = -radix;
if (value < 0)
{
negative = TRUE;
value = -value;
}
}
uvalue = value;
do
{
if (radix != 16)
{
digit = uvalue % radix;
uvalue = uvalue / radix;
}
else
{
digit = uvalue & 0xf;
uvalue = uvalue >> 4;
}
buffer[bi] = digit + ((digit <= 9) ? '0' : ('A' - 10));
bi++;
if (uvalue != 0)
{
if ((radix == 10)
&& ((bi == 3) || (bi == 7) || (bi == 11) | (bi == 15)))
{
buffer[bi++] = ',';
}
}
}
while (uvalue != 0);
if (negative)
{
buffer[bi] = '-';
bi += 1;
}
if (width <= bi)
PutStringReverse(buffer, bi);
else
{
width -= bi;
if (!left)
PutRepChar(fill, width);
PutStringReverse(buffer, bi);
if (left)
PutRepChar(fill, width);
}
}
char *FormatItem(char *f, int a)
{
char c;
int fieldwidth = 0;
int leftjust = FALSE;
int radix = 0;
char fill = ' ';
if (*f == '0')
fill = '0';
while ((c = *f++) != 0)
{
if (c >= '0' && c <= '9')
{
fieldwidth = (fieldwidth * 10) + (c - '0');
}
else
switch (c)
{
case '\000':
return (--f);
case '%':
UART_putchar('%');
return (f);
case '-':
leftjust = TRUE;
break;
case 'c':
{
if (leftjust)
UART_putchar(a & 0x7f);
if (fieldwidth > 0)
PutRepChar(fill, fieldwidth - 1);
if (!leftjust)
UART_putchar(a & 0x7f);
return (f);
}
case 's':
{
if (leftjust)
UART_PutString((char *)a);
if (fieldwidth > strlen((char *)a))
PutRepChar(fill,
fieldwidth - strlen((char *)a));
if (!leftjust)
UART_PutString((char *)a);
return (f);
}
case 'd':
case 'i':
radix = -10;
break;
case 'u':
radix = 10;
break;
case 'x':
radix = 16;
break;
case 'X':
radix = 16;
break;
case 'o':
radix = 8;
break;
default:
radix = 3;
break; /* unknown switch! */
}
if (radix)
break;
}
if (leftjust)
fieldwidth = -fieldwidth;
PutNumber(a, radix, fieldwidth, fill);
return (f);
}
void UART_printf(char *f, ...) /* variable arguments */
{
char *argP;
vaStart(argP, f); /* point at the end of the format string */
while (*f)
{ /* this works because args are all ints */
if (*f == '%')
f = FormatItem(f + 1, vaArg(argP, int));
else
UART_putchar(*f++);
}
}
void HexDumpBuffer(char str[], uint8 *buf, int size)
{
int idx, i;
UART_printf("%s -> 0x%X\n", str, (int)buf);
idx = 0;
while (size > 0)
{
for (i = 0; i < 16; i++)
UART_printf("%02x ", buf[idx + i]);
UART_printf(" ");
for (i = 0; i < 16; i++)
{
if ((buf[idx + i] >= 0x20) && (buf[idx + i] < 127))
UART_printf("%c", buf[idx + i]);
else
UART_printf(".");
size--;
}
idx += 16;
UART_printf("\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -