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

📄 serial.c

📁 国外网站上的一些精典的C程序
💻 C
字号:
/*+----------------------------------------------------+|               Thunderbird Software                 |+----------------------------------------------------+| Filespec  :  Serial.c                              || Date      :  October 24, 1991                      || Time      :  15:03                                 || Revision  :  1.1                                   ||     Update: August 29, 1994                        |+----------------------------------------------------+| Programmer:  Scott Andrews                         || Address   :  5358 Summit RD SW                     || City/State:  Pataskala, Ohio                       || Zip       :  43062                                 |+----------------------------------------------------+| Released to the Public Domain                      |+----------------------------------------------------+*//*+----------------------------------------------------------+|  Call open_serial to install the interrupt handler       ||  You must call close_serial before exiting your program  ||  or a machine crash will occur!                          |+----------------------------------------------------------+*/#include <stdlib.h>#include <dos.h>#include <string.h>#include "serial.h"#include "queue.h"QUEUE *Serial_In_Queue;QUEUE *Serial_Out_Queue;OLD_COMM_PARAMS old_comm_params;COMM_STATUS     comm_status;void (INTERRUPT FAR *oldvector_serial )(); /* save addr for intr handler */int  ComBase;                        /* Comm port address */int  IrqNum;                         /* Comm interrupt request */int OpenComPort ( char Port )        /* install int. handler */{      unsigned status;      int retval = -1;          /* allocate input and output queues */      Serial_In_Queue = alloc_queue( SerInBufSize );      if ( (QUEUE *) 0 == Serial_In_Queue)            return retval;      Serial_Out_Queue = alloc_queue( SerOutBufSize );      if ( (QUEUE *) 0 == Serial_Out_Queue)      {            free ( Serial_In_Queue );            return retval;      }      retval = 0;      /* Setup Comm base port address and IRQ number */      switch ( Port)      {            case '1': ComBase = 0x3F8; IrqNum = 4; break;            case '2': ComBase = 0x2F8; IrqNum = 3; break;            case '3': ComBase = 0x3E8; IrqNum = 4; break;            case '4': ComBase = 0x2E8; IrqNum = 3; break;            default : ComBase = 0x3F8; IrqNum = 4; break;      }      old_comm_params.int_enable = inp ( ComBase + INT_EN );      outp ( ComBase + INT_EN, 0 ); /* turn off comm interrupts */      /* save old comm parameters */      old_comm_params.line = inp ( ComBase + LINE_CNTRL );      old_comm_params.modem = inp ( ComBase + MODEM_CNTRL );      status = inp ( ComBase + LINE_CNTRL );      outp ( ComBase + LINE_CNTRL, (unsigned char) status | 0x80 );      old_comm_params.baud_lsb = inp ( ComBase + BAUD_LSB );      old_comm_params.baud_msb = inp ( ComBase + BAUD_MSB );      status = inp ( ComBase + LINE_CNTRL );      outp ( ComBase + LINE_CNTRL, (unsigned char) status | 0x7F );      status = OUT2 | DTR;              /* DTR/OUT2 must be set! */      outp ( ComBase + MODEM_CNTRL, (unsigned char) status );      /* get serial port address/vector */      oldvector_serial = (void(INTERRUPT FAR *)(void))getvect(IrqNum + 8 );      /* set our interrupt handler */      setvect ( IrqNum + 8, serial );      /* save the PIC */      old_comm_params.int_cntrl = inp ( 0x21 );      status = ( 1 << IrqNum);      /* calculate int enable bit */      status = ~status;      /* ok enable comm ints */      outp ( 0x21, (unsigned char) old_comm_params.int_cntrl &             (unsigned char) status );      return retval;}void CloseComPort ( void ){      int status;      /* restore UART to previous state */      outp ( ComBase + INT_EN, (unsigned char) 0 );      outp ( ComBase + MODEM_CNTRL,             (unsigned char) old_comm_params.modem );      status = inp ( ComBase + LINE_CNTRL );      outp ( ComBase + LINE_CNTRL,             (unsigned char) status | 0x80 );      outp ( ComBase + BAUD_LSB,             (unsigned char) old_comm_params.baud_lsb );      outp ( ComBase + BAUD_MSB,             (unsigned char) old_comm_params.baud_msb );      outp ( ComBase + LINE_CNTRL,             (unsigned char) old_comm_params.line );      outp ( 0x21, (unsigned char) old_comm_params.int_cntrl );      /* restore old interrupt handler */      setvect ( IrqNum + 8, oldvector_serial );      /* free input and output queues */      free ( Serial_In_Queue );      free ( Serial_Out_Queue );      return;}void InitComPort ( char Baud[], char Databits,                    char Parity, char Stopbits ){      int status;      long baudrate;      unsigned divisor;      /* set baud rate */      status = inp ( ComBase + LINE_CNTRL );      outp ( ComBase + LINE_CNTRL,             (unsigned char) status | 0x80 );      baudrate = atol ( Baud );      if ( baudrate == 0)            baudrate = 2400L;      divisor = (unsigned) ( 115200L / baudrate);      outp ( ComBase + BAUD_LSB,             (unsigned char) ( divisor & 0x00FF) );      outp ( ComBase + BAUD_MSB,             (unsigned char) ( ( divisor >> 8) & 0x00FF) );      status = 0x00;      /* set parity */      switch ( Parity)                    /* set parity value     */      {      case 'O':                           /* odd parity           */      case 'o':            status = 0x08; break;      case 'E':                           /* even parity          */      case 'e':            status = 0x18; break;      case 'S':                           /* stick parity         */      case 's':            status = 0x28; break;      case 'N':                           /* no parity            */      case 'n':            default :   status = 0x00;      }    /* set number data bits */      switch ( Databits)      {      case '5':            break;      case '6':            status = status | 0x01;            break;      case '7':            status = status | 0x02;            break;      case '8':      default :            status = status | 0x03;      }      /* set number stop bits */      switch ( Stopbits)      {      case '2':            status = status | 0x04;            break;      case '1':      default :            ;      }      outp ( ComBase + LINE_CNTRL, (unsigned char) status );      status = OUT2 | DTR;        /* DTR/OUT2 must be set! */      outp ( ComBase + MODEM_CNTRL, (unsigned char) status );      /* enable serial interrupts */      outp ( ComBase + INT_EN, RX_INT | ERR_INT | RS_INT );      return;}void DropDtr ( void ){      int status;      status = inp ( ComBase + MODEM_CNTRL );      status &= 0xFE;                 /* turn off DTR bit */      outp ( ComBase + MODEM_CNTRL, (unsigned char) status );      return;}void RaiseDtr ( void ){      int status;      status = inp ( ComBase + MODEM_CNTRL );      status |= 0x01;                  /* turn on DTR bit */      outp ( ComBase + MODEM_CNTRL, (unsigned char) status );      return;}int ComRecChar ( void ){      return de_queue ( Serial_In_Queue );}int ComSendString ( char *string ){      int retval;      char *pointer;      pointer = string;      while ( *pointer)      {            retval = en_queue ( Serial_Out_Queue, *pointer );            pointer++;      }      if ( 0x0 == (comm_status.modem & 0x40))            RaiseDtr ();      outp ( ComBase + INT_EN, RX_INT | TBE_INT | ERR_INT | RS_INT );      return retval;}int ComSendChar ( char character ){      int retval;      /* interrupt driven send */      if ( 0x0 == (comm_status.modem & 0x40))            RaiseDtr ();      retval = en_queue ( Serial_Out_Queue, character );      if ( - 1 != retval)            outp ( ComBase + INT_EN, RX_INT | TBE_INT | ERR_INT | RS_INT );      return retval;}int ComStatus ( void ){      unsigned status;      unsigned retval;      retval = inp ( ComBase + LINE_STATUS );      retval = retval << 8;      status = inp ( ComBase + MODEM_STATUS );      retval = retval | status;      if ( queue_empty ( Serial_In_Queue ))            retval &= 0xFEFF;      else  retval |= 0x0100;      return (int) retval;}void INTERRUPT FAR serial ( void )            /* interrupt handler */{      int temp;      disable ();      while ( 1)      {            comm_status.intrupt = inp ( ComBase + INT_ID );            comm_status.intrupt &= 0x0f;            switch ( comm_status.intrupt)            {            case 0x00:                 /* modem interrupt */                  comm_status.modem = inp( ComBase + MODEM_STATUS );                  break;            case 0x02:                 /* xmit interrupt */                  if ( queue_empty ( Serial_Out_Queue ))                        outp(ComBase + INT_EN, RX_INT|ERR_INT|RS_INT );                  else                  {                        temp = de_queue ( Serial_Out_Queue );                        if ( - 1 != temp)                              outp ( ComBase + XMIT, temp );                  }                  break;            case 0x04:                 /* receive interrupt */                  en_queue(Serial_In_Queue, (char)inp(ComBase + REC));                  break;            case 0x06:                 /* line interrupt */                  comm_status.line = inp ( ComBase + LINE_STATUS );                  (void) inp ( ComBase + REC );                  en_queue ( Serial_In_Queue, '!' );                  break;            default:                   /* No Mo` Left */                  comm_status.modem = inp ( ComBase + MODEM_STATUS );                  outp ( 0x20, 0x20 );                  enable ();                  return;            }   /* switch */      }   /* while */}/* End of Serial.C */

⌨️ 快捷键说明

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