现在的位置: 首页 > 综合 > 正文

LPC1114_基本串口1_中断_软件BUF

2013年12月03日 ⁄ 综合 ⁄ 共 6202字 ⁄ 字号 评论关闭

/***************************************************************************************************
                                    基本串口使用
LPC1114 硬件:
        P1.6-RXD
        P1.7-TXD
        GND -GND
        VCC -3.3
配置 8bit数据 1stop 无校验

实现方法:
    1 使用1字节硬件FIFO。(相当于没用),每1字节中断一次,时间隔86uS
    2 使用软件BUFF,长度可配置
    3 收发函数可立即返回
编    者 张永辉 2012年11月29日
***************************************************************************************************/
#ifndef __UART0_H
#define __UART0_H

/*******************************配置***************************************************************/
#define UART0_BUF_TYPE  unsigned char       //接收的数据类型。都是8位就按此类型了
#define UART0_DATA_CNT  unsigned char       //若设置buf长度超过255,则需要改变此类型。

#define UART0_SENDBUF_LEN  32               //发送数据BUF长度
#define UART0_RECVBUF_LEN  32               //接收数据BUF长度

/*******************************函数声明***********************************************************/
UART0_DATA_CNT Uart0Recv(UART0_BUF_TYPE * buff,UART0_DATA_CNT len);
UART0_DATA_CNT Uart0Send(UART0_BUF_TYPE * buff,UART0_DATA_CNT len);
void           UartTest(void);
void           UartInit(void);
void           UART_IRQHandler(void);

/**************************************************************************************************/
#endif

 

/***************************************************************************************************
本文件功能:                        串口
***************************************************************************************************/
#define __UART0_C
#include "LPC11xx.h"
#include "systick.h"
#include "uart.h"
/*******************************声明***************************************************************/
UART0_BUF_TYPE Uart0SendBuf[UART0_SENDBUF_LEN];
UART0_DATA_CNT Uart0SendIn  = 0;
UART0_DATA_CNT Uart0SendOut = 0;

UART0_BUF_TYPE Uart0RecvBuf[UART0_RECVBUF_LEN];
UART0_DATA_CNT Uart0RecvIn = 0;
UART0_DATA_CNT Uart0RecvOut = 0;

void Uart0SendByte_server(void);
void Uart0RecvByte_server(void);
/***************************************************************************************************
函数功能:UART测试
***************************************************************************************************/
void UartTest(void)
{
    unsigned char a[5]="12345";
    UartInit();
    while(1)
    {
        Uart0Send(a,5);
        SYSTICKDelay10ms(10);

        a[0] = Uart0Recv(a,5);
        a[0] += 0x30;
    }
}

/***************************************************************************************************
函数功能:UART初始化
参    数:固定波特率 115200
***************************************************************************************************/
void UartInit(void)
{
    NVIC_DisableIRQ(UART_IRQn);             //先禁止UART中断

    //引脚配置,仅使用RXD TXD引脚
    LPC_IOCON->PIO1_6 &= ~0x07;             //配置引脚为UART模式
    LPC_IOCON->PIO1_6 |= 0x01;              //UART RXD

    LPC_IOCON->PIO1_7 &= ~0x07;
    LPC_IOCON->PIO1_7 |= 0x01;              //UART TXD

    //AHBCLKCTRL 对UART开关
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);   //即开启UART. 关闭此位可以降低功耗
    LPC_SYSCON->UARTCLKDIV = 0x1;           //USART时钟使能,=0除能

    //波特率由UARTCLKDIV控制
    //波特率使用115200,如下配置实际为115384,误差0.16%
    LPC_UART->LCR |=  (0X80);               //DLAB=1 允许对除数锁存器的访问
    LPC_UART->FDR = 0x85;                   //需要DLAB=1
    LPC_UART->DLM = 0;                      //需要DLAB=1
    LPC_UART->DLL = 16;
    LPC_UART->LCR &= ~(0X80);               //DLAB=0 禁止对除数锁存器的访问
    LPC_UART->LCR |=  (0X03);               //8bits,1个停止位,无校验,禁止间隔发送

    //中断控制
    //LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;
    LPC_UART->IER = 0x03;                   //允许RBR THRE中断
    LPC_UART->FCR = 0x01;                   //使能FIFO 收满1字节触发中断.U0FCR对FIFO无影响

    //发送使能位
    LPC_UART->TER &= ~(0X80);               //除能发送

    NVIC_EnableIRQ(UART_IRQn);              //使能UART中断
}

/***************************************************************************************************
函数功能:接收数据函数
    参数:buff  接收数据指针
          len   最大数据长度
    返回:接收到的个数
***************************************************************************************************/
UART0_DATA_CNT Uart0Recv(UART0_BUF_TYPE * buff,UART0_DATA_CNT len)
{
    //能够接收多少个数据
    len = (len < Uart0RecvIn) ? len : Uart0RecvIn;

    Uart0RecvOut = 0;

    //接收数据
    while(len--)
    {
        *buff++ = Uart0RecvBuf[Uart0RecvOut++];
    }

    //清空Buf   bug:若len < Uart0RecvBuf 则丢失接收到的数据了
    Uart0RecvIn = 0;
    return Uart0RecvOut;
}

/***************************************************************************************************
函数功能:发送数据
    参数:buff  发送数据指针
          len   最大数据长度
    返回:发送的个数
***************************************************************************************************/
UART0_DATA_CNT Uart0Send(UART0_BUF_TYPE * buff,UART0_DATA_CNT len)
{
    //不能 发送0个数据 或者有数据正在发送
    if(0==len || Uart0SendOut != 0)
    {
        return 0;
    }

    //应该最大发送长度
    len =   (len < UART0_SENDBUF_LEN) ? len : UART0_SENDBUF_LEN;

    //数据复制
    while(len--)
    {
        Uart0SendBuf[Uart0SendOut++] = *buff++;
    }

    //装载第一个数据
    LPC_UART->THR = Uart0SendBuf[0];
    Uart0SendIn++;

    //发送使能,会中断一次,立即发送数据。
    LPC_UART->TER = (0X80);

    //返回发送的数据个数
    return (Uart0SendOut);
}

/***************************************************************************************************
函数功能:中断处理函数

***************************************************************************************************/
void UART_IRQHandler(void)
{
    uint8_t IIRValue;
    uint8_t LSRValue;

    //只读 中断标志寄存器
    IIRValue = LPC_UART->IIR;   //==0x02 THER  ==0X40接收数据可用
                                //IIR           == 0x03 接收线状态
                                //                  02  接收数据可用
                                //                  06  字符超时指示器
                                //                  01  THRE 中断
                                //                  00  modle
    IIRValue = IIRValue;

    //线状态寄存器
    LSRValue = LPC_UART->LSR;
                                //byte0 = 1 U0RBR有数据
                                //byte5 = 1 U0THR为空

    //发生数据空  也可以判断IIRValue
    if(LSRValue & (1<<5))
    {
        Uart0SendByte_server();
    }

    if(LSRValue & 0x01)
    {   //读数据会清空中断标志
        Uart0RecvByte_server();
    }
}

void Uart0SendByte_server(void)
{
    //一次数据发送完成
    if(Uart0SendIn >= Uart0SendOut)
    {
        Uart0SendIn = 0;
        Uart0SendOut = 0;
        LPC_UART->TER &= ~(0X80);           //除能发送,否则会继续中断
        return;
    }

    //装载数据
    LPC_UART->THR = Uart0SendBuf[Uart0SendIn++];
}

void Uart0RecvByte_server(void)
{
    UART0_BUF_TYPE rev;
    rev = LPC_UART->RBR;                    //读数据会清空中断标志

    //接收满了直接返回
    if(Uart0RecvIn >= UART0_RECVBUF_LEN)
    {
        return;
    }

    //接收数据
    Uart0RecvBuf[Uart0RecvIn++] = rev;
}

 

抱歉!评论已关闭.