📄 uart.c
字号:
Comm0RxBufCtr = 0;
Comm0RxInIx = 0;
Comm0RxOutIx = 0;
#endif
#if COMM0_TXD_EN > 0 // 初始化发送的各种变量
Comm0TxBufCtr = 0;
Comm0TxInIx = 0;
Comm0TxOutIx = 0;
Comm0bCanSend = 0; // 串口0寄存器发送忙标志 0允许
#endif
}
#endif
/********************************************************************************************************
* 功 能 : 串口0中断响应函数
* 入 口 : 无
* 返 回 : 无
* 说 明 : 1> 使用串口中断前 先用Comm0CfgPort 函数配置好波特率 工作模式等信息
* 2> 使用串口中断前 再调用Comm0VarInit 函数初始化各种变量 否则工作可能出错
* 3> 如果使能串口0接收部分则 需要配置接收缓存 此缓存不能太小 发送方的数据根据波特率的关系处理发送
* 速度和MCU的处理速度(串口进缓存24MHz <40us)决定发送速度不能太快 否则后面的数据会抛弃 造成数据
* 的丢失
* 4> 如果使能串口发送部分 需要配置好发送缓存 此发送缓存的大小不做特殊要求 但太小会影响本地的MCU的
* 处理本地事务的能力 (特别是前后模式的程序和波特率低的情况)
* 5> 如果是在OS中使用 可以启用通知函数给串口接收分析任务 分析接收的数据 参考程序中屏蔽的函数
* 6> 中断响应的速度与COMM_MEM_SEL和高优先级中断的响应时间有关 如果接收数据很快可以加 DISABLE命令
********************************************************************************************************/
#if (COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0) || ( COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0)
//__irq void Comm0IntISR (void)
void Uart0_Exception (void)
{
INT8U IIRValue;
INT8U LSRValue;
INT8U Dummy;
VICVectAddr = 0; // Acknowledge Interrupt
IIRValue = U0IIR; // 读中断状态 能进入到这里 一般表示是有中断发生的 检查状态
IIRValue >>= 1; // 所以不用在对U0IIR 0bit检查
IIRValue &= 0x07; // check bit 1~3, interrupt identification
switch (IIRValue) { // 根据中断信息来处理
case IIR_RLS : // -- 中断标志 接收线状态 暂时未处理
LSRValue = U0LSR; //
Dummy = LSRValue; //
break;
case IIR_RDA: // -- 中断标志 接收数据
Dummy = U0RBR; // 读数据
if (Comm0RxBufCtr < COMM0_RXD_SIZE) { // 检查缓冲大小
Comm0RxBufCtr++; // 接收缓存计数器加1
Comm0RxBuf[Comm0RxInIx++] = Dummy; // 接收到的数据进缓存
if (Comm0RxInIx >= COMM0_RXD_SIZE) { // 处理索引
Comm0RxInIx = 0; // 进入索引复位
}
}
break;
case IIR_CTI: // -- 中断标志 超时
U0IER = U0IER & (~0x01); // 禁止接收及字符超时中断 暂时未处理
break;
case IIR_THRE: // -- 中断标志 发送数据
if (Comm0TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据
Comm0TxBufCtr--; // 缓存计数器减1
U0THR = Comm0TxBuf[Comm0TxOutIx++]; // 读走一个数据到发送寄存器
if (Comm0TxOutIx >= COMM0_TXD_SIZE) { // 判断
Comm0TxOutIx = 0; // 复位
}
} else {
Comm0bCanSend = 0; // 发送标志为0表示 可以直接发送信息
}
break;
default : // 未定义
break;
}
}
#endif
/********************************************************************************************************
* 功 能 : 串口0读1则数据
* 入 口 : 'err' 返回错误信息的指针
* 返 回 : 1> 读到的数据
* 2> err=COMM_RXD_EMPTY 接收缓存没有数据
* 3> err=COMM_RXD_OK 正确在接收缓存读到数据
* 说 明 : 1> 在调用此函数前 最好用Comm0RxGetNMsgs函数检查一下接收缓存里面有没有信息
* 2> 如果不按1>的用法用 则要对返回的错误代码分析
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GET_EN > 0
INT8U Comm0RxGetChar (INT8U *err)
{
INT8U msg;
*err = COMM_RXD_EMPTY; /* 返回代码为接收为空 */
COMM_ENTER_CRITICAL(); /* 进入临界 */
if (Comm0RxBufCtr > 0) { /* 检测接收缓存是否有数据 */
Comm0RxBufCtr--; /* 有数据计数器减1 */
msg = Comm0RxBuf[Comm0RxOutIx++]; /* 取出数据 */
*err = COMM_RXD_OK; /* 返回代码为读数据正确 */
if (Comm0RxOutIx >= COMM0_RXD_SIZE) { /* 检查出数据计数器 是否大于最大接收缓存 */
Comm0RxOutIx = 0; /* 是复位出数据计数器 */
}
}
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (msg);
}
#endif
/********************************************************************************************************
* 功 能 : 检测接收缓存中的数据个数
* 入 口 : 无
* 返 回 : 缓存中的数据个数
* 说 明 : 无
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GETNMSGS_EN > 0
INT16U Comm0RxGetNMsgs (void)
{
COMM0_RXD_TYPE counter;
COMM_ENTER_CRITICAL(); /* 进入临界 */
counter = Comm0RxBufCtr; /* 取接收计数器数据 */
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (counter); /* 返回接收缓存计数 */
}
#endif
/********************************************************************************************************
* 功 能 : 一次串口0读N则数据
* 入 口 : 'p' 返回数据信息的指针
* 'len' 读的数据长度 < COMM0_RXD_SIZE
* 返 回 : 1> COMM_RXD_EMPTY 读数据为空 一般是len为空 或接收缓存中没有数据
* 2> COMM_RXD_FALSE 错误读数据 一般为len大于数据接收缓存中的数据
* 3> COMM_RXD_OK 数据正确读到
* 说 明 : 1> 对于返回参数2> 可以使用Comm0RxGetNMsgs 先取得缓存中的数据个数再一次读走
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_RXD_EN > 0 && COMM0_RXD_GETS_EN > 0
INT8U Comm0RxGetsChar (INT8U *s, COMM0_RXD_TYPE len)
{
COMM_ENTER_CRITICAL(); /* 进入临界 处理Comm0RxBufCtr */
if ((len == 0) || (Comm0RxBufCtr == 0)) { /* 检查数据长度 和接收缓存是否为空 */
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (COMM_RXD_EMPTY); /* 返回代码为接收空 */
}
if (len > Comm0RxBufCtr) { /* 检查读数长度跟实际接收缓存数据个数 */
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (COMM_RXD_FALSE); /* 返回代码为 读数据失败 */
}
COMM_EXIT_CRITICAL(); /* 退出临界 */
/* 必须退出临界以便其他的中断响应 否则len大时就会影响中断*/
while (len--) { /* 读走len个数据 */
COMM_ENTER_CRITICAL(); /* 进入临界 处理Comm0RxBufCtr */
*s++ = Comm0RxBuf[Comm0RxOutIx++]; /* 取出数据 */
Comm0RxBufCtr--; /* 接收缓存计数器减1 */
if (Comm0RxOutIx >= COMM0_RXD_SIZE) { /* 处理接收出数据计数器 */
Comm0RxOutIx = 0; /* 复位出数据计数器 */
}
COMM_EXIT_CRITICAL(); /* 退出临界 */
}
return (COMM_RXD_OK); /* 返回代码为 接收到正确数据 */
}
#endif
/********************************************************************************************************
* 功 能 : 来不及发送的消息进入发送缓存
* 入 口 : 'Data' 进入缓存的消息数据
* 返 回 : 1> COMM_TXD_FLOODL 发送消息进入缓存满 (失败)
* 2> COMM_TXD_OK 发送消息进入缓存OK
* 说 明 : 1> 内部模式 用户不能调用
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0
static void Comm0TxInBuf (INT8U Data)
{
if (Comm0TxBufCtr < COMM0_TXD_SIZE) { /* 处理发送缓存计数器 */
Comm0TxBufCtr++; /* 发送缓存计数器加1 */
Comm0TxBuf[Comm0TxInIx++] = Data; /* 来不及发送的数据进发送缓存 */
if (Comm0TxInIx >= COMM0_TXD_SIZE) { /* 处理发送进缓存计数器 */
Comm0TxInIx = 0; /* 复位发送进缓存计数器 */
}
}
}
#endif
/********************************************************************************************************
* 功 能 : COMM0 发送1 BYTE数据
* 入 口 : 'Date' 发送的数据
* 返 回 : 1> COMM_TXD_OK 发送数据OK
* 2> COMM_TXD_FALSE 发送失败 一般是发送缓存已满
* 说 明 : 1> SBUF发送寄存器为空时直接把要发送的数据放到发送缓存
* 2> SBUF发送寄存器为忙时来不及发的数据进入到发送缓存
* 3> 发送缓存满时直接返回发送失败
********************************************************************************************************/
#if COMM0_UNIT_EN > 0 && COMM0_TXD_EN > 0 && COMM0_TXD_PUT_EN > 0
INT8U Comm0TxPutChar (INT8U Data)
{
COMM_ENTER_CRITICAL(); /* 进入临界 */
if (!Comm0bCanSend) { /* 判断串口直接发送允许标志位 0为允许 */
Comm0bCanSend = 1; /* 设置为忙 */
U0THR = Data; /* 发送出数据 */
COMM_EXIT_CRITICAL(); /* 退出临界 */
return (COMM_TXD_OK); /* 返回代码为发送OK */
}
if (Comm0TxBufCtr >= COMM0_TXD_SIZE) { /* 判断发送缓存计数器是否为最大发送缓存 */
COMM_EXIT_CRITICAL(); /* 是退出临界 不处理 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -