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

📄 rs_demo.c

📁 RS232.C was written to provide all of the basic functionality needed to employ serial I/O in any a
💻 C
字号:
/*

   RS_DEMO: Terminal program to demonstrate most of the functions
   available with RS232.C.

   C. Karcher

*/

#include<conio.h>
#include<dos.h>
#include"rs232.c"           /* full path for rs232.c */

#define BUF_SIZ 1024U       /* 1K input and output buffers */

int initialize(char);       /* Draws screen and initializes port */
void scr_update(int, int);  /* Redefines text window and positions cursor */
void update(int);           /* Decodes function keys and takes appropriate
                               action.  Updates port status display */
int end_it(void);           /* Restores text window and closes port prior
                               to exiting */

int loc_echo,add_nl;        /* global operating mode flags */
char *in_buf,*out_buf;      /* global buffer pointers */

int port_ok;

main()
{

  extern int loc_echo,add_nl;
  char buf1[BUF_SIZ],buf2[BUF_SIZ],in_lin[BUF_SIZ]; /* declare buffers */
  int ip,i_cnt,c,k = 1;

  ctrlbrk(end_it); /* set up control/break routine to insure port is
                      properly close */

  in_buf = buf1; /* initialize global buffer pointers */
  out_buf = buf2;

  port_ok = initialize('1'); /* draw screen and initialize com port 1 */

  loc_echo = add_nl = 0; /* init. misc. options */

  /* become a terminal */
  do{
    if(port_ok > 0){ /* if port was initialized succesfully */
      if((i_cnt = rs_inrcvd()) != 0){ /* anything in input buffer ? */
        if(i_cnt > 1){ /* more than one byte, use rs_getstr to retrieve */
          rs_getstr(i_cnt,in_lin);
          }
        else
          *in_lin = rs_getbyt(); /* only one byte, use rs_getbyt */
        for(ip = 0;ip < i_cnt;ip++){  /* display received bytes */
          c = *(in_lin + ip);
          putch(c);
          if(add_nl && c == 0x0D) /* add NL to CR if applicable */
            putch(0x0A);
          }
        }
      update(0); /* in case any dynamics have changed */
      }
    if(rs_keyhit()){ /* any keyhits ? */
      if((k = getch()) == 0){ /* if first byte 0, it's a function key */
        k = getch();          /* get next byte and call update */
        update(k);
        }
      else if(port_ok > 0){  /* otherwise if port's active, send the byte */
        while(rs_sndbyt(k)){
          if(rs_keyhit()){
            k = getch();
            if(k == 27)
              break;
            else
              ungetch(k);
            }
          }
        if(loc_echo){ /* display it if local echo on */
          putch(k);
          if(add_nl && k == 0x0D) /* add NL to CR if applicable */
            putch(0x0A);
          }
        }
      }
    }while(k != 27); /* fall out if ESC */

  end_it();
  return 0;

}

void update(int key)
{

  int port_update,x_save,y_save,tmp_i;
  unsigned tmp_u;
  extern int loc_echo,add_nl;
  extern char *in_buf,*out_buf;
  long baud[] = {110L,300L,600L,1200L,2400L,4800L,9600L,19200L,
                 38400L,57600L,115200L};
  char parity[] = "NEOSM";
  char *flow_str[] = {"None","XON/XOFF","CTS","DSR","RI","DCD"};
  char *flwstat_str[] = {"Output Enabled","Output Disabled"};
  char *line_str[] = {"Off","On"};
  char *error_str[] = {"None","Break Detected","Framing Error",
                       "Parity Error","Rcv Data Overrun",
                       "Rcv Buffer Overflow"};
  static struct{ /* static struct to hold user selectable characteristics */
    char port;
    int speed;
    int par;
    char dbits;
    char sbits;
    int flw_cnt;
    int dtr;
    int rts;
    int loc_echo;
    int add_nl;
    }select = {'1',4,0,'8','1',RS_FLWOFF,0,0,0,0};

  static struct{ /* static struct to hold dynamic statistics */
    int flow_stat;
    int mod_stat;
    unsigned rcv_buf;
    unsigned xmit_buf;
    int error;
    }dynamic;

  port_update = 0; /* flag to indicate whether or not port should be closed
                      and reopened with new parameters */

  /* Determine action from key code if one was sent.  If port is inactive
     except only command to change port number */
  if(key != 0 && (port_ok > 0 || key == 0x3B)){
    switch(key){
      case 0x3B: /* F1 key - port ID */
        if(++select.port > '4')
          select.port = '1';
        select.speed = 4;
        select.par = 0;
        select.dbits = '8';
        select.sbits = '1';
        port_ok = initialize(select.port);
        break;
      case 0x3C: /* F2 key - baud rate */
        if(++select.speed > 10)
          select.speed = 0;
        port_update = 1;
        scr_update(25,1);
        cprintf("%-6ld",baud[select.speed]);
        scr_update(0,0);
        break;
      case 0x3D: /* F3 key - parity */
        if(++select.par > 4)
          select.par = 0;
        port_update = 1;
        scr_update(44,1);
        putch(parity[select.par]);
        scr_update(0,0);
        break;
      case 0x3E: /* F4 key - data bits */
        if(++select.dbits > '8')
          select.dbits = '7';
        port_update = 1;
        scr_update(61,1);
        putch(select.dbits);
        scr_update(0,0);
        break;
      case 0x3F: /* F5 key - stop bits */
        if(++select.sbits > '2')
          select.sbits = '1';
        port_update = 1;
        scr_update(78,1);
        putch(select.sbits);
        scr_update(0,0);
        break;
      case 0x40: /* F6 key - Set Flow Control */
        if(++select.flw_cnt > 5)
          select.flw_cnt = 0;
        switch(select.flw_cnt){
          case 0:
            rs_setflow(RS_FLWOFF);
            break;
          case 1:
            rs_setflow(RS_FLWXON,RS_XON,RS_XOFF);
            break;
          case 2:
            rs_setflow(RS_FLWHDW,RS_FLWCTS);
            break;
          case 3:
            rs_setflow(RS_FLWHDW,RS_FLWDSR);
            break;
          case 4:
            rs_setflow(RS_FLWHDW,RS_FLWRI);
            break;
          case 5:
            rs_setflow(RS_FLWHDW,RS_FLWDCD);
            break;
          }
        scr_update(21,3);
        cprintf("%-8s",flow_str[select.flw_cnt]);
        scr_update(0,0);
        break;
      case 0x41: /* F7 key - Clear Xmit buffer */
        rs_clrout();
        break;
      case 0x42: /* F8 key - Clear Rcv buffer */
        rs_clrin();
        break;
      case 0x43: /* F9 - toggle DTR */
        if(select.dtr == 0){
          select.dtr = 1;
          rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINON);
          }
        else{
          select.dtr = 0;
          rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINOFF);
          }
        scr_update(10,5);
        cprintf("%-3s",line_str[select.dtr]);
        scr_update(0,0);
        break;
      case 0x44: /* F10 - toggle RTS */
        if(select.rts == 0){
          select.rts = 1;
          rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINON);
          }
        else{
          select.rts = 0;
          rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINOFF);
          }
        scr_update(24,5);
        cprintf("%-3s",line_str[select.rts]);
        scr_update(0,0);
        break;
      case 0x54: /* sh/F1 key - local echo */
        if(select.loc_echo == 1){
          select.loc_echo = 0;
          loc_echo = 0; /* update global variable */
          }
        else{
          select.loc_echo = 1;
          loc_echo = 1; /* update global variable */
          }
        scr_update(47,5);
        cprintf("%-3s",line_str[select.loc_echo]);
        scr_update(0,0);
        break;
      case 0x55: /* sh/F2 key - add newline to carriage return */
        if(select.add_nl == 1){
          select.add_nl = 0;
          add_nl = 0;    /* update global variable */
          }
        else{
          select.add_nl = 1;
          add_nl = 1;    /* update global variable */
          }
        scr_update(77,5);
        cprintf("%-3s",line_str[select.add_nl]);
        scr_update(0,0);
        break;
      case 0x56: /* sh/F3 key - send break */
        rs_break();
        break;
      case 0x57: /* sh/F4 key - send XON */
        rs_setflow(RS_FLWINS,RS_XON);
        break;
      case 0x58: /* sh/F5 key - send XOFF */
        rs_setflow(RS_FLWINS,RS_XOFF);
      }
    }

  if(port_ok <= 0) /* don't continue if port is invalid */
    return;

  if(port_update){ /* new port parameters - close and reopen port */
    rs_close();
    select.flw_cnt = 0;
    scr_update(21,3);
    cprintf("%-8s",flow_str[select.flw_cnt]);
    scr_update(0,0);
    rs_initport(select.port,select.speed[baud],parity[select.par],
      select.dbits,select.sbits,BUF_SIZ,in_buf,BUF_SIZ,out_buf);
    }

  /* check for changed flow control status */
  if((tmp_i = rs_setflow(RS_FLWSTAT)) != dynamic.flow_stat){
    dynamic.flow_stat = tmp_i;
    scr_update(26,9);
    cprintf("%-15s",flwstat_str[dynamic.flow_stat]);
    scr_update(0,0);
    }

  /* check for modem status change */
  tmp_i = rs_modctrl(RS_GETMSR);
  if(tmp_i & 0x0F){  /* if any change bits are set */
    if(tmp_i & RS_CTSCHG){ /* CTS change bit set? */
      scr_update(47,9);
      /* "(tmp_i & RS_CTSSTE) == RS_CTSSTE" equates to one if CTS bit
         is on, otherwise, equates to 0 */
      cprintf("%-3s",line_str[(tmp_i & RS_CTSSTE) == RS_CTSSTE]);
      scr_update(0,0);
      }
    if(tmp_i & RS_DSRCHG){ /* DSR change bit set? */
      scr_update(56,9);
      cprintf("%-3s",line_str[(tmp_i & RS_DSRSTE) == RS_DSRSTE]);
      scr_update(0,0);
      }
    if(tmp_i & RS_RICHG){ /* RI change bit set? */
      scr_update(64,9);
      cprintf("%-3s",line_str[(tmp_i & RS_RISTE) == RS_RISTE]);
      scr_update(0,0);
      }
    if(tmp_i & RS_DCDCHG){ /* DCD change bit set? */
      scr_update(73,9);
      cprintf("%-3s",line_str[(tmp_i & RS_DCDSTE) == RS_DCDSTE]);
      scr_update(0,0);
      }
    }

  tmp_u = rs_inrcvd(); /* update "number of bytes in rcv buffer" if changed */
  if(tmp_u != dynamic.rcv_buf){
    dynamic.rcv_buf = tmp_u;
    scr_update(20,10);
    cprintf("%04u",dynamic.rcv_buf);
    scr_update(0,0);
    }

  tmp_u = rs_outfre(); /* update "number of bytes in xmit buffer" if changed */
  if(tmp_u != dynamic.xmit_buf){
    dynamic.xmit_buf = tmp_u;
    scr_update(40,10);
    cprintf("%04u",BUF_SIZ - dynamic.xmit_buf);
    scr_update(0,0);
    }

  /* Update error status if changed.  Error status is displayed for
     approx. 3 seconds */
  tmp_i = rs_error();
  if(tmp_i){
    if(tmp_i & RS_BKDT)
      tmp_i = 1;
    else if(tmp_i & RS_FERR)
      tmp_i = 2;
    else if(tmp_i & RS_PERR)
      tmp_i = 3;
    else if(tmp_i & RS_ROER)
      tmp_i = 4;
    else if(tmp_i & RS_RBER)
      tmp_i = 5;
    dynamic.error = tmp_i;
    scr_update(54,10);
    cprintf("%-19s",error_str[tmp_i]);
    scr_update(0,0);
    rs_timer(RS_CLRTIM); /* clear timer */
    }
  else if(dynamic.error){
    if(rs_timer(RS_GETTIM) > 50){ /* after about 3 seconds, clear error */
      dynamic.error = 0;
      scr_update(54,10);
      cprintf("%-19s",error_str[0]);
      scr_update(0,0);
      }
    }

}

int initialize(char port)
{
  int x,port_ok;
  char *line_str[] = {"Off","On"};
  char txt[] = "  (F1)Port:   (F2)Speed:2400    (F3)Parity:N  (F4)Data "
               "Bits:8  (F5)Stop Bits:1\r\n\n   (F6)Flow Control:None  "
               "      (F7)Clear Xmit Buffer    (F8)Clear Rcv Buffer\r\n"
               "\n (F9)DTR:Off  (F10)RTS:Off  (Sh/F1)Local Echo:Off  (S"
               "h/F2)Add NewLine to CR:Off\r\n\n  (Sh/F3)Send Break    "
               "(Sh/F4)Send XON    (Sh/F5)Send XOFF   (ESC)End Program\r"
               "\n\n     Flow Control Status:Output Enabled   CTS:     "
               "DSR:     RI:     DCD:\r\n        Rcv Buffer:0000    X"
               "mit Buffer:0000    Error:None";
  extern char *in_buf,*outbuf;


  window(1,1,80,25);
  clrscr();

  cprintf("%s",txt);

  rs_close();
  port_ok = rs_initport(port,RS_B2400,RS_NOPAR,RS_DBIT8,RS_SBIT1,
                        BUF_SIZ,in_buf,BUF_SIZ,out_buf);

  gotoxy(12,1);
  putch(port);

  /* if port initialization OK, get and display modem status and control */
  if(port_ok > 0){
    x = rs_modctrl(RS_GETMSR);
    gotoxy(47,9);
    if(x & RS_CTSSTE)
      cputs(line_str[1]);
    else
      cputs(line_str[0]);
    gotoxy(56,9);
    if(x & RS_DSRSTE)
      cputs(line_str[1]);
    else
      cputs(line_str[0]);
    gotoxy(64,9);
    if(x & RS_RISTE)
      cputs(line_str[1]);
    else
      cputs(line_str[0]);
    gotoxy(73,9);
    if(x & RS_DCDSTE)
      cputs(line_str[1]);
    else
      cputs(line_str[0]);
    /* set DTR and RTS off */
    rs_modctrl(RS_WRTMCR,RS_MCRDTR | RS_MCRRTS,RS_LINOFF);
    }
  else{ /* if port initialization not OK, display message */
    gotoxy(14,1);
    cprintf("%-65s","UNAVAILABLE");
    }

  gotoxy(1,8);
  for(x = 0;x < 80;x++)
    putch(196);

  gotoxy(1,11);
  for(x = 0;x < 80;x++)
    putch(196);

  window(1,12,80,25);

  return port_ok; /* value returned by rs_initport */

}

void scr_update(int x, int y)
{

  static int x_sav,y_sav;

  /* If x != 0, save current cursor position, relocate cursor to new x
     and y.  If x = 0, set window back to terminal window and restore
     old cursor postion */
  if(x){
    x_sav = wherex();
    y_sav = wherey();
    window(1,1,80,25);
    gotoxy(x,y);
    }
  else{
    window(1,12,80,25);
    gotoxy(x_sav,y_sav);
    }

}

int end_it(void)
{

  window(1,1,80,25);  /* restore window to full screen */
  gotoxy(1,24);       /* put cursor at bottom of window */
  rs_close();         /* close the port */

  return 1;

}

⌨️ 快捷键说明

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