LPC2138微控制器之UART

第七章 UART

特性介绍

LPC2138微控制器具有两个UART控制器,每个UART控制器拥有Rx & Tx FIFO(各16字节),Rx FIFO可以设置当接收到1/4/8/14个字节时触发中断。

UART控制器的参考时钟是PCLK。

UART控制器原理

从UART控制器内部原理图上可以看出,UART控制器主要由配置中断部分(U0IER & U0IIR)、帧控制(U0LCR)、波特率配置(U0FDR & U0DLL & U0DLM)、FIFO配置(U0FCR)、发送和接收(U0THR & U0RBR)几部分组成。

它们各司其职,UART初始化时,首先通过PCLK频率和波特率计算U0FDR、U0DLL、U0DLM的值,然后通过U0LCR配置数据帧格式(如8位数据位、一位停止位、无奇偶校验位),接下来通过U0FCR配置FIFO工作模式(包括接收到多少个字节触发中断),最后使能中断。此外就是读写函数和中断服务函数的实现。

波特率计算公式如下:

UART协议

UART协议请参考我之前写的一篇博文

UART调试串口实例

调试UART程序的过程中,发现读写均无效,最后发现是因为U1IIR中断状态寄存器是读清的,在中断服务函数中必须进行读操作,否则程序会一直驻留在中断服务函数中。

#include <lpc213x.h>
#include "serial.h"

#define CR 0x0D

void serial1_isr(void) __irq
{
    /*  The U1IIR must be read in order to
    **  clear the interrupt prior to exiting the
    **  Interrupt Service Routine.
    */
    if ((U1IIR & 0x0E) == 0x04)
    {
        /* Receive Interrupt */
        sendchar(U1RBR);
    }

    if (U1LSR & 0x20)
    {
        /* Transmit Interrupt */
    }
}

void serial_init(void)
{
    /* configure P0.8~9 as TXD1 & RXD1 */
    PINSEL0 &= 0xFFF0FFFF;
    PINSEL0 |= 0x00050000;

    /* 8bits, no Parity, 1 Stop bit */
    U1LCR = 0x83;

    /* 9600 bauds while PCLK is 30MHz */
    U1DLL = 0xC3;
    U1DLM = 0x00;
    U1FDR = 0x10;

    /* DLAB = 0 */
    U1LCR = 0x03;

    /* Reset & Enable FIFO, configure Rx FIFO trigger level 0 (1 character) */
    U1FCR = 0x07;

    /* Enable RDA & THRE Interrupts */
    U1IER = 0x03;

    /* UART1 ISR */
    VICVectCntl1 = 0x20 | 7;
    VICVectAddr1 = (unsigned int)serial1_isr;
    VICIntEnable = 0x80;

}

int sendchar(char ch)
{
    if ('\n' == ch)
    {
        while (!(U1LSR & 0x20));
        U1THR = CR;
    }

    while (!(U1LSR & 0x20));
    return (U1THR = ch);
}

void sendhex(char hex)
{
    int i = 0;
    char half[2] = {0};

    half[0] = hex >> 4;
    half[1] = hex & 0x0F;

    sendstr("0x");

    for (i = 0; i < 2; i++)
    {
        if (half[i] > 9)
            sendchar('A' + (half[i] - 10));
        else
            sendchar('0' + half[i]);
    }

}

void sendstr(char *p)
{
    while (*p)
        sendchar(*p++);
}

posted on 2020-02-21 11:30  者旨於陽  阅读(848)  评论(0编辑  收藏  举报

导航