📄 uart.c
字号:
/********************************************************************************************************
* 文 件 名 : Comm.C
* 程 序 员 : (CaiJie) hnclcj@gmail.com
* (c) Copyright 2007-2007, CaiJie
* All Rights Reserved
* 说 明 : 这里的串口函数都是建立在LPC ARM7的基础上的 应用时根据硬件环境更改硬件相关函数 (硬件函数如下)
********************************************************************************************************/
#define COMM_GLOBALS
#include "includes.h"
#if COMM_MODULE_EN > 0
/********************************************************************************************************
* 局部常数
********************************************************************************************************/
#ifndef MCU_Fosc /* MCU的晶振频率设置 这是计算波特率必须的参数 */
//#error "no defien MCU_Fosc e.g. #define MCU_Fosc 11059200L "
#endif
#define IER_RBR 0x01 // 中断使能 接收数据
#define IER_THRE 0x02 // 中断使能 发送数据
#define IER_RLS 0x04 // 中断使能 线状态 (可能涉及字符超时)
#define IIR_PEND 0x01 // 中断标志 是否中断发生
#define IIR_RLS 0x03 // 中断标志 接收线状态
#define IIR_RDA 0x02 // 中断标志 接收数据
#define IIR_CTI 0x06 // 中断标志 超时
#define IIR_THRE 0x01 // 中断标志 发送数据
#define LSR_RDR 0x01 //
#define LSR_OE 0x02 //
#define LSR_PE 0x04 //
#define LSR_FE 0x08 //
#define LSR_BI 0x10 //
#define LSR_THRE 0x20 //
#define LSR_TEMT 0x40 //
#define LSR_RXFE 0x80 //
/********************************************************************************************************
* 局部变量
********************************************************************************************************/
// 串口0的变量信息
#if COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 // 串口0接收变量
static INT8U volatile Comm0RxBuf[COMM0_RXD_SIZE]; // 串口0接收分配缓存
static COMM0_RXD_TYPE volatile Comm0RxBufCtr; // 串口0接收数据个数计数器
static COMM0_RXD_TYPE volatile Comm0RxInIx; // 串口0接收数据入缓存位置索引
static COMM0_RXD_TYPE volatile Comm0RxOutIx; // 串口0接收数据出缓存位置索引
#endif
#if COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 // 串口0发送变量
static BOOL volatile Comm0bCanSend; // 串口0发送忙标志 0=不忙 1=忙
static INT8U volatile Comm0TxBuf[COMM0_TXD_SIZE]; // 串口0发送分配缓存
static COMM0_TXD_TYPE volatile Comm0TxBufCtr; // 串口0发送数据个数计数器
static COMM0_TXD_TYPE volatile Comm0TxInIx; // 串口0发送数据入缓存位置索引
static COMM0_TXD_TYPE volatile Comm0TxOutIx; // 串口0发送数据出缓存位置索引
#endif
// 串口1的变量信息
#if COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0 // 串口1接收变量
static INT8U volatile Comm1RxBuf[COMM1_RXD_SIZE]; // 串口1接收分配缓存
static COMM1_RXD_TYPE volatile Comm1RxBufCtr; // 串口1接收数据个数计数器
static COMM1_RXD_TYPE volatile Comm1RxInIx; // 串口1接收数据入缓存位置索引
static COMM1_RXD_TYPE volatile Comm1RxOutIx; // 串口1接收数据出缓存位置索引
#endif
#if COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0 // 串口1发送变量
static BOOL volatile Comm1bCanSend; // 串口1发送忙标志 0=不忙 1=忙
static INT8U volatile Comm1TxBuf[COMM1_TXD_SIZE]; // 串口1发送分配缓存
static COMM1_TXD_TYPE volatile Comm1TxBufCtr; // 串口1发送数据个数计数器
static COMM1_TXD_TYPE volatile Comm1TxInIx; // 串口1发送数据入缓存位置索引
static COMM1_TXD_TYPE volatile Comm1TxOutIx; // 串口1发送数据出缓存位置索引
#endif
/********************************************************************************************************
* 局部函数
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 /* 串口0的本地函数 */
static void Comm0TxInBuf (INT8U Data);
//__irq void Comm0IntISR (void);
extern void UART0_Handler(void);
#endif
#if COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0 /* 串口0的本地函数 */
static void Comm1TxInBuf (INT8U Data);
//__irq void Comm1IntISR (void);
extern void UART1_Handler(void);
#endif
/********************************************************************************************************
* 功 能 : COMM0 工作状态初始化
* 入 口 : 'baud' 波特率 最大波特率为实际硬件能支持的波特率和数据处理能力设置
* 'parity' 奇偶效验 这里根据bits自动为固定模式
* 'bits' 数据位 为8或9 其他数据则在C51为8BIT移位模式
* 'stops' 停止位 这里根据bits自行更改为固定模式 为了兼容以后的版本预留
* 返 回 : 1> COMM_ON_ERR 串口设置没有错误
* 2> COMM_BAD_BUAD 错误的波特率
* 3> COMM_BAD_MODE 错误的工作模式
* 说 明 : 1> baud 为600以下时 需要屏蔽掉SETBIT(PCON,SMOD)波特率倍增模式
* 2> TH1的波特率发生率的计算公式需要更改
********************************************************************************************************/
#if (COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0) || ( COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0)
INT8U Comm0CfgPort (INT32U baud, INT8U parity, INT8U bits, INT8U stops)
{
INT32U Fdiv;
INT8U mode;
if ((baud == 0) || (baud > 115200)) { // 波特率过滤
return (COMM_BAD_BAUD); // 错误波特率
}
if ((bits <5) || (bits > 8)) { // 数据位数
return (COMM_BAD_MODE); // 错误模式
}
if (parity > 4) { // 校验
return (COMM_BAD_MODE); // 错误模式
}
if ((stops == 0) || (stops > 2)) { // 停止位
return (COMM_BAD_MODE); // 错误模式
}
mode = 0; // 准备设置UART工作模式 BITS
switch (parity) { // 校验模式
case 0 : // 奇校验
mode &= ~(3 << 4); //
mode |= (0 << 4); // 1
break;
case 1 : // 偶校验
mode &= ~(3 << 4); //
mode |= (1 << 4); // 1
break;
case 2 : // 强制为1
mode &= ~(3 << 4); //
mode |= (2 << 4); // 1
break;
case 3 : // 强制为0
mode &= ~(3 << 4); //
mode |= (3 << 4); // 1
break;
default : //
return(COMM_BAD_MODE); // 错误模式
}
switch (bits) { // 设置bits
case 5 : // 5
mode &= ~(3 << 0); //
mode |= (0 << 0); // 0
break;
case 6 : // 6
mode &= ~(3 << 0); //
mode |= (1 << 0); // 1
break;
case 7 : // 7
mode &= ~(3 << 0); //
mode |= (2 << 0); // 2
break;
case 8 : // 8
mode &= ~(3 << 0); //
mode |= (3 << 0); // 3
break;
default: //
return(COMM_BAD_MODE); // 错误模式
}
switch (stops) { // 停止位
case 1 : //
mode &= ~(1 << 2); //
mode |= (0 << 2); // 0
break;
case 2 : //
mode &= ~(1 << 2); //
mode |= (1 << 2); // 1
break;
default : //
return(COMM_BAD_MODE); // 错误模式
}
U0LCR = 0x80; // 允许访问除数寄存器
Fdiv = (Fpclk / 16 ) / baud ; //
U0DLM = (INT8U)(Fdiv >> 8); // 波涛率
U0DLL = (INT8U)(Fdiv >> 0); // 波特率
U0LCR = 0x00; // DLAB = 0(禁止访问除数寄存器)
U0FCR = 0x07; // 使能并初始化FIFO 1字节触发中断
U0LCR = mode; // 设置好通讯模式数据
U0IER = IER_RBR | IER_THRE; // 允许接收和发送中断 线状态中断未使能
// U0IER = IER_RBR | IER_THRE | IER_RLS; // Enable UART0 interrupt
return (COMM_NO_ERR);
}
#endif
/********************************************************************************************************
* 功 能 : 初始化串口0的各种变量
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if (COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0) || ( COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0)
void Comm0Init (void)
{
PINSEL0 &= ~(0x05<<0); // 清除设置 0,1=TXD 2,3=RXD
PINSEL0 |= (0x05<<0); // 连接GPIO到TXD RXD
IRQInstall(UART0_INT, (void *)UART0_Handler); // 装载IRQ
// IRQInstall(UART0_INT, (void *)(Comm0IntISR));// 配置UART为向量中断
#if COMM0_RXD_EN > 0 // 初始化接收的各种变量
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -