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