📄 serial.c
字号:
/*****************************************************************************/
/* SERIAL.C: 应用RTX-51 tiny的串行口中断控制器 */
/*****************************************************************************/
#include <reg52.h> /* 8052单片机特殊功能寄存器定义 */
#include <rtx51tny.h> /* RTX-51 tiny 功能函数定义 */
#define OLEN 8 /* 定义串行口通信发送缓冲区的大小 */
unsigned char ostart; /* 串行口发送缓冲区起点 */
unsigned char oend; /* 串行口发送缓冲区终点 */
idata char outbuf[OLEN]; /* 串行口发送缓冲区 */
unsigned char otask = 0xff; /* 输出任务的任务号 */
#define ILEN 8 /* 定义串行口通信接收缓冲区大小 */
unsigned char istart; /* 串行口接收缓冲区起点 */
unsigned char iend; /* 串行口接收缓冲区终点 */
idata char inbuf[ILEN]; /* 串行口接收缓冲区 */
unsigned char itask = 0xff; /* 输入任务的任务号 */
#define CTRL_Q 0x11 /* 定义CTRL_Q代码 */
#define CTRL_S 0x13 /* 定义CTRL_S代码 */
bit sendfull; /* 发送缓冲区满标志 */
bit sendactive; /* 发送激活标志 */
bit sendstop; /* XOFF 字符标志 */
/******************************************************************************/
/* putbuf: 向SBUF 或发送缓冲区写入字符函数 */
/******************************************************************************/
putbuf (char c) {
if (!sendfull) { /* 仅当缓冲区未满时发送 */
if (!sendactive && !sendstop) { /* 如果发送器未处于活动态:*/
sendactive = 1; /* 直接发送第一个字符 */
SBUF = c; /* 到SBUF,启动发送 */
}
else { /* 否则: */
outbuf[oend++ & (OLEN-1)] = c; /* 向发送缓冲区传送字符 */
if (((oend ^ ostart) & (OLEN-1)) == 0) sendfull = 1;
} /* 置位缓冲区满标志 */
}
}
/******************************************************************************/
/* putchar: 中断控制器的putchar 函数 */
/******************************************************************************/
char putchar (char c) {
if (c == '\n') { /* 扩展一行新字符: */
while (sendfull) { /* 等待发送缓冲区空 */
otask = os_running_task_id (); /* 置位输出任务号 */
os_wait (K_SIG, 0, 0); /* RTX-51 调用: 等待信号 */
otask = 0xff; /* 清零输出任务号 */
}
putbuf (0x0D); /* 在换行符LF之前发送回车符CR */
}
while (sendfull) { /* 等待发送缓冲区空 */
otask = os_running_task_id (); /* 置位输出任务号 */
os_wait (K_SIG, 0, 0); /* RTX-51 调用: 等待信号 */
otask = 0xff; /* 清零输出任务号 */
}
putbuf (c); /* 发送字符 */
return (c); /* 返回字符 */
}
/******************************************************************************/
/* _getkey: 中断控制器函数 _getkey */
/******************************************************************************/
char _getkey (void) {
while (iend == istart) {
itask = os_running_task_id (); /* 置位输入任务号 */
os_wait (K_SIG, 0, 0); /* RTX-51 调用: 等待信号 */
itask = 0xff; /* 清零输入任务号 */
}
return (inbuf[istart++ & (ILEN-1)]);
}
/******************************************************************************/
/* serial: 串行接收/发送中断 */
/******************************************************************************/
serial () interrupt 4 using 2 { /* 中断使用工作寄存器2区 */
unsigned char c;
bit start_trans = 0;
if (RI) { /* 如果是接收中断 */
c = SBUF; /* 读字符 */
RI = 0; /* 清零中断请求标志 */
switch (c) { /* 字符处理 */
case CTRL_S:
sendstop = 1; /* 如果是CTRL_S 则停止发送 */
break;
case CTRL_Q:
start_trans = sendstop; /* 如果是CTRL_Q 则开始发送 */
sendstop = 0;
break;
default: /* 将其它字符读入输入缓冲区 */
if (istart + ILEN != iend) {
inbuf[iend++ & (ILEN-1)] = c;
}
/* 如果是任务等待:信号就绪 */
if (itask != 0xFF) isr_send_signal (itask);
break;
}
}
if (TI || start_trans) { /* 如果是发送中断 */
TI = 0; /* 清零中断请求标志 */
if (ostart != oend) { /* 如果输入缓冲区接收到字符 */
if (!sendstop) { /* 且不是CTRL_S */
SBUF = outbuf[ostart++ & (OLEN-1)]; /* 发送字符 */
sendfull = 0; /* 清零sendfull 标志 */
/* 如果是任务等待:信号就绪 */
if (otask != 0xFF) isr_send_signal (otask);
}
}
else sendactive = 0; /* 如果全部发送完则清零sendactive */
}
}
/******************************************************************************/
/* serial_init: 串行口初始化 */
/******************************************************************************/
serial_init () {
SCON = 0x50; /* 串行口方式1,8位 UART, 允许接收 */
TMOD |= 0x20; /* 定时器方式2,8位自动重装 */
TH1 = 0xf3; /* 2400 波特率 */
TR1 = 1; /* 启动定时器1 */
ES = 1; /* 允许串行口中断 */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -