1. uart_register_t ---描述uart 端口寄存器使用情况
/* UART registers */
typedef volatile struct
{
uart_dr_reg_t DATA; /* data register 0x000 */
uint32_t RSR; /* Receive status/Error clear register 0x004 */
uint32_t unused_1[(0x018 - 0x008) >> 2]; /* unused */
uart_flag_reg_t FR; /* Flag register 0x018 */
uint32_t unused_2[(0x024 - 0x01C) >> 2]; /* unused */
uint32_t IBRD; /* Integer baud rate register 0x024 */
uint32_t FBRD; /* Fractional baud rate register 0x028 */
uart_lcr_reg_t LCRH; /* Line Control register 0x02C */
uart_cr_reg_t CR; /* Control register 0x030 */
uart_ifls_reg_t IFLS; /* Interrupt Fifo level select register 0x034 */
uart_int_reg_t IMSC; /* Interrupt mask set/clear register 0x038 */
uint32_t RIS; /* Raw Interrupt register 0x03C */
uart_int_reg_t MIS; /* Masked Interrupt register 0x040 */
uart_int_reg_t ICR; /* Interrupt Clear register 0x044 */
uint32_t DMACR; /* DMA Control register 0x048 */
uint32_t unused_3; /* unused */
uint32_t XFCR; /* XON/XOFF Control register 0x050 */
uint32_t XON1; /* Xon1 character for sw flow control 0x054 */
uint32_t XON2; /* Xon2 character for sw flow control 0x058 */
uint32_t XOFF1; /* Xoff1 character for sw flow control 0x05C */
uint32_t XOFF2; /* Xoff2 character for sw flow control 0x060 */
uint32_t unused_4[(0x100 - 0x064) >> 2]; /* unused */
uint32_t ABCR; /* Autobaud Control register 0x100 */
uint32_t ABSR; /* Autobaud Status register 0x104 */
uint32_t ABFMT; /* Autobaud Format register 0x108 */
uint32_t unused_5[(0x150 - 0x10C) >> 2]; /* unused */
uint32_t ABDR; /* Autobaud Divisor register 0x150 */
uint32_t ABDFR; /* Autobaud Divisor Fraction register 0x154 */
uint32_t ABMR; /* Autobaud Measurement register 0x158 */
uint32_t ABIMSC; /* Autobaud Interrupt Mask register 0x15C */
uint32_t ABRIS; /* Autobaud Raw Interrupt status register 0x160 */
uint32_t ABMIS; /* Autobaud Masked Interrupt register 0x164 */
uint32_t ABICR; /* Autobaud Interrupt Clear register 0x168 */
uint32_t unused_6[(0xFE0 - 0x16C) >> 2]; /* unused */
uint32_t PeriphID0; /* Peripheral id register0 0xFE0 */
uint32_t PeriphID1; /* Peripheral id register1 0xFE4 */
uint32_t PeriphID2; /* Peripheral id register2 0xFE8 */
uint32_t PeriphID3; /* Peripheral id register3 0xFEC */
uint32_t PCellID0; /* PrimeCell id register0 0xFF0 */
uint32_t PCellID1; /* PrimeCell id register1 0xFF4 */
uint32_t PCellID2; /* PrimeCell id register2 0xFF8 */
uint32_t PCellID3; /* PrimeCell id register3 0xFFC */
} uart_register_t;
2. uart_dr_reg_t --- uart 数据寄存器,采用8位数据位 或别的。
/* UART Data register Register */
typedef struct
{
bitfield_t Data :8;
bitfield_t Error :4;
bitfield_t unused :20;
} uart_dr_reg_t;
3. uart_flag_reg_t --- uart 标志位寄存器
/* UART Flag Register */
typedef struct
{
bitfield_t ClearToSend :1;
bitfield_t DataSetReady :1;
bitfield_t DataCarrierDetect :1;
bitfield_t Busy :1;
bitfield_t ReceiveFifoEmpty :1;
bitfield_t TransmitFifoFull :1;
bitfield_t ReceiveFifoFull :1;
bitfield_t TransmitFifoEmpty :1;
bitfield_t RingIndicator :1;
bitfield_t DCTS :1;
bitfield_t DDSR :1;
bitfield_t DDCD :1;
bitfield_t TERI :1;
bitfield_t RTXDIS :1;
bitfield_t unused :18;
} uart_flag_reg_t;
4. uart_lcr_reg_t --- uart 线路控制寄存器
/* UART Line Control Register */
typedef union
{
struct
{
bitfield_t SendBreak :1;
bitfield_t ParityEnable :1;
bitfield_t EvenParitySelect :1;
bitfield_t TwoStopBitsSelect :1;
bitfield_t FifoEnable :1;
bitfield_t WordLength :2;
bitfield_t StickParitySelect :1;
bitfield_t unused :24;
} Bit;
uint32_t Reg;
} uart_lcr_reg_t;
5. uart_cr_reg_t --- uart 控制寄存器
/* UART Control Register */
typedef union
{
struct
{
bitfield_t UartEnable :1;
bitfield_t Unused1 :2;
bitfield_t OversamplingFactor :1;
bitfield_t Unused2 :3;
bitfield_t LoopBackEnable :1;
bitfield_t TransmitEnable :1;
bitfield_t ReceiveEnable :1;
bitfield_t DataTransmitReady :1;
bitfield_t RequestToSend :1;
bitfield_t Unused3 :2;
bitfield_t RTSEnable :1;
bitfield_t CTSEnable :1;
bitfield_t unused3 :16;
} Bit;
uint32_t Reg;
} uart_cr_reg_t;
6 uart_ifls_reg_t --- uart 中断清楚/屏蔽寄存器
/* UART Interrupt Clear/Mask Register */
typedef struct
{
bitfield_t TxIntFifoLevel :3;
bitfield_t RxIntFifoLevel :3;
bitfield_t unused2 :26;
} uart_ifls_reg_t;
7。 uart_int_reg_t --- uart 中断寄存器
/* UART Interrupt Clear/Mask Register */
typedef union
{
struct
{
bitfield_t RingIndicatorModem :1;
bitfield_t ClearToSendModem :1;
bitfield_t DataCarrierDetectModem :1;
bitfield_t DataSetReadyModem :1;
bitfield_t Received :1;
bitfield_t Transmit :1;
bitfield_t ReceivedTimeout :1;
bitfield_t FramingError :1;
bitfield_t ParityError :1;
bitfield_t BreakError :1;
bitfield_t OverrunError :1;
bitfield_t XOFFInterrupt :1;
bitfield_t unused :20;
} Bit;
uint32_t Reg;
} uart_int_reg_t;
8。 uart 寄存器内存映射地址定义:
/* UART0 interface */
#define UART0_REG_START_ADDR 0x101FD000
#define UART0_REG_LENGTH CNTRL_REG_SIZE
#define UART0_REG_END_ADDR (UART0_REG_START_ADDR+UART0_REG_LENGTH-1)
/* UART1 interface */
#define UART1_REG_START_ADDR 0x101FB000
#define UART1_REG_LENGTH CNTRL_REG_SIZE
#define UART1_REG_END_ADDR (UART1_REG_START_ADDR+UART1_REG_LENGTH-1)
/* UART2 interface */
#define UART2_REG_START_ADDR 0x101F2000
#define UART2_REG_LENGTH CNTRL_REG_SIZE
#define UART2_REG_END_ADDR (UART2_REG_START_ADDR+UART2_REG_LENGTH-1)
/* UART3 interface */
#define UART3_REG_START_ADDR 0x101FE000
#define UART3_REG_LENGTH CNTRL_REG_SIZE
#define UART3_REG_END_ADDR (UART3_REG_START_ADDR+UART3_REG_LENGTH-1)
9. uart_baudrate_t --- uart 波特率定义:
typedef enum
{
BR110BAUD = 0x2F6A88,
BR1200BAUD = 0x0009C4,
BR2400BAUD = 0x0004E2,
BR9600BAUD = 0x200138,
BR38400BAUD = 0x08004E,
BR115200BAUD = 0x03001A,
BR230400BAUD = 0x02000D,
BR460800BAUD = 0x210006,
BR921600BAUD = 0x110003,
BR1843200BAUD = 0x290001,
BR3000000BAUD = 0x000001
} uart_baudrate_t;
10。 uart_stop_bits_t --- uart 停止位定义
// Stop bits number
typedef enum
{
ONE_STOPBIT = 0x0,
TWO_STOPBITS = 0x1
} uart_stop_bits_t;
11。uart_data_bits_t --- uart 数据位定义
// Data bits number
typedef enum
{
DATABITS_5 = 0x0,
DATABITS_6 = 0x1,
DATABITS_7 = 0x2,
DATABITS_8 = 0x3
} uart_data_bits_t;
12。uart_parity_bit_t --- uart 奇偶校验位定义
// Parity definition
typedef enum
{
NOPARITY_BIT,
EVEN_PARITY_BIT,
ODD_PARITY_BIT,
PARITY_0_BIT,
PARITY_1_BIT
} uart_parity_bit_t;
13。 uart_error_t --- uart 错误值定义,这个一般都是用来函数返回时用的
typedef enum
{
/* standard error defines */
UART_UNSUPPORTED_HW = HCL_UNSUPPORTED_HW, /* (-2) */
UART_ERROR = HCL_ERROR, /* (-1) */
UART_OK = HCL_OK /* (0) */
} uart_error_t;
14。 uart_init() --- uart 初始化函数:
uart_error_t UART_Init(uart_baudrate_t baudrate, uart_parity_bit_t parity_bit,
uart_stop_bits_t stop_bits, uart_data_bits_t data_bits)
{
/* Variable to flush ~Rx fifo */
volatile uint32_t dataflushed;
uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
gpio_register_t *pGpio0Regs = (gpio_register_t *) GPIO0_REG_START_ADDR;
//定义个块物理内存区,用来存放log,起始地址是__LOG_START
logBuffer = &__LOG_START;
memset(logBuffer, 0, &__LOG_END - logBuffer);
// Reset main registers : really need ?
pUartRegs->CR.Reg = 0; /* RTL 4 : reset value = 0x300 */
pUartRegs->RSR = 0;
pUartRegs->IMSC.Reg = 0;
// Control register
pUartRegs->CR.Bit.UartEnable = 1; /* enable Uart functionality */
//configure baudrate (MUST be performed before a LCRH write)
pUartRegs->IBRD = (uint32_t) (baudrate & MASK_ALL16); /* program baudrate: integer part */
pUartRegs->FBRD = (uint32_t) (baudrate >> 16); /* program baudrate: fractional part*/
//configure line control register
pUartRegs->LCRH.Reg = 0;
pUartRegs->LCRH.Bit.SendBreak = 0; /* Disable sendbreak */
pUartRegs->LCRH.Bit.FifoEnable = 1; /* enable Fifo */
pUartRegs->LCRH.Bit.WordLength = (data_bits >> 1 - 1); /* 00=5bits 01=6bits 10=7bits 11=8bits */
pUartRegs->LCRH.Bit.TwoStopBitsSelect = stop_bits; /* 0=1 stop bits 1=2 stop bits */
pUartRegs->LCRH.Bit.ParityEnable = 0;
pUartRegs->LCRH.Bit.StickParitySelect = 0;
pUartRegs->LCRH.Bit.EvenParitySelect = 0;
/* Enable Alternate function A : GPIO[56-57] are under control of UART1 */
pGpio0Regs->gpio_afsla |= 0xC000; /* Alt A: Set bits 14 & 15: UART1 Transmitted Serial Data and UART1 Received Serial Data */
pGpio0Regs->gpio_afslb &= ~((uint32_t) 0xC000); /* Alt A: Set bits 14 & 15: UART1 Transmitted Serial Data and UART1 Received Serial Data */
/* Set to 4 characters the interrupt FIFO level for transmit and receive */
pUartRegs->IFLS.TxIntFifoLevel = 2;
pUartRegs->IFLS.RxIntFifoLevel = 2;
/* All It are cleared */
pUartRegs->ICR.Bit.ReceivedTimeout = 1;
pUartRegs->ICR.Bit.Received = 1;
pUartRegs->ICR.Bit.FramingError = 1;
pUartRegs->ICR.Bit.OverrunError = 1;
pUartRegs->ICR.Bit.ParityError = 1;
pUartRegs->ICR.Bit.BreakError = 1;
pUartRegs->ICR.Bit.ReceivedTimeout = 1;
pUartRegs->ICR.Bit.Received = 1;
pUartRegs->ICR.Bit.Transmit = 1;
/* Enable IT */
pUartRegs->IMSC.Reg = 0;
pUartRegs->IMSC.Bit.BreakError = 1;
pUartRegs->IMSC.Bit.ParityError = 1;
pUartRegs->IMSC.Bit.FramingError = 1;
pUartRegs->IMSC.Bit.OverrunError = 1;
pUartRegs->CR.Bit.ReceiveEnable = 1; /* enable RX */
while (!IsRxfifoEmpty())
dataflushed = pUartRegs->DATA.Data;
pUartRegs->CR.Bit.TransmitEnable = 1; /* enable TX */
while (!IsTxfifoEmpty());
return UART_OK;
}
15. puts() --- 打印字符串,也就是输出字符到串口上:
void puts(char *buf)
{
uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
while (*buf)
{
while (IsTxfifoFull());
//打印字符串的同时,也把字符串备份到物理内存区
*logBuffer++ = *buf;
if (logBuffer >= &__LOG_END)
logBuffer = &__LOG_START;
pUartRegs->DATA.Data = *buf++;
}
*logBuffer = 0;
}
16. 一些判断函数:
static bool_t IsRxfifoEmpty(void)
{
uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
return (pUartRegs->FR.ReceiveFifoEmpty) ? TRUE : FALSE;
}
static bool_t IsTxfifoFull(void)
{
uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
return (pUartRegs->FR.TransmitFifoFull) ? TRUE : FALSE;
}
static bool_t IsTxfifoEmpty(void)
{
uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
return (pUartRegs->FR.TransmitFifoEmpty) ? TRUE : FALSE;
}
17. UART_flush() --- flush uart, 有时后uart input 不正常,可以用这个函数来flush uart, 之后uart就正常了。
void UART_flush(void)
{
while (!IsTxfifoEmpty());
}
18 . writeHex() --- 输出整形变量值到串口终端
void writeHex(uint32_t data)
{
const char hex[16] = "0123456789ABCDEF";
char str[2] =
{ '0', 0 };
uint8_t i;
for (i = 0; i <= 7; i++)
{
str[0] = hex[(data & 0xf0000000) >> 28];
puts(str);
data &= 0x0fffffff;
data = data << 4;
}
}