JN5169具有两个通用异步接收器/发送器(UART)串行通信接口。 它们提供与以FIFO模式运行的行业标准16550A器件相似的操作功能。这些接口对传入的串行数据执行串行到并行转换,并对从CPU到外部设备的传出数据执行并行到串行转换。 在两个方向上,可配置的FIFO缓冲区(默认深度为16字节)使CPU可以在每个事务中读写多个字符。 这意味着,CPU不再需要逐个字符地处理数据,并且会增加相关的处理器开销。 UART具有以下功能:
注:这里描述的 UART 操作假设外设时钟运行在 16MHz,时钟来自一个外部晶体振荡器。不建议用户在任何其他时钟下运行 UART。
可以将UART0和UART1都配置为使用标准或备用DIO线,如表8所示。此外,可以将UART0配置为以2线模式使用(其中未配置CTS0和RTS0),并且可以配置UART1 在1线模式下(未配置RXD1)。 这些释放的DIO引脚随后可用于其他目的。
可以使用函数vAHI_UartSetLocation()将UART0信号从DIO4-7移至DIO12-15。 可以使用相同的功能将UART1信号分别从DIO14和DIO15移至DIO11和DIO9。 如果需要此功能,则必须在启用UART之前调用它。
备注:在自动流控制阈值设置为15的情况下,当接收FIFO即将满时,UART模块中的硬件流控制将取消RTS。 在某些情况下,已经观察到,正在传输数据的远程设备不能对断言的CTS做出足够迅速的响应,而是继续传输数据。 在这些情况下,数据将在接收FIFO溢出中丢失。
UART 使用以下信号与一个外部设备相连:
如果 UART 只使用信号 RxD 和 TxD,就表明 UART 工作在 2 线模式。如果 UART 使用上面全部 4 个信号,就表明 UART 工作在 4 线模式并执行流控制。 在 JN5169 器件上:
UART 的发送和接收通路每个都有一个 FIFO 缓冲区,它允许和外部设备执行多字节的串行传输:
FIFO 包含在 RAM 中,由应用来定义。每个 FIFO 的大小可以从 16 个字节直至 2047 个字节。
在本地设备上,CPU 可以一次性向 FIFO 写入/读出一个字节和一个数据块。读/写通路互相独立,因此发送和接收单独出现。由一个 DMA(直接存储器存取)引擎来处理 FIFO 和 TxD/RxD之间的数据移动,不需要 CPU 的参与。
在 2 线模式下,UART 只使用信号线 TxD 和 RxD。只要发送设备方便(例如,当发送 FIFO包含一些数据时),可以不做任何通知就发送数据。数据还也可以根据发送设备的方便不做任何通知就接收。这可能会产生问题和导致数据丢失,例如,接收设备可能在接收 FIFO 中没有足够的空间来接收发送过来的数据。
在 4 线模式下,UART0 使用信号线 TxD、RxD、RTS 和 CTS,允许执行流控制,保证发送的数据总是能接收到。流控制的一般原理在下面描述。
RTS 和 CTS 线是标志,用来指示数据在设备之间安全传输。一个设备上的 RTS 线连接到另一个设备的 CTS 线。
目标设备命令源设备应该何时给它发送数据,如下所述:
在 1 线模式下,UART1 根据发送设备方便,在不通知的情况下使用 TxD 线发送数据。该模式下不接收数据,也不使用 RxD 线(因此,相关的 DIO 引脚可以用作其他用途)
NXP JN5169 UART集成外设API函数
#define UART E_AHI_UART_0
#define TRUE (1) /* page 207 K+R 2nd Edition */
#define FALSE (0)
/* Value enumerations: UART */
#define E_AHI_UART_RATE_4800 (0)
#define E_AHI_UART_RATE_9600 (1)
#define E_AHI_UART_RATE_19200 (2)
#define E_AHI_UART_RATE_38400 (3)
#define E_AHI_UART_RATE_76800 (4)
#define E_AHI_UART_RATE_115200 (5)
#define E_AHI_UART_WORD_LEN_5 (0)
#define E_AHI_UART_WORD_LEN_6 (1)
#define E_AHI_UART_WORD_LEN_7 (2)
#define E_AHI_UART_WORD_LEN_8 (3)
#define E_AHI_UART_FIFO_LEVEL_1 (0)
#define E_AHI_UART_FIFO_LEVEL_4 (1)
#define E_AHI_UART_FIFO_LEVEL_8 (2)
#define E_AHI_UART_FIFO_LEVEL_14 (3)
#define E_AHI_UART_LS_ERROR (0x80)
#define E_AHI_UART_LS_TEMT (0x40)
#define E_AHI_UART_LS_THRE (0x20)
#define E_AHI_UART_LS_BI (0x10)
#define E_AHI_UART_LS_FE (0x08)
#define E_AHI_UART_LS_PE (0x04)
#define E_AHI_UART_LS_OE (0x02)
#define E_AHI_UART_LS_DR (0x01)
#define E_AHI_UART_MS_CTS (0x10)
#define E_AHI_UART_MS_DCTS (0x01)
#define E_AHI_UART_INT_MODEM (0)
#define E_AHI_UART_INT_TX (1)
#define E_AHI_UART_INT_RXDATA (2)
#define E_AHI_UART_INT_RXLINE (3)
#define E_AHI_UART_INT_TIMEOUT (6)
#define E_AHI_UART_TX_RESET (TRUE)
#define E_AHI_UART_RX_RESET (TRUE)
#define E_AHI_UART_TX_ENABLE (FALSE)
#define E_AHI_UART_RX_ENABLE (FALSE)
#define E_AHI_UART_EVEN_PARITY (TRUE)
#define E_AHI_UART_ODD_PARITY (FALSE)
#define E_AHI_UART_PARITY_ENABLE (TRUE)
#define E_AHI_UART_PARITY_DISABLE (FALSE)
#define E_AHI_UART_1_STOP_BIT (TRUE)
#define E_AHI_UART_2_STOP_BITS (FALSE)
#define E_AHI_UART_RTS_HIGH (TRUE)
#define E_AHI_UART_RTS_LOW (FALSE)
#define E_AHI_UART_FIFO_ARTS_LEVEL_8 (0)
#define E_AHI_UART_FIFO_ARTS_LEVEL_11 (1)
#define E_AHI_UART_FIFO_ARTS_LEVEL_13 (2)
#define E_AHI_UART_FIFO_ARTS_LEVEL_15 (3)
/*发送单个字符*/
PRIVATE void vPutChar(unsigned char c)
{
while (!(u8AHI_UartReadLineStatus(UART) & E_AHI_UART_LS_THRE)); /*发送FIFO为空*/
vAHI_UartWriteData(UART, c); /*写入要发送的字符*/
/*
发送移位寄存器为空或者发送FIFO为空,即等待发送完毕
E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT = 0x20 | 0x40 = 0x60
*/
while ((u8AHI_UartReadLineStatus(UART) & (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT))
!= (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT));
}
/*发送字符串*/
PRIVATE void vPutStrs(unsigned char *str)
{
while(*str){
vPutChar(*str++);
}
}
/*初始化串口*/
PRIVATE void vUartInit(void)
{
#if (UART == E_AHI_UART_0)
vAHI_UartSetRTSCTS(UART, FALSE); /* UART0 2线模式。Disable use of CTS/RTS */
#endif
vAHI_UartEnable(UART);
//复位指定UART的发送和接收FIFO,并将FIFO触发级别设置为单字节触发
vAHI_UartReset(UART,
TRUE, /* 复位收发FIFO*/
TRUE);
vAHI_UartSetBaudRate(UART, E_AHI_UART_RATE_115200); /* 设置波特率*/
}
/*主函数*/
PUBLIC void AppColdStart (void)
{
vAHI_WatchdogStop();
(void)u32AHI_Init();
vUartInit();
vPutStrs((uint8*)"System Ready!\n");
while (1) {
vPutStrs((uint8*)"System Ready!\n");
}
}
/*热启动函数*/
PUBLIC void AppWarmStart (void)
{
AppColdStart();
}
#define UART E_AHI_UART_0
#define RECV_MAX_LEN 30 //最长接收字符长度
uint8 recv_buf[RECV_MAX_LEN]; //接收缓冲区
uint8 recv_len; //已接收的字符长度
PRIVATE void vAHI_DelayXms(uint32 n)
{
uint32 temp;
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); /* 关闭滴答定时器 */
vAHI_TickTimerWrite(0); /* 设置起始值 */
vAHI_TickTimerInterval(16000 * n); /* 设置参照值 */
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_STOP); /* 到达参考值停止计数 */
vAHI_TickTimerIntEnable(FALSE); /* 关闭中断 */
do{
temp = u32AHI_TickTimerRead();
}while(temp < 16000 * n);//向上计数
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); /* 关闭滴答定时器 */
}
/*发送单个字符*/
PRIVATE void vPutChar(unsigned char c)
{
while (!(u8AHI_UartReadLineStatus(UART) & E_AHI_UART_LS_THRE)); /*发送FIFO为空*/
vAHI_UartWriteData(UART, c); /*写入要发送的字符*/
/*
发送移位寄存器为空或者发送FIFO为空,即等待发送完毕
E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT = 0x20 | 0x40 = 0x60
*/
while ((u8AHI_UartReadLineStatus(UART) & (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT))
!= (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT));
}
/*发送字符串*/
PRIVATE void vPutStrs(unsigned char *str)
{
while(*str){
vPutChar(*str++);
}
}
/*UART0中断回调函数*/
PRIVATE void vCbUart0 (uint32 u32Device, uint32 u32ItemBitmap)
{
uint8 recv;
if(E_AHI_DEVICE_UART0 == u32Device){
//UART0中断
if(E_AHI_UART_INT_RXDATA == u32ItemBitmap){
//接收数据可用中断
recv = u8AHI_UartReadData(UART);
if(recv != 0x0d && (recv_len < RECV_MAX_LEN - 2)){
//回车0x0d,换行0x0a
recv_buf[recv_len++] = recv;
}
else{
recv_buf[recv_len++] = '\0';
vPutStrs(recv_buf);
recv_len = 0;
}
}
}
}
/*初始化串口*/
PRIVATE void vUartInit(void)
{
#if (UART == E_AHI_UART_0)
vAHI_UartSetRTSCTS(UART, FALSE); /* UART0 2线模式。Disable use of CTS/RTS */
#endif
vAHI_UartEnable(UART);
//复位指定UART的发送和接收FIFO,并将FIFO触发级别设置为单字节触发
vAHI_UartReset(UART,
TRUE, /* 复位收发FIFO*/
TRUE);
vAHI_UartSetBaudRate(UART, E_AHI_UART_RATE_115200); /* 设置波特率*/
/*启用接收数据可用中断,将接收FIFO触发级别设置为单字节触发。*/
vAHI_UartSetInterrupt(UART, FALSE, FALSE, FALSE, TRUE, E_AHI_UART_FIFO_LEVEL_1);
/*UART0中断回调函数*/
vAHI_Uart0RegisterCallback(vCbUart0);
}
PUBLIC void AppColdStart (void)
{
vAHI_WatchdogStop();
(void)u32AHI_Init();
recv_len = 0;
vUartInit();
vAHI_DelayXms(100);
vPutStrs((uint8*)"System Ready!\n");
while (1) {
vAHI_DelayXms(500);
vPutStrs((uint8*)"System Ready!\n");
}
}
PUBLIC void AppWarmStart (void)
{
AppColdStart();
}
#define UART E_AHI_UART_1
/*发送单个字符*/
PRIVATE void vPutChar(unsigned char c)
{
while (!(u8AHI_UartReadLineStatus(UART) & E_AHI_UART_LS_THRE)); /*发送FIFO为空*/
vAHI_UartWriteData(UART, c); /*写入要发送的字符*/
/*
发送移位寄存器为空或者发送FIFO为空,即等待发送完毕
E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT = 0x20 | 0x40 = 0x60
*/
while ((u8AHI_UartReadLineStatus(UART) & (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT))
!= (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT));
}
/*发送字符串*/
PRIVATE void vPutStrs(unsigned char *str)
{
while(*str){
vPutChar(*str++);
}
}
/*初始化串口*/
PRIVATE void vUartInit(void)
{
#if (UART == E_AHI_UART_1)
vAHI_UartTxOnly(UART, TRUE); /* UART1 1线模式*/
#endif
vAHI_UartEnable(UART);
//复位指定UART的发送和接收FIFO,并将FIFO触发级别设置为单字节触发
vAHI_UartReset(UART,
TRUE, /* 复位收发FIFO*/
TRUE);
vAHI_UartSetBaudRate(UART, E_AHI_UART_RATE_115200); /* 设置波特率*/
}
/*主函数*/
PUBLIC void AppColdStart (void)
{
vAHI_WatchdogStop();
(void)u32AHI_Init();
vUartInit();
vPutStrs((uint8*)"System Ready!\n");
while (1) {
vPutStrs((uint8*)"System Ready!\n");
}
}
/*热启动函数*/
PUBLIC void AppWarmStart (void)
{
AppColdStart();
}
#define UART E_AHI_UART_1
#define RECV_MAX_LEN 30 //最长接收字符长度
uint8 recv_buf[RECV_MAX_LEN]; //接收缓冲区
uint8 recv_len; //已接收的字符长度
PRIVATE void vAHI_DelayXms(uint32 n)
{
uint32 temp;
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); /* 关闭滴答定时器 */
vAHI_TickTimerWrite(0); /* 设置起始值 */
vAHI_TickTimerInterval(16000 * n); /* 设置参照值 */
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_STOP); /* 到达参考值停止计数 */
vAHI_TickTimerIntEnable(FALSE); /* 关闭中断 */
do{
temp = u32AHI_TickTimerRead();
}while(temp < 16000 * n);//向上计数
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); /* 关闭滴答定时器 */
}
/*发送单个字符*/
PRIVATE void vPutChar(unsigned char c)
{
while (!(u8AHI_UartReadLineStatus(UART) & E_AHI_UART_LS_THRE)); /*发送FIFO为空*/
vAHI_UartWriteData(UART, c); /*写入要发送的字符*/
/*
发送移位寄存器为空或者发送FIFO为空,即等待发送完毕
E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT = 0x20 | 0x40 = 0x60
*/
while ((u8AHI_UartReadLineStatus(UART) & (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT))
!= (E_AHI_UART_LS_THRE | E_AHI_UART_LS_TEMT));
}
/*发送字符串*/
PRIVATE void vPutStrs(unsigned char *str)
{
while(*str){
vPutChar(*str++);
}
}
/*UART1中断回调函数*/
PRIVATE void vCbUart1 (uint32 u32Device, uint32 u32ItemBitmap)
{
uint8 recv;
if(E_AHI_DEVICE_UART1== u32Device){
//UART1中断
if(E_AHI_UART_INT_RXDATA == u32ItemBitmap){
//接收数据可用中断
recv = u8AHI_UartReadData(UART);
if(recv != 0x0d && (recv_len < RECV_MAX_LEN - 2)){
//回车0x0d,换行0x0a
recv_buf[recv_len++] = recv;
}
else{
recv_buf[recv_len++] = '\0';
vPutStrs(recv_buf);
recv_len = 0;
}
}
}
}
/*初始化串口*/
PRIVATE void vUartInit(void)
{
vAHI_UartEnable(UART);
//复位指定UART的发送和接收FIFO,并将FIFO触发级别设置为单字节触发
vAHI_UartReset(UART,
TRUE, /* 复位收发FIFO*/
TRUE);
vAHI_UartSetBaudRate(UART, E_AHI_UART_RATE_115200); /* 设置波特率*/
/*启用接收数据可用中断,将接收FIFO触发级别设置为单字节触发。*/
vAHI_UartSetInterrupt(UART, FALSE, FALSE, FALSE, TRUE, E_AHI_UART_FIFO_LEVEL_1);
/*UART1中断回调函数*/
vAHI_Uart1RegisterCallback(vCbUart1);
}
PUBLIC void AppColdStart (void)
{
vAHI_WatchdogStop();
(void)u32AHI_Init();
recv_len = 0;
vUartInit();
vAHI_DelayXms(100);
vPutStrs((uint8*)"System Ready!\n");
while (1) {
vAHI_DelayXms(500);
vPutStrs((uint8*)"System Ready!\n");
}
}
PUBLIC void AppWarmStart (void)
{
AppColdStart();
}