⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 波特率可变;中断方式接收、发送;收发独立8字节缓冲区;可选择是否在满缓冲区后丢弃数据
💻 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 + -