📄 uart.c
字号:
/******************************************************************************************
** 文件名称:UART.c
** 文件描述:LPC2103 UART操作软件包。
** 文件说明:软件包中缺少Modem的操作部分。
******************************************************************************************/
#include "config.h"
#define TXD0 1 //TXD0是引脚P0.0的第2功能
#define RXD0 (1<<2) //RXD0是引脚P0.1的第2功能
#define TXD1 (1<<16) //TXD1是引脚P0.8的第2功能
#define RXD1 (1<<18) //RXD1是引脚P0.9的第2功能
/******************************************************************************************
** 函数名称:uint8 UARTn_Init( uint8 n,uint32 baud,uint8 datab,
** uint8 stopb,uint8 parity,uint8 INT_En)
** 功能描述:对UARTn进行初始化。
** 输 入: n 0-UART0 1-UART1
** baud 串口通信波特率
** datab 数据位个数,有效值为:5,6,7,8
** stopb 停止位个数,有效值为:1,2
** parity 奇偶校验位
** 0--无校验
** 1--奇校验
** 2--偶校验
** 3--强制为1
** 4--强制为0
** INT_En 中断控制字节,按位操作
** bit0 1--RBR中断使能,0--RBR中断禁止
** bit1 1--THRE中断使能,0--THRE中断禁止
** bit3 1--RX线状态中断使能,0--RX线状态中断禁止
** 输 出: 0 初始化失败
** 1 初始化成功
** 说明:LPC2103中波特率的设置忽略了小数分频寄存器和FIFO。
******************************************************************************************/
uint8 UARTn_Init(uint8 n,uint32 baud,uint8 datab,uint8 stopb,uint8 parity,uint8 INT_En)
{
uint32 bak;
/*检查参数的合理性*/
if((baud==0)||(baud>115200)) return(0); //波特率:1~115200,否则出错
if((datab<5)||(datab>8)) return(0); //数据位数:1~8,否则出错
if((stopb==0)||(stopb>2)) return(0); //停止位:1、2,否则出错
if(parity>4) return(0); //奇偶校验位有错
/*设置串口模式*/
bak = datab - 5; //设置字长
if(stopb==2)
bak |= 0x04; //判断是否为2位停止位
if(parity != 0)
{
parity -= 1;
bak |= 0x08;
}
bak |= parity<<4; //设置奇偶校验位
switch(n)
{
case 0: //UART0
//设置UART0引脚,且不影响其它引脚
PINSEL0 = (PINSEL0 & (~0x0f)) | TXD0 | RXD0;
/*设置串口波特率*/
U0LCR = 0x80; //DLAB=1
U0DLM = ((Fpclk/16)/baud)/256;
U0DLL = ((Fpclk/16)/baud)%256;
/*设置串口模式*/
U0LCR = bak;
U0IER = INT_En & 0x07; //设置中断使能寄存器
return(1);
case 1: //UART1
//设置UART1引脚,且不影响其它引脚
PINSEL0 = (PINSEL0 & (~(0x0f<<16))) | TXD1 | RXD1;
/*设置串口波特率*/
U1LCR = 0x80; //DLAB=1
U1DLM = ((Fpclk/16)/baud)/256;
U1DLL = ((Fpclk/16)/baud)%256;
/*设置串口模式*/
U1LCR = bak;
U1IER = INT_En & 0x07; //设置中断使能寄存器
return(1);
default: //只有两个串口
return(0);
}
}
/*********************************************************************************************************
** 函数名称:uint8 UARTn_AutoInit(uint8 n,uint8 datab,uint8 stopb,uint8 parity,uint32 INT_En,uint8 Mode)
** 功能描述:对UARTn首先进行自动波特率测试,然后再进行其它方面的初始化
** 输 入: n 0-UART0 1-UART1
** datab 数据位个数,有效值为:5,6,7,8
** stopb 停止位个数,有效值为:1,2
** parity 奇偶校验位,0-无校验,1-奇校验,2-偶校验,3-强制为1,4-强制为0
** INT_En 中断控制字节,按位操作
** bit0 1--RBR中断使能,0--RBR中断禁止
** bit1 1--THRE中断使能,0--THRE中断禁止
** bit3 1--RX线状态中断使能,0--RX线状态中断禁止
** bit8 1--自动波特率超时中断使能,0--自动波特率超时中断禁止
** bit9 1--自动波特率完成中断使能,0--自动波特率完成中断禁止
** Mode 自动波特率模式位
** 0 模式0
** 1 模式1
** 输 出: 0 :初始化失败
** 1 :初始化成功
********************************************************************************************************/
uint8 UARTn_AutoInit(uint8 n,uint8 datab,uint8 stopb,uint8 parity,uint32 INT_En,uint8 Mode)
{
uint32 bak;
/*检查参数的合理性*/
if((datab<5)||(datab>8)) return(0); //数据位数:1~8,否则出错
if((stopb==0)||(stopb>2)) return(0); //停止位:1、2,否则出错
if(parity>4) return(0); //奇偶校验位有错
/*设置串口模式*/
bak = datab - 5; //设置字长
if(stopb==2)
bak |= 0x04; //判断是否为2位停止位
if(parity != 0)
{
parity -= 1;
bak |= 0x08;
}
bak |= parity<<4; //设置奇偶校验位
switch(n)
{
case 0: //UART0
//设置UART0引脚,且不影响其它引脚
PINSEL0 = (PINSEL0 & (~0x0f)) | TXD0 | RXD0;
//测量波特率
U0ACR = 0x005|(Mode<<1); //超时则自动重新启动
/*设置串口模式*/
U0LCR = bak;
U0IER = (INT_En & (0x307)); //设置中断使能寄存器
return(1);
case 1: //UART1
//设置UART1引脚,且不影响其它引脚
PINSEL0 = (PINSEL0 & (~(0x0f<<16))) | TXD1 | RXD1;
//测量波特率
U1ACR = 0x005|(Mode<<1); //超时则自动重新启动
/*设置串口模式*/
U1LCR = bak;
U1IER = (INT_En & (0x307)); //设置中断使能寄存器
return(1);
default: //只有两个串口
return(0);
}
}
/*********************************************************************************************************
** 函数名称: void Set_FIFO(uint8 n,uint8 data)
** 功能描述: 设置FIFO
** 输 入: n :0-UART0 1-UART1
** data:FIFO缓冲区的大小,只能为1,2,8、14个字节
** 输 出: 0 :初始化失败
** 1 :初始化成功
********************************************************************************************************/
uint8 Set_FIFO(uint8 n,uint8 data)
{
if(n == 0) //UART0
{
switch(data)
{
case 1:
U0FCR = 0x01; //缓冲区为1个字节
return(1);
case 4:
U0FCR = 0x41; //缓冲区为4个字节
return(1);
case 8:
U0FCR = 0x81; //缓冲区为8个字节
return(1);
case 14:
U0FCR = 0xc1; //缓冲区为14个字节
return(1);
default:
return(0);
}
}
if(n == 1) //UART1
{
switch(data)
{
case 1:
U1FCR = 0x01; //缓冲区为1个字节
return(1);
case 4:
U1FCR = 0x41; //缓冲区为4个字节
return(1);
case 8:
U1FCR = 0x81; //缓冲区为8个字节
return(1);
case 14:
U1FCR = 0xc1; //缓冲区为14个字节
return(1);
default:
return(0);
}
}
return(0);
}
/*********************************************************************************************************
** 函数名称: void UARTn_SendByte(uint8 n,uint8 data)
** 功能描述: 从UART发送一字节数据
** 输 入: n :0-UART0 1-UART1
** data:发送的数据
** 输 出: 无
** 全局变量:
** 调用模块: 程序采用查询方式,并且没有使用FIFO
********************************************************************************************************/
void UARTn_SendByte(uint8 n,uint8 data)
{
if(n == 0)
{
U0THR = data; //发送数据
while((U0LSR & 0x20)==0); //等待数据发送完毕
}
if(n == 1)
{
U1THR = data; //发送数据
while((U1LSR & 0x20)==0); //等待数据发送完毕
}
}
/*********************************************************************************************************
** 函数名称: void UARTn_SendData(uint8 n,uint8 *data_buf,uint8 count)
** 功能描述: 从串口发送多字节数据
** 输 入: n :0-UART0 1-UART1
** data_buf:发送数据缓冲区首地址
** count :发送字节数
** 输 出: 无
** 全局变量:
** 调用模块: 程序采用查询方式,并且没有使用FIFO
********************************************************************************************************/
void UARTn_SendData(uint8 n,uint8 *data_buf,uint8 count)
{
uint8 i;
for(i=0;i<count;i++)
{
UARTn_SendByte(n,data_buf[i]); //发送数据
}
}
/*********************************************************************************************************
** 函数名称: void UARTn_RcvData(uint8 n,uint8 *data_buf,uint8 count)
** 功能描述: 从串口接收多字节数据
** 输 入: n :0-UART0 1-UART1
** data_buf:接收数据缓冲区首地址
** count :接收字节数
** 输 出: 无
** 全局变量:
** 调用模块: 程序采用查询方式,存在死等待,没有使用FIFO
********************************************************************************************************/
void UARTn_RcvData(uint8 n,uint8 *data_buf,uint8 count)
{
uint8 i;
if(n == 0)
{
for(i=0;i<count;i++)
{
while((U0LSR & 0x01) == 0); //等待接收标志置位
data_buf[i] = U0RBR; //保存接收到的数据
}
}
if(n == 1)
{
for(i=0;i<count;i++)
{
while((U1LSR & 0x01) == 0); //等待接收标志置位
data_buf[i] = U1RBR; //保存接收到的数据
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -