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

📄 serial.c

📁 c51学习的好书!
💻 C
字号:
/*****************************************************************************/
/*       SERIAL.C:  应用RTX-51 tiny的串行口中断控制器     */
/*****************************************************************************/
#include <reg52.h>                    
#include <rtx51tny.h>                 

#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 + -