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

📄 serial.c

📁 这是《Keil Cx51 V7.0单片机高级语言编程与uVision2应用实践》教材各章中列出的全部程序例子。
💻 C
字号:

/*****************************************************************************/
/*       SERIAL.C:  应用RTX-51 tiny的串行口中断控制器     */
/*****************************************************************************/
#include <reg52.h>                    /* 8052单片机特殊功能寄存器定义 */
#include <rtx51tny.h>                 /* RTX-51 tiny 功能函数定义 */

#define  OLEN  8                      /* 定义串行口通信发送缓冲区的大小 */
unsigned char  ostart;                /* 串行口发送缓冲区起点 */
unsigned char  oend;                  /* 串行口发送缓冲区终点 */
idata    char  outbuf[OLEN];          /* 串行口发送缓冲区 */
unsigned char  otask = 0xff;          /* 输出任务的任务号 */

#define  ILEN  8                      /* 定义串行口通信接收缓冲区大小 */
unsigned char  istart;                /* 串行口接收缓冲区起点 */
unsigned char  iend;                  /* 串行口接收缓冲区终点 */
idata    char  inbuf[ILEN];           /* 串行口接收缓冲区 */
unsigned char  itask = 0xff;          /* 输入任务的任务号 */

#define   CTRL_Q  0x11                /* 定义CTRL_Q代码 */
#define   CTRL_S  0x13                /* 定义CTRL_S代码 */

bit   sendfull;                       /* 发送缓冲区满标志 */
bit   sendactive;                     /* 发送激活标志 */
bit   sendstop;                       /* XOFF 字符标志 */

/******************************************************************************/
/*       putbuf:  向SBUF 或发送缓冲区写入字符函数                             */
/******************************************************************************/
putbuf (char c)  {
  if (!sendfull)  {                   /* 仅当缓冲区未满时发送 */
    if (!sendactive && !sendstop)  {  /* 如果发送器未处于活动态:*/
      sendactive = 1;                 /* 直接发送第一个字符 */
      SBUF = c;                       /* 到SBUF,启动发送 */
    }
    else  {                          /* 否则: */
      outbuf[oend++ & (OLEN-1)] = c;  /* 向发送缓冲区传送字符 */
      if (((oend ^ ostart) & (OLEN-1)) == 0)  sendfull = 1;
    }                                 /* 置位缓冲区满标志 */
  }
}

/******************************************************************************/
/*       putchar:  中断控制器的putchar 函数                                  */
/******************************************************************************/
char putchar (char c)  {
  if (c == '\n')  {                   /* 扩展一行新字符: */
    while (sendfull)  {               /* 等待发送缓冲区空 */
      otask = os_running_task_id ();  /* 置位输出任务号 */
      os_wait (K_SIG, 0, 0);          /* RTX-51 调用: 等待信号 */
      otask = 0xff;                   /* 清零输出任务号 */
    }
    putbuf (0x0D);                    /* 在换行符LF之前发送回车符CR */
  }
  while (sendfull)  {                 /* 等待发送缓冲区空 */
    otask = os_running_task_id ();    /*  置位输出任务号 */
    os_wait (K_SIG, 0, 0);            /* RTX-51 调用: 等待信号 */
    otask = 0xff;                     /* 清零输出任务号 */
  }
  putbuf (c);                         /* 发送字符 */
  return (c);                         /* 返回字符 */
}

/******************************************************************************/
/*       _getkey:  中断控制器函数 _getkey                                     */
/******************************************************************************/
char _getkey (void)  {
  while  (iend == istart)  {
    itask = os_running_task_id ();    /* 置位输入任务号 */
    os_wait (K_SIG, 0, 0);            /* RTX-51 调用: 等待信号 */
    itask = 0xff;                     /* 清零输入任务号 */
  }
  return (inbuf[istart++ & (ILEN-1)]);
}

/******************************************************************************/
/*       serial:  串行接收/发送中断                                           */
/******************************************************************************/
serial () interrupt 4 using 2  {     /* 中断使用工作寄存器2区 */
  unsigned char c;
  bit   start_trans = 0;

  if (RI)  {                         /* 如果是接收中断 */
    c = SBUF;                        /* 读字符 */
    RI = 0;                          /* 清零中断请求标志 */
    switch (c)  {                    /* 字符处理 */
      case CTRL_S:
        sendstop = 1;                /* 如果是CTRL_S 则停止发送 */
        break;

      case CTRL_Q:
        start_trans = sendstop;      /* 如果是CTRL_Q 则开始发送 */
        sendstop = 0;
        break;

      default:                       /* 将其它字符读入输入缓冲区 */
        if (istart + ILEN != iend)  {
          inbuf[iend++ & (ILEN-1)] = c;
        }
                                     /* 如果是任务等待:信号就绪 */
        if (itask != 0xFF) isr_send_signal (itask);
        break;
    }
  }

  if (TI || start_trans)  {          /* 如果是发送中断 */
    TI = 0;                          /* 清零中断请求标志 */
    if (ostart != oend)  {           /* 如果输入缓冲区接收到字符 */
      if (!sendstop)  {              /* 且不是CTRL_S */
        SBUF = outbuf[ostart++ & (OLEN-1)];      /* 发送字符 */
        sendfull = 0;                /* 清零sendfull 标志 */
                                     /* 如果是任务等待:信号就绪 */
        if (otask != 0xFF)  isr_send_signal (otask);
      }
    }
    else sendactive = 0;             /* 如果全部发送完则清零sendactive */
  }

}

/******************************************************************************/
/*       serial_init: 串行口初始化                                            */
/******************************************************************************/
serial_init ()  {
  SCON  = 0x50;                      /* 串行口方式1,8位 UART, 允许接收 */
  TMOD |= 0x20;                      /* 定时器方式2,8位自动重装 */
  TH1   = 0xf3;                      /* 2400 波特率 */
  TR1   = 1;                         /* 启动定时器1 */
  ES    = 1;                         /* 允许串行口中断 */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -