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

📄 serial_communication.c

📁 零基础单片机C语言设计全套教程
💻 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 + -