今天是學習lm3s811第三天。
我用的測試程式是常式中uart_echo工程。
附上代碼:
int main(void)
{
//
JtagWait();
// Set the clocking to run directly from the crystal.
//
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ);//設定頻率
// Initialize the OLED display and write status.
// Display96x16x1Init(false); /* Mask for cut down version EVK */
// Display96x16x1StringDraw("UART echo: UART0", 0, 0); /* Mask for cut down version EVK */
// Display96x16x1StringDraw("115,200, 8-N-1", 6, 1); /* Mask for cut down version EVK */
//
// Enable the peripherals used by this example.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);//外設使能[1]
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//這個不能少。具體見datasheet 中文版119頁。 [2]
//
// Enable processor interrupts.
//
IntMasterEnable();//使能處理器中斷
//
// Set GPIO A0 and A1 as UART pins.
//
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//GPIO PA0 、PA1作為UART0的2個複用引腳。
//[1]、[2]2個設定缺一不可。 否則uart0不能觸發中斷~
//
// Configure the UART for 115,200, 8-N-1 operation.
//
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
//
// Enable the UART interrupt.
//
IntEnable(INT_UART0);//uart0使能
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);//開啟接受和發送中斷
//
// Prompt for text to be entered.
//
UARTSend((unsigned char *)"Enter text: ", 12);
//
// Loop forever echoing data through the UART.
//
while(1);
}
我試著配置了uart1。
看了網上一個文章,在和上面程式配置情況的基礎上又加入了下面2行代碼
GPIOPinConfigure(GPIO_PD2_U1RX);
GPIOPinConfigure(GPIO_PD3_U1TX);
到後來我查了下datasheet,覺得上面的做法是多餘的。因為GPIO_PIN_D2和GPIO_PIN_D3的預設複用功能是uart1。
忍不住問了下老大,老大說uart1是要自己接外設的。
因為這個問題困擾了一會,但是對於uart的理解還是有積累的。
lm3s811有提供串口中斷註冊函數
void UARTIntRegister(unsigned long ulBase, void(*)(void)pfnHandler);
還有一種方法就是在啟動代碼裡面extern串口中斷ISR,
然後在中斷向量表裡面添加就可以了
DCD UARTIntHandler ; UART0 Rx and Tx
接下來我講述下FIFO的一些設定。
首先講下我遇到的一個問題。我手動禁能FIFO。程式在啟動並執行時候,發送到串口工具的字串只有En,並不是完整的Enter text:
到後來我把UARTSend改成
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
int flag = 0;
// Loop while there are more characters to send.
//
while(ulCount)
{
//
// Write the next character to the UART.
//
if((flag = UARTCharPutNonBlocking(UART0_BASE, *pucBuffer)) == 1)
{
pucBuffer++;
ulCount--;
}
}
}
發現就可以了。個人理解是我設定的傳輸速率為115200。發送一個位元組大概是80us。當串口發送FIFO卡主的時候,程式仍然進行ulCount--
一下子函數就結束了。。所以只發送了2位元組~~
還有一種解決方案就是UARTCharPutNonBlocking改成UARTCharPut。後者是有等待的~~
很高興~~ 早上又解決了一個問題。
下來來介紹下驅動庫的幾個關於UART的函數
1、IntEnable();
使能中斷,eg:IntEnable(INT_UART0);
2、void UARTEnable(unsigned long ulBase) ;
置位 UARTEN、TXE 和 RXE 位,再使能發送和接收 FIFO。 一般是先配置
UART,最後使能收發。當需要修改 UART 配置時,應當先禁止,配置完成後再使能。
3、void UARTIntEnable(unsigned long ulBase, unsigned long ulIntFlags);
參數 ulIntFlags 是下列值任何組合的邏輯或:
UART_INT_OE:過載錯誤中斷
UART_INT_BE:暫停錯誤中斷
UART_INT_PE:奇偶錯誤中斷
UART_INT_FE:幀錯誤中斷
UART_INT_RT:接收逾時中斷
UART_INT_TX:發送中斷
UART_INT_RX:接收中斷
4、void UARTFIFOLevelSet(unsigned long ulBase, unsigned
long ulTxLevel, unsigned long ulRxLevel)
參數
ulBase:UART連接埠的基址,取值UART0_BASE、UART1_BASE或 UART2_BASE
ulTxLevel:發送中斷FIFO的深度層級,取下列值之一:
UART_FIFO_TX1_8 // 在1/8深度時產生髮送中斷
UART_FIFO_TX2_8 // 在1/4深度時產生髮送中斷
UART_FIFO_TX4_8 // 在1/2深度時產生髮送中斷
UART_FIFO_TX6_8 // 在3/4深度時產生髮送中斷
UART_FIFO_TX7_8 // 在7/8深度時產生髮送中斷
註:當發送FIFO裡剩餘的資料減少到預設的深度時觸發中斷,而非填充到預設深度時觸發中斷。因此在需要發送大量資料的應用場合,為了減少中斷次數提高發送效率,發送FIFO中斷觸發深度層級設定的越淺越好,如設定為UART_FIFO_TX1_8。
ulRxLevel:接收中斷FIFO的深度層級,取下列值之一:
UART_FIFO_RX1_8 // 在1/8深度時產生接收中斷
UART_FIFO_RX2_8 // 在1/4深度時產生接收中斷
UART_FIFO_RX4_8 // 在1/2深度時產生接收中斷
UART_FIFO_RX6_8 // 在3/4深度時產生接收中斷
UART_FIFO_RX7_8 // 在7/8深度時產生接收中斷
註:當接收FIFO裡已有的資料累積到預設的深度時觸發中斷,因此在需要接收大量資料的應
用場合,為了減少中斷次數提高接收效率,接收FIFO中斷觸發深度層級設定的越深越好,如設定
為UART_FIFO_RX7_8。
有一個uart介紹很詳細的連結:http://bbs.eeworld.com.cn/thread-214040-1-3.html