📄 uart.c
字号:
return (COMM_TXD_FALSE); /* 发送缓存满 返回代码为发送失败 */
} else {
Comm0TxInBuf(Data); /* 来不及发送的数据一直等到进入发送缓存 */
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (COMM_TXD_OK); /* 返回代码为发送OK */
}
}
#endif
/********************************************************************************************************
* 功 能 : COMM0 发送N BYTE数据
* 入 口 : 'p' 指向发送消息的指针
* 'len' 发送数据的长度
* 返 回 : 1> 实际已经发送的数据长度
* 说 明 : 1> 返回实际发送数据的长度 对剩下的字节 就需要用户自己处理
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 && COMM0_TXD_PUTS_EN > 0
INT8U Comm0TxPutsChar (INT8U *s, COMM0_TXD_TYPE len)
{
COMM0_TXD_TYPE i;
COMM_ENTER_CRITICAL(); // 进入临界
i = COMM0_TXD_SIZE - Comm0TxBufCtr; // 剩下的发送缓存长度
i = i >= len ? len : i; // 处理实际发送数据长度
len = i; // 实际已经发送的数据长度
while (i--) { // 发送数据处理
if (!Comm0bCanSend) { // 检测直接发送条件
Comm0bCanSend = 1; // 可以 置直接发送标志为忙
U0THR = *s; // 发送数据
} else { // 理解下面的指令实际就是变相的while(!TI)
Comm0TxInBuf(*s); // 发送不了的数据进入发送缓存
}
s++; // 指针处理
}
COMM_EXIT_CRITICAL(); // 退出临界
return (len); // 返回实际已经发送的数据长度
}
#endif
/********************************************************************************************************
* 功 能 : COMM1 工作状态初始化
* 入 口 : '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 (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0)
INT8U Comm1CfgPort (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); // 错误模式
}
U1LCR = 0x80; // 允许访问除数寄存器
Fdiv = (Fpclk / 16 ) / baud ; //
U1DLM = (INT8U)(Fdiv >> 8); // 波涛率
U1DLL = (INT8U)(Fdiv >> 0); // 波特率
U1LCR = 0x00; // DLAB = 0(禁止访问除数寄存器)
U1FCR = 0x07; // 使能并初始化FIFO 1字节触发中断
U1LCR = mode; // 设置好通讯模式数据
U1IER = IER_RBR | IER_THRE; // 允许接收和发送中断 线状态中断未使能
// U1IER = IER_RBR | IER_THRE | IER_RLS; // Enable UART0 interrupt
return (COMM_NO_ERR);
}
#endif
/********************************************************************************************************
* 功 能 : 初始化串口1的各种变量
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0)
void Comm1Initr (void)
{
PINSEL0 &= ~(0x05 << 16); // 清除设置 0,1=TXD 2,3=RXD
PINSEL0 |= (0x05 << 16); // 连接GPIO到TXD RXD
IRQInstall(UART0_INT, (void *)UART1_Handler); // 装载IRQ
// IRQInstall(UART0_INT, (void *)(Comm1IntISR));// 配置UART为向量中断
#if COMM1_RXD_EN > 0 // 初始化接收的各种变量
Comm1RxBufCtr = 0;
Comm1RxInIx = 0;
Comm1RxOutIx = 0;
#endif
#if COMM1_TXD_EN > 0 // 初始化发送的各种变量
Comm1TxBufCtr = 0;
Comm1TxInIx = 0;
Comm1TxOutIx = 0;
Comm1bCanSend = 0; // 串口0寄存器发送忙标志 0允许
#endif
}
#endif
/********************************************************************************************************
* 功 能 : 串口1中断响应函数
* 入 口 : 无
* 返 回 : 无
* 说 明 : 1> 使用串口中断前 先用Comm1CfgPort 函数配置好波特率 工作模式等信息
* 2> 使用串口中断前 再调用Comm1VarInit 函数初始化各种变量 否则工作可能出错
* 3> 如果使能串口0接收部分则 需要配置接收缓存 此缓存不能太小 发送方的数据根据波特率的关系处理发送
* 速度和MCU的处理速度(串口进缓存24MHz <40us)决定发送速度不能太快 否则后面的数据会抛弃 造成数据
* 的丢失
* 4> 如果使能串口发送部分 需要配置好发送缓存 此发送缓存的大小不做特殊要求 但太小会影响本地的MCU的
* 处理本地事务的能力 (特别是前后模式的程序和波特率低的情况)
* 5> 如果是在OS中使用 可以启用通知函数给串口接收分析任务 分析接收的数据 参考程序中屏蔽的函数
* 6> 中断响应的速度与COMM_MEM_SEL和高优先级中断的响应时间有关 如果接收数据很快可以加 DISABLE命令
********************************************************************************************************/
#if (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0)
//__irq void Comm1IntISR (void)
void Uart1_Exception (void)
{
INT8U IIRValue;
INT8U LSRValue;
INT8U Dummy;
OS_ENTER_CRITICAL(); //
IIRValue = U1IIR; // 读中断状态 能进入到这里 一般表示是有中断发生的 检查状态
IIRValue >>= 1; // 所以不用在对U0IIR 0bit检查
IIRValue &= 0x07; // check bit 1~3, interrupt identification
switch (IIRValue) { // 根据中断信息来处理
case IIR_RLS : // -- 中断标志 接收线状态 暂时未处理
LSRValue = U1LSR; //
Dummy = LSRValue; //
break;
case IIR_RDA: // -- 中断标志 接收数据
Dummy = U1RBR; // 读数据
if (Comm1RxBufCtr < COMM1_RXD_SIZE) { // 检查缓冲大小
Comm1RxBufCtr++; // 接收缓存计数器加1
Comm1RxBuf[Comm1RxInIx++] = Dummy; // 接收到的数据进缓存
if (Comm1RxInIx >= COMM1_RXD_SIZE) { // 处理索引
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -