📄 uart0.c
字号:
/****************************************Copyright (c)*************************
** Guangzhou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info------------------------------------------------------
** File Name: UART.c
** Last modified Date: 2004-11-29
** Last Version: 1.0
** Description: operater UART for LPC2xxx
**
**-----------------------------------------------------------------------------
** Created date: 2004-11-29
** Version: 1.0
** Description: operater UART for LPC2xxx
**
**-----------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
******************************************************************************/
#include "UART0.h"
#include <string.h>
#include "config.h"
#include "LPC23xx.h"
#include "VIC.h"
#include "Timer1.h"
// 操作UART的状态
#define UART_STATE_ERROR 0x00 // 出错
#define UART_STATE_FINISHED 0x01 // 完成
#define UART_STATE_NOFINISH 0x02 // 未完成
//
// 这些全局变量只在本文件中使用
//
static uint8 g_anRecvBuf[UART_RECV_BUF_SIZE]; // 接收缓冲区
volatile static uint32 g_nRecvCount = 0; // 接收到数据的数量
volatile static uint8 g_nRecvState = UART_STATE_NOFINISH; // 接收数据的状态
static uint32 g_nBaudRate = 19200; // 波特率
static uint32 g_nTimeout = 200; // 超时时间,单位毫秒
static uint8 g_nFIFOSize = 8;
// UART0 中断服务函数
void __irq UART0_ISR(void);
/******************************************************************************
** Function name: UART0_Init
** Descriptions: Initialize the UART, Set baudrate and other config.
(初始化串口,设置波特率和其它配置)
** Input: nBaudrate: the communicate baudrate (波特率)
** nFIFO: the trigger point of receive FIFO (接收FIFO的触发点)
** nConfig:the other config, eg parity... (其它配置,如奇偶校验等)
** Output: none (无)
** Created Date: 2004-11-29
**-----------------------------------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------------------------------
******************************************************************************/
void UART0_Init(uint32 nBaudrate, uint16 nConfig)
{
uint32 temp;
g_nBaudRate = nBaudrate;
// 初始化引脚,设置P0.2和P0.3连接到UART0
PINSEL0 = (0x01 << 4) | (0x01 << 6);
U0LCR = (uint8) (UART_RBR_EN | (nConfig & 0xFF));
temp = Fpclk / 16 / nBaudrate;
U0DLM = (uint8) ((temp >> 8) & 0xFF);
U0DLL = (uint8) (temp & 0xFF);
U0LCR &= ~UART_RBR_EN;
U0FCR = (uint8) (nConfig >> 8);
switch (nConfig & 0xF000)
{
case UART_FIFO_1:
g_nFIFOSize = 1;
break;
case UART_FIFO_4:
g_nFIFOSize = 4;
break;
case UART_FIFO_8:
g_nFIFOSize = 8;
break;
case UART_FIFO_14:
g_nFIFOSize = 14;
break;
default:
break;
}
// 清中断
temp = U0IIR;
// 安装中断
VIC_InstallIRQ(IS_UART0, UART0_ISR, 0);
// 使能RDA中断
U0IER = 0x01;
// 初始化超时定时器
Timer1_Init(Fpclk / 1000); // 每1ms为一个tick
}
/******************************************************************************
** Function name: UART0_Send
** Descriptions: Send datum with UART (从串口发送数据)
** Input: pBuf: the point of datum (指向要发送的数据的指针)
** nLen: the length of datum (要发送的数据的长度,以字节为单位)
** Output: return: the count of sended datum in fact (实际已发送数据的长度)
**-----------------------------------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------------------------------
******************************************************************************/
uint32 UART0_Send(const void *pBuf, uint32 nLen)
{
const uint8 *p = (const uint8 *) pBuf;
while (nLen-- > 0)
{
U0THR = *p++;
while ( (U0LSR & UART_LSR_THRE) == 0); // 等待发送保持器空
}
return 0;
}
/******************************************************************************
** Function name: UART0_Receive
** Descriptions: Receive datum from UART (从串口接收数据)
** Input: pBuf: the point of datum (接收数据缓冲区的指针)
** nLen: the length of datum (要接收的数据的长度,以字节为单位)
** Output: return: the count of sended datum in fact (实际已接收数据的长度)
** Created Date: 2004-11-29
**-----------------------------------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------------------------------
******************************************************************************/
uint32 UART0_Receive(void *pBuf, uint32 nLen)
{
// 启动超时定时器
Timer1_StartCount();
while (g_nRecvState == UART_STATE_NOFINISH && Timer1_GetCount() < g_nTimeout);
if (g_nRecvState == UART_STATE_FINISHED)
{
// 从驱动接收缓冲区复制数据到用户数据区
nLen = nLen < g_nRecvCount ? nLen : g_nRecvCount;
memcpy(pBuf, g_anRecvBuf, nLen);
}
else
{
nLen = 0;
}
// 复位接收状态
g_nRecvState = UART_STATE_NOFINISH;
g_nRecvCount = 0;
return nLen;
}
/******************************************************************************
** Function name: UART0_SetTimeout
** Descriptions: set the timeout of receive data (设置接收数据的超时时间)
** Input: nTimeout: the timeout value (超时时间值,如果为INFINITY_TIME,表示永远不超时)
** Output: NONE (无)
** Created Date: 2005-04-13
**-----------------------------------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------------------------------
******************************************************************************/
void UART0_SetTimeout(uint32 nTimeout)
{
g_nTimeout = nTimeout;
}
/******************************************************************************
** Function name: UART0_ISR
** Descriptions: the rount of UART0 interrupt(UART0 中断服务函数)
** Input: NONE(无)
** Output: NONE(无)
**-----------------------------------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------------------------------
******************************************************************************/
void __irq UART0_ISR(void)
{
uint8 i;
uint8 nState = U0IIR & 0x0F;
if (nState == UART_IIR_RDA || nState == UART_IIR_CTI)
{// 接收数据中断或字符超时中断。
if (g_nRecvState != UART_STATE_FINISHED)
{
if (nState == UART_IIR_RDA)
{
// 把数据存放到接收缓冲区,读取(FIFOSize-1)个数据,
// 特意留一个字节在FIFO中,让其触发字符超时中断
for (i = 0; i < (g_nFIFOSize - 1) &&g_nRecvCount < UART_RECV_BUF_SIZE; i++)
{
g_anRecvBuf[g_nRecvCount++] = U0RBR;
}
}
else
{
// 把数据存放到接收缓冲区
while (g_nRecvCount < UART_RECV_BUF_SIZE && (U0LSR & UART_LSR_RDR) != 0)
{
g_anRecvBuf[g_nRecvCount++] = U0RBR;
}
}
// 接收缓冲区已满或发生的是字符超时中断,就置接收状态为完成。
if (g_nRecvCount == UART_RECV_BUF_SIZE || nState == UART_IIR_CTI)
{
g_nRecvState = UART_STATE_FINISHED;
}
}
}
else if (nState == UART_IIR_RLS)
{// 线状态中断
g_nRecvState = UART_STATE_ERROR;
}
nState = U0LSR; // 读 U0LSR 寄存器,清除线状态中断
VICVectAddr = 0; // 通知VIC中断控制器已处理完中断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -