📄 serial.c
字号:
/**********************************************************************************************
**
**
**
**
**
**
**------------------------------------文件信息-----------------------------------------------**
** 文 件 名: serial.c
** 描 述: 中断方式、收发各8字节缓冲区,串行口通讯程序
** 作 者: wickman
** 日 期: 2006.5.28
** 版 本: v0.1
**------------------------------------历史信息-----------------------------------------------**
** 描 述:
** 修 改 人:
** 日 期:
**------------------------------------版本信息-----------------------------------------------**
** 描 述:
** 日 期:
** 版 本:
**-------------------------------------------------------------------------------------------**
**********************************************************************************************/
#include <REGX52.H>
#include "serial.h"
#ifdef __not_lost__ // 是否使用不丢失数据的方法从SBUF读取数据(但因此会引起系统增加进入中断处理程序的次数)
static void serial_isr(void)interrupt 4 using 1
{
/*------------------------------- 接收数据中断 ----------------------------------------*/
if (RI) {
if (istart + ILEN != iend) {
inbuf[iend++ & (ILEN-1)] = SBUF; // 但字符放入缓冲区
RI = 0; // 清除中断请求标志
}
}
/*------------------------------- 发送数据中断 ----------------------------------------*/
if (TI) {
TI = 0; // 清除中断请求标志
if (ostart != oend) { // 如果缓冲区内有字符
SBUF = outbuf[ostart++ & (OLEN-1)]; // 传输字符
sendfull = 0; // 清除'sendfull'标志
}
else { // 如果所有的字符被传输
sendactive = 0; // 清除 'sendactive'
}
}
}
#else // 当缓冲区满则丢弃已经收到的数据
static void serial_isr(void)interrupt 4 using 1
{
unsigned char c;
/*------------------------------- 接收数据中断 ----------------------------------------*/
if (RI) {
c = SBUF; // 读字符
RI = 0; // 清除中断请求标志
if (istart + ILEN != iend) {
inbuf[iend++ & (ILEN-1)] = c; // 但字符放入缓冲区
}
}
/*------------------------------- 发送数据中断 ----------------------------------------*/
if (TI) {
TI = 0; // 清除中断请求标志
if (ostart != oend) { // 如果缓冲区内有字符
SBUF = outbuf[ostart++ & (OLEN-1)]; // 传输字符
sendfull = 0; // 清除'sendfull'标志
}
else { // 如果所有的字符被传输
sendactive = 0; // 清除 'sendactive'
}
}
}
#endif
void serial_init(unsigned long xtal,unsigned long baudrate)
{
/*------------------------------- 串行缓冲区初始化 -------------------------------------*/
istart = 0; // 空接收缓冲区
iend = 0;
ostart = 0; // 空发送缓冲区
oend = 0;
sendactive = 0; // 发送器无效
sendfull = 0; // 清除'sendfull'标志
/*------------------------------- 串口初始化设置 ---------------------------------------*/
TMOD = 0x20;
TH1 = TL1 = 256 - (unsigned char)(xtal / 12.0 / 16 / baudrate);
PCON |= 0x80;
TR1 = 1;
SCON = 0x50;
ES=1;
}
/****************************************************************************
** 函数名称: putbuf
** 功能描述: 写入一个字符到SBUF或传输缓冲区
** 输入参数: 1. char c : 输入字符
** 输出参数: 无
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
**---------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**---------------------------------------------------------------------------
****************************************************************************/
void putbuf (char c) {
if (!sendfull) { // 若缓冲区未满则发送
if (!sendactive) { // 若发送器未激活
sendactive = 1; // 则直接传送第一个字符到
SBUF = c; // SBUF来启动发送器
}
else {
ES = 0; // 在缓冲区更新期间禁止串行中断
outbuf[oend++ & (OLEN-1)] = c; // 放字符到发送缓冲区
if (((oend ^ ostart) & (OLEN-1)) == 0) {
sendfull = 1;
} // 若缓冲区满置标志
ES = 1; // 则再次允许串行口中断
}
}
}
/****************************************************************************
** 函数名称: putchar
** 功能描述: 替换标准库函数putchar程序。printf函数使用putchar输出一个字符
** 输入参数: 1. char c : 输入字符
** 输出参数: 2. char : 输出该字符
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
**---------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**---------------------------------------------------------------------------
****************************************************************************/
char putchar (char c) {
if (c == '\n') { // 扩展新一行字符
while (sendfull); // 等待直道缓冲区有空间
putbuf (0x0D); // 在LF前发送CR用于<新行>
}
while (sendfull); // 等待直到缓冲区有空间
putbuf (c); // 把字符放入缓冲区
return (c);
}
/****************************************************************************
** 函数名称: _getkey
** 功能描述: 替换标准库函数_getkey程序,getchar和gets函数使用_getkey来读字符
** 输入参数: 无
** 输出参数: char :输出从缓冲区中读出的字符
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
**---------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**---------------------------------------------------------------------------
****************************************************************************/
char _getkey (void) {
char c;
while (iend == istart); // 等待直道有字符
ES = 0; // 在缓冲区更新期间禁止中断
c = inbuf[istart++ & (ILEN-1)];
ES = 1; // 再次允许串行口中断
return (c);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -