您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
新唐的M0/M4 UART都有16級(jí)或者64級(jí)FIFO,用來緩存UART數(shù)據(jù)的收/發(fā)。例如:如果RX FIFO中斷觸發(fā)級(jí)別設(shè)為14,UART接收14個(gè)字節(jié)才會(huì)發(fā)生RDA(接收數(shù)據(jù)可得)中斷。這樣可以降低CPU的loading。上面的情況,如果RX只接收到10個(gè)字節(jié)怎么辦呢?這時(shí)候就要用到接收超時(shí)中斷。當(dāng)RX FIFO中收到1個(gè)字節(jié)以后,定時(shí)器就開始計(jì)數(shù),如果定時(shí)器超時(shí)都沒有再收到下一個(gè)字節(jié)就會(huì)發(fā)生接收超時(shí)中斷(RTO)。
每個(gè)IP的初始化都需要先初始化時(shí)鐘,然后才是IP功能初始化。初始化UART之前需要使能要用的晶振,然后選擇時(shí)鐘源并使能時(shí)鐘。最后將UART用到的引腳切換為UART功能。
void UART0_Init() { /* UART選擇HIRC做時(shí)鐘源 */ CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_UART_S_Msk) | CLK_CLKSEL1_UART_S_HIRC; /* 使能UART0 IP的時(shí)鐘 */ CLK->APBCLK |= CLK_APBCLK_UART0_EN; /* PB13用作UART0 接收,PB14用作UART0發(fā)送 */ SYS->PB_H_MFP &= ~(SYS_PB_H_MFP_PB13_MFP_Msk | SYS_PB_H_MFP_PB14_MFP_Msk); SYS->PB_H_MFP |= (SYS_PB_H_MFP_PB13_MFP_UART0_RX | SYS_PB_H_MFP_PB14_MFP_UART0_TX); /* Init UART0 */ UART_Open(UART0, 115200); /*默認(rèn)數(shù)據(jù)長度為8bit,沒有奇偶校驗(yàn),1個(gè)停止位*/ /*初始化UART1,波特率9600,數(shù)據(jù)長度8bit,1個(gè)停止位,偶校驗(yàn)*/ UART_SetLine_Config(UART1, 9600, UART_WORD_LEN_8, UART_PARITY_EVEN, UART_STOP_BIT_1); } UART_Open會(huì)根據(jù)UART選擇的時(shí)鐘源計(jì)算波特率。 上面的代碼執(zhí)行之后,UART_WRITE(UART0, 0x31)就會(huì)從UART TX引腳發(fā)送0x31了。如果要使用printf打印信息,keil project中加入retarget.c就可以,然后由宏定義#define DEBUG_PORT UART0決定printf從哪個(gè)UART口打印。 如果想使用中斷接收數(shù)據(jù),代碼如下: void UART0_Init() { /* 選擇UART時(shí)鐘源 */ CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_UART_S_Msk) | CLK_CLKSEL1_UART_S_HIRC; /* 使能UART0 IP的時(shí)鐘 */ CLK->APBCLK |= CLK_APBCLK_UART0_EN; /* PB13用作UART0 接收,PB14用作UART0發(fā)送 */ SYS->PB_H_MFP &= ~(SYS_PB_H_MFP_PB13_MFP_Msk | SYS_PB_H_MFP_PB14_MFP_Msk); SYS->PB_H_MFP |= (SYS_PB_H_MFP_PB13_MFP_UART0_RX | SYS_PB_H_MFP_PB14_MFP_UART0_TX); /* Init UART0 */ UART_Open(UART0, 115200); /*默認(rèn)數(shù)據(jù)長度為8bit,沒有奇偶校驗(yàn),1個(gè)停止位*/ /*初始化UART1,波特率9600,數(shù)據(jù)長度8bit,1個(gè)停止位,偶校驗(yàn)*/ UART_SetLine_Config(UART1, 9600, UART_WORD_LEN_8, UART_PARITY_EVEN, UART_STOP_BIT_1); /*設(shè)置接收超時(shí)時(shí)間為40,單位波特率*/ UART_SetTimeoutCnt(UART0, 40); /*設(shè)置接收FIFO觸發(fā)級(jí)別為14B*/ UART_SET_RX_FIFO_INTTRGLV(UART0, UART_TLCTL_RFITL_14BYTES); /*使能接收FIFO 閥值中斷,和接收超時(shí)中斷*/ UART_ENABLE_INT(UART0, (UART_IER_RDA_IE_Msk | UART_IER_RTO_IE_Msk)); NVIC_EnableIRQ(UART0_IRQn); } /*UART0中斷處理函數(shù)*/ void UART0_IRQHandler(void) { uint8_t u8InChar=0xFF; uint32_t u32IntSts= UART0->ISR; /*發(fā)生接收閥值中斷或者接收超時(shí)中斷*/ if(u32IntSts & (UART_ISR_RDA_IS_Msk| UART_ISR_RTO_IS_Msk)) { /* 讀走接收FIFO中所有的數(shù)據(jù),直到接收FIFO為空 */ while(UART_GET_RX_EMPTY(UART0)==0) { /* 從接收FIFO中讀一個(gè)數(shù)據(jù) */ u8InChar = UART_READ(UART0); } } }
UART IP有個(gè)復(fù)位函數(shù):SYS_ResetModule(UART0_RST); 其實(shí)新唐的芯片每個(gè)IP都有單獨(dú)的復(fù)位控制。什么時(shí)候需要復(fù)位UART0呢?如果該代碼是通過CPU reset執(zhí)行到的,那原本UART可能在工作,RX FIFO中可能有數(shù)據(jù),可能會(huì)發(fā)生中斷等等一些無法預(yù)估的事情,這時(shí)候最好復(fù)位一下UART IP的邏輯。
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08