NXP JN5169使用UART發送資料
- 一、UART介紹
- 1、UART介紹
- 2、UART系統圖
- 3、UART引腳
- 4、UART操作
- 5、2線模式
- 6、4線模式(帶流控制)(僅適用UART0)
- 7、1線模式(僅適用UART1)
- 二、UART集成外設API函式介紹
- 三、實作代碼
- 1、UART0 2線模式發送資料
- 2、UART0 2線模式發送/接收資料
- 3、UART1 1線模式發送資料
- 4、UART1 2線模式發送/接收資料
一、UART介紹
1、UART介紹
JN5169具有兩個通用異步接收器/發送器(UART)串行通信介面, 它們提供與以FIFO模式運行的行業標準16550A器件相似的操作功能,這些介面對傳入的串行資料執行串行到并行轉換,并對從CPU到外部設備的傳出資料執行并行到串行轉換, 在兩個方向上,可配置的FIFO緩沖區(默認深度為16位元組)使CPU可以在每個事務中讀寫多個字符, 這意味著,CPU不再需要逐個字符地處理資料,并且會增加相關的處理器開銷, UART具有以下功能:
- 遵守行業標準NS16450和NS16550A,
- 可配置的發送和接收FIFO緩沖區(每個緩沖區的默認深度為16位元組),可直接訪問每個緩沖區的填充級別,向/從串行資料中添加/洗掉標準的開始,停止和奇偶校驗位,
- 獨立控制的發送,接收,狀態和資料發送中斷,
- UART0上的可選調制解調器流控制信號CTS和RTS,
- 完全可編程的資料格式:波特率,開始,停止和奇偶校驗設定,
- 錯誤的起始位檢測,奇偶校驗,成幀和FIFO超限錯誤檢測和中斷指示,
- 內部診斷功能:用于通信鏈路故障隔離的環回控制,
- 通過軟體或通過硬體自動控制流量,
注:這里描述的 UART 操作假設外設時鐘運行在 16MHz,時鐘來自一個外部晶體振蕩器,不建議用戶在任何其他時鐘下運行 UART,
2、UART系統圖

3、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 使用以下信號與一個外部設備相連:
- 發送資料(TxD)輸出 —— 連接到外部設備的 RxD
- 接收資料(RxD)輸入 —— 連接到外部設備的 TxD
- 請求發送(RTS)輸出 —— 連接到外部設備的 CTS
- 清除發送(CTS)輸入 —— 連接到外部設備的 RTS
如果 UART 只使用信號 RxD 和 TxD,就表明 UART 作業在 2 線模式,如果 UART 使用上面全部 4 個信號,就表明 UART 作業在 4 線模式并執行流控制, 在 JN5169 器件上:
- UART0 可以作業在 4 線模式(默認情況)或 2 線模式;
- UART1 可以作業在 2 線模式(默認情況)或 1 線(僅發送)模式;
4、UART操作
UART 的發送和接收通路每個都有一個 FIFO 緩沖區,它允許和外部設備執行多位元組的串行傳輸:
- TxD 引腳連接到發送 FIFO;
- RxD 引腳連接到接收 FIFO;
FIFO 包含在 RAM 中,由應用來定義,每個 FIFO 的大小可以從 16 個位元組直至 2047 個位元組,
在本地設備上,CPU 可以一次性向 FIFO 寫入/讀出一個位元組和一個資料塊,讀/寫通路互相獨立,因此發送和接收單獨出現,由一個 DMA(直接存盤器存取)引擎來處理 FIFO 和 TxD/RxD之間的資料移動,不需要 CPU 的參與,

5、2線模式
在 2 線模式下,UART 只使用信號線 TxD 和 RxD,只要發送設備方便(例如,當發送 FIFO包含一些資料時),可以不做任何通知就發送資料,資料還也可以根據發送設備的方便不做任何通知就接收,這可能會產生問題和導致資料丟失,例如,接收設備可能在接收 FIFO 中沒有足夠的空間來接收發送過來的資料,
6、4線模式(帶流控制)(僅適用UART0)
在 4 線模式下,UART0 使用信號線 TxD、RxD、RTS 和 CTS,允許執行流控制,保證發送的資料總是能接收到,流控制的一般原理在下面描述,
RTS 和 CTS 線是標志,用來指示資料在設備之間安全傳輸,一個設備上的 RTS 線連接到另一個設備的 CTS 線,
目標設備命令源設備應該何時給它發送資料,如下所述:
- 當目標設備準備好接收資料時,它激活 RTS 線來請求源設備發送資料,這種情況可能是目標設備的接收 FIFO填充水平(fill-level)降至低于一個預定義好的水平,并且 FIFO能夠接收更多的資料;
- 源設備將目標設備 RTS 線的激活看成是自己 CTS 線的激活,然后將資料從發送 FIFO中發送出去,
流控制操作如下面所示,

7、1線模式(僅適用UART1)
在 1 線模式下,UART1 根據發送設備方便,在不通知的情況下使用 TxD 線發送資料,該模式下不接收資料,也不使用 RxD 線(因此,相關的 DIO 引腳可以用作其他用途)
二、UART集成外設API函式介紹
NXP JN5169 UART集成外設API函式
三、實作代碼
1、UART0 2線模式發送資料
#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();
}
2、UART0 2線模式發送/接收資料
#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();
}
3、UART1 1線模式發送資料
#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();
}
4、UART1 2線模式發送/接收資料
#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();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/201522.html
標籤:其他
