TA的每日心情 | 开心 2017-6-8 21:55 |
---|
签到天数: 5 天 连续签到: 1 天 [LV.2]偶尔看看I
|
LPC824具有三个串口,相比较于别的单片机来说,串口资源优势相当明显,对于设计产品来说特别好,可以减少软件模拟串口的开销,稳定而且方便大家开发。串口作为MCU的重要组成,基本上设计的电路中必不可少。我们要好好掌握。下面介绍LPC824的串口。
1、LPC824liteUSART的基本特性:
(1)数据格式:7、8、9个数据位、1、2个停止位
(2)RS-485通信模式
(3)数据校验:奇数、偶数或无校验位。
(4)一个发送和一个接收数据缓冲区。
(5)DMA收发:USART发送和接收功可以使用DMA
(6)异步下最高速率可达1.875Mbits/s
(7)同步下最高速率可达10Mbits/s
(8)内置波特率发生器,具有自动检测波特率功能。
(9)所有USART之间共享一个分数速率分频器。(10)用于测试数据和流量控制的环回模式。
2、具有主从操作的同步通信模式,可以选择数据相位和连续时钟输出
(1)在异步模式下,软件可以从5到16个时钟进行过采样。
(2) 使用RTS和CTS信号支持硬件流控
(3)可以产生与识别break信号
(4) 多机通信(9个位)模式,软件匹配地址
(5) 异步通信模式下只能从睡眠模式下唤醒
(6)同步通信模式下可以从全部低功耗模式下唤醒
3、USART的时钟如下图所示:
4、USART功能框图如下图所示:
5、使用USART模块的主要的步骤:
(1)通过SYSCON模块(SYSAHBCLKCTRL:bit14/15/16)开启USART0/1/2模块的时钟,解除复位PININT模块;配置全部USART的主分频和分数分频数
(2)SWM分配引脚,通过IOCON寄存器正确配置引脚属性
(3)通过NVIC配置打开对应的USART中断源,按需配置优先级,USART支持DMA
(4)配置USART模块
6、配置USART模块:
(1)基本配置:配置USART的CFG寄存器,使能USART;数据位为8位;无校验位,1位停止位;无流控
(2)配置波特率:配置整数分频器和分数分频器
(3)其他配置:配置USART的CTL寄存器使能发送器
(4)中断配置:配置INTENSET和INTTENCLR寄存器使能中断
(5)USART的发送数据和接收数据:配置STAT寄存器决定USART是发送还是接收数据
7、DMA数据的收发:
(1)每个USART的每个方向(接收/发送)各对应一个DMA通道
(2)USART对DMA的请求是自动完成的,无需配置
(3)初始化DMA控制器:
a、填写对应通道的地址
b、配置对应的DMA通道的CFG寄存器
c、开启传输完成中断
d、使能外设请求
8、睡眠模式下,触发USART中断的信号可以唤醒芯片,相关配置如下:
(1)配置USART为异步模式或同步模式
(2)使能NVIC寄存器中的USART中断
(3)使能USART中断使能寄存器INTENSET中的中断
9、深度睡眠/掉电模式下,只能支持USART同步从机模式的唤醒,相关配置如下:
(1)配置USART为同步从机模式
(2)使能STARTERP1寄存器中的USART唤醒中断
(3)使能NVIC寄存器中的USART中断
(4)在PDAWAKE寄存器中,配置所有唤醒后需要正常工作的外设模块
(5)使能USART中断使能寄存器INTENSET中的中断作为唤醒事件
一般情况下,USART都是结合DMA一起使用,实现高速数据通信的,下面我们来介绍一下DMA吧
1、DMA 的功能描述:
(1)支持18个通道,每个通道都支持USART,SPI和I2C外设
(2)每个通道都可以选择9个中断源中一种
(3)每个通道都可以选择优先级
(4)单次传输最多支持1,024个字/
2、DMA的结构框图如下图所示:
3、DMA寄存器描述:
DMA的全局控制和状态寄存器:
CTRL:控制DMA的使能
INTSTATMA的中断状态
SRAMBASE:设置DMA描述符表的地址
DMA通道的共享寄存器:
设置DMA通道的使能/禁能,通道忙、错误、触发、中断等
DMA的通道寄存器:
CFG0-CFG17:配置通大道的触发方式、传输字节等
CTLSTAT0-CTLSTAT17:通道的控制和状态
XFERCFG0-XFERCFG17:通道传输相关的配置
4、DMA控制器有三种触发方式:DMA triggers、DMA request、软件触发,这三种方式都可以触发DMA工作
5、DMA的传输模式:single buffer、ping-pong和Linked transfers
6、DMA基本配置:
(1)使能DMA外设时钟 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_DMA);
(2)使能DMA中断NVIC_EnableIRQ(DMA_IRQn);
(3)选择DMA的输入触发源 Chip_DMATRIGMUX_SetInputTrig() ;
(4)设置DMA的输出作为DMA的输入触发 Chip_INMUX_SetDMAOTrig
int main(void)
{
int bytes, idx;
uint8_t buff[UARTRXBUFFSIZE];
SystemCoreClockUpdate();
Board_Init();
Init_UART_PinMux();
DEBUGSTR("EEPROM demo\r\n");
DEBUGOUT("DMA-UART Clock: %uMHz\r\n", SystemCoreClock / 1000000);
DEBUGOUT("Device ID: 0x%x\r\n", Chip_SYSCTL_GetDeviceID());
Board_LED_Set(0, false);
Chip_UART_Init(LPC_USART0);
Chip_UART_ConfigData(LPC_USART0, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1);
Chip_Clock_SetUSARTNBaseClockRate((115200 * 16), true);
Chip_UART_SetBaud(LPC_USART0, 115200);
Chip_UART_Enable(LPC_USART0);
Chip_UART_TXEnable(LPC_USART0);
/* DMA initialization - enable DMA clocking and reset DMA if needed */
Chip_DMA_Init(LPC_DMA);
/* Enable DMA controller and use driver provided DMA table for current descriptors */
Chip_DMA_Enable(LPC_DMA);
Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
/* Setup UART 0 TX DMA support */
dmaTXSetup();
/* Setup UART 0 RX DMA support */
dmaRXSetup();
/* Enable the DMA IRQ */
NVIC_EnableIRQ(DMA_IRQn);
/* Enqueue a bunch of strings in DMA transmit descriptors and start
transmit. In this use of DMA, the descriptors aren't chained, so
the DMA restarts the next queued descriptor in the DMA interrupt
handler. */
for (idx = 0; idx < DMASENDSTRCNT; idx++) {
sprintf(dmaSendStr[idx], "DMA send string (unlinked) #%d\r\n", idx);
dmaTXSend((uint8_t *) dmaSendStr[idx], strlen(dmaSendStr[idx]));
}
/* Wait for UART TX DMA channel to go inactive */
while (1) {
__WFI();
if (Chip_DMA_GetActiveChannels(LPC_DMA) & (1 << DMAREQ_USART0_TX)) {
break;
}
}
/* Receive buffers are queued. The DMA interrupt will only trigger on a
full DMA buffer receive, so if the UART is idle, but the DMA is only
partially complete, the DMA interrupt won't fire. For UART data
receive where data is not continuous, a timeout method will be
required to flush the DMA when the DMA has pending data and no
data has been received on the UART in a specified timeout */
dmaRXQueue();
/* Get RX data via DMA and send it out on TX via DMA */
while (1) {
/* Sleep until something happens */
__WFI();
/* Did any data come in? */
bytes = checkRxData(buff);
if (bytes > 0) {
/* RX data received, send it via TX DMA */
dmaTXSend(buff, bytes);
}
}
} |
|