今天是学习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