📄 serial_communication.c
字号:
#include <reg52.h> //头文件
#include <rtx51tny.h>
#define uchar unsigned char //宏定义
#define OUTBUF_LEN 8 //串行口发送缓冲区的长度
uchar outbuf_start; //串行口发送缓冲区的起点
uchar outbuf_end; //串行口发送缓冲区的终点
idata char outbuf[OUTBUF_LEN]; //串行口发送缓冲区
uchar out_task = 0xff; //串行口输出任务的任务号
#define INBUF_LEN 8 //串行口接收缓冲区的长度
uchar inbuf_start; //串行口接收缓冲区的起点
uchar inbuf_end; //串行口接收缓冲区的终点
idata char inbuf[INBUF_LEN]; //串行口接收缓冲区
uchar in_task = 0xff; //串行口输入任务的任务号
#define CTRL_Q 0x11
#define CTRL_S 0x13
bit sendfull; //发送缓冲区满标志位
bit sendactive; //发送激活标志位
bit sendstop; //发送停止标志位
void putbuf (char c)
{
if (!sendfull) //判断发送缓冲区满标志位
{
if (!sendactive && !sendstop) //缓冲区未满,发送器未处于活动态
{
sendactive = 1;
SBUF = c; //直接发送第一个字符到SBUF,并启动发送
}
else
{
outbuf[outbuf_end++ & (OUTBUF_LEN-1)] = c; //向定义的发送缓冲区传送字符
if (((outbuf_end ^ outbuf_start) & (OUTBUF_LEN-1)) == 0)
sendfull = 1; //缓冲区满标志置位
}
}
}
char putchar (char c)
{
if (c == '\n') //扩展一行新字符
{
while (sendfull) //如果发送缓冲区满,则等待
{
out_task = os_running_task_id (); //置位输出任务号
os_wait (K_SIG, 0, 0); //等待信号
out_task = 0xff; //输出任务号清零
}
putbuf (0x0D); //在LF换行符之前发送CR回车符
}
while (sendfull) //如果发送缓冲区满,则等待
{
out_task = os_running_task_id (); //置位输出任务号
os_wait (K_SIG, 0, 0); //等待信号
out_task = 0xff; //输出任务号清零
}
putbuf (c); //发送字符
return c; //返回字符
}
char _getkey (void)
{
while (inbuf_end == inbuf_start) //等待
{
in_task = os_running_task_id (); //置位输入任务号
os_wait (K_SIG, 0, 0); //等待信号
in_task = 0xff; //输入任务号清零
}
return (inbuf[inbuf_start++ & (INBUF_LEN-1)]); //返回值
}
void serial () interrupt 4 using 2 //中断响应函数
{
unsigned char c;
bit start_trans = 0;
if (RI) //RI置1,接收中断
{
c = SBUF; //读SBUF
RI = 0; //中断请求标志RI清零
switch (c) //字符处理
{
case CTRL_S: //如果是CTRL_S
sendstop = 1; //置位sendstop,停止发送
break;
case CTRL_Q: //如果是CTRL_Q
start_trans = sendstop; //开始发送
sendstop = 0;
break;
default: //对于其它字符
if (inbuf_start + INBUF_LEN != inbuf_end) //则读入输入缓冲区
{
inbuf[inbuf_end++ & (INBUF_LEN-1)] = c;
}
if (in_task != 0xFF) //如果是任务等待
isr_send_signal (in_task); //发送信号
break;
}
}
if (TI || start_trans) //TI置位,发送中断
{
TI = 0; //中断请求标志TI清零
if (outbuf_start != outbuf_end) //如果输入缓冲区接收到字符
{
if (!sendstop)
{ //发送字符
SBUF = outbuf[outbuf_start++ & (OUTBUF_LEN-1)];
sendfull = 0; // sendfull 标志清零
if (out_task != 0xFF) //如果是任务等待
isr_send_signal (out_task); //发送信号
}
}
else sendactive = 0; //全部发送完,sendactive清零
}
}
void init_serial (void)
{
SCON = 0x50; //串行口方式1,8位 UART, 允许接收
TMOD = 0x20; //定时器方式2,8位自动重装
TH1 = 0xf3; //波特率2400bit/s
TR1 = 1; //启动定时器T1
ES = 1; //允许串行口中断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -