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

📄 rs232.doc

📁 RS232.C was written to provide all of the basic functionality needed to employ serial I/O in any a
💻 DOC
📖 第 1 页 / 共 4 页
字号:
              received.  Flow control effects output only.  Characters can
              continue to be received or written to the output buffer up to
              it's capacity when output is disabled via flow control.  Only
              one type of flow control may be used at once.

              If the remote equipment is using XON/XOFF type flow control,
              rs_setflow can be used to control remote output with the
              RS_FLWINS command.  The control character will be sent
              immediately, even if characters are already being transmitted
              via the output buffer.  The buffer will continue to be sent
              after the control character has been transmitted.

      >   rs_close

        >   Purpose:
              Closes" port prepared by rs_initport.

        >   Prototype:
              void rs_close(void);

        >   Return Value:
              none

        >   Notes:
              This function should always be used when an application has
              "opened" a port with rs_initport.  rs_close disables interrupts
              from the port and restores the previous interrupt vector.
              Failure to call rs_close before exiting from the application can
              very likely cause undefined behavior.  The function can be
              registered with the library function atexit() to insure that it
              gets called.  It is probably also a good idea to install a
              ctrl-break handler which calls rs_close to prevent exiting the
              application without closing the port:

                int c_break(void)
                {
                  rs_close();
                  return(0);
                }

                  /* somewhere in application */
                  ctrlbrk(c_break); /* library function ctrlbrk registers
                                       cleanup function */

              If a buffer transmit is currently in progress, rs_close waits
              for it to finish before closing the port unless output is
              currently disabled via flow control.

    >   General Notes:

      >   Baud Rates:
              Although RS232.C supports speeds up to 115.2K baud, the higher
              speeds may not work on some machines due to a variety of
              factors.  Foremost is the speed of the CPU itself - slower
              machines may not be capable of sustained input at high speeds.
              Other factors may effect the maximum usable baud rate also.  For
              instance, even though a machine's CPU is fast enough to support
              high speeds, other software running on the machine may prevent
              it.  (One example is a 386 CPU running an extended memory
              manager which places the CPU in protected mode.  This can cause
              interrupt service routines to be slower.)  The BIOS in some
              machines may have routines which are too slow, such as the timer
              interrupt service routine - this can effect time critical
              routines like the serial interrupt service routine in RS232.C.
              Only experimentation can determine what the highest usable speed
              is on any given machine and configuration.

      >   Interrupts:
              Because machines equipped with COM ports 3 and 4 use hardware
              interrupt lines shared with ports 1 and 2, a problem can arise
              with some hardware.  For example, an internal modem is installed
              as COM1 and you are attempting to use COM3 for some other
              purpose.  Because both ports use interrupt request line IRQ4, if
              the modem board is "holding" IRQ4 inactive, COM3 will never be
              able to signal an interrupt and thus will appear dead.  Most
              serial adapter boards do not behave this way and will "float"
              the interrupt request line when not signaling an interrupt.
              Also, the problem can only occur if software accessing the
              problem board leaves interrupts enabled at the board.
              (Specifically, the signal OUT2 is left active with modem control
              register bit 3.)

              If your application installs any of it's own interrupt routines,
              they must re-enable interrupts as soon as possible after entry
              to prevent loss of incoming serial characters.

              RS232.C re-prioritizes hardware interrupts to give serial
              interrupts the highest priority.  While this will have no
              noticeable effect with most applications, it should be taken
              into account in those applications which make use of hardware
              interrupts from other sources.

      >   Polled vs. interrupt driven output:
              The default method of character transmission by RS232.C uses
              interrupts.  Each time a character is written a character is
              written to the UART's transmit holding register, an interrupt is
              generated by the UART when the transmit holding register becomes
              available for the next character to be sent.  It may be
              desirable under certain circumstances to disable this feature
              and use "polled transmission" instead.  This requires that
              software constantly poll the UART and write the next character
              when the transmit holding register becomes free.  The method
              used is determined at compile time.  If the macro RS_POLLED_XMIT
              is defined, the polling method will be used.  The following line
              placed at the beginning of the application's source code will
              accomplish this:

                 #DEFINE RS_POLLED_XMIT

              The following describes some advantages and disadvantages to
              both methods:

              Interrupt driven output:
                Advantages:  This is the more efficient method of output.  No
                CPU time is wasted polling the UART.  Characters may be queued
                for output and the application may go on processing without
                waiting for the characters to actually be sent.

                Disadvantages:  Some additional overhead is incurred in the
                interrupt service routine.  At high transmission speeds this
                may cause problems on slower machines or under certain
                circumstances.  Interrupt driven output may not work properly
                with some non-standard hardware.

              Polled output:
                Advantages:  This method makes the interrupt service routine
                slightly "leaner" and simplifies some of the code elsewhere
                making the overall code size slightly smaller.  This method
                may prove to be more reliable on some hardware.

                Disadvantages:  While the application is sending characters,
                it can do nothing else and no output buffer is used.  This
                method is less efficient for throughput.

      >   Flow control and handshaking:
              Flow control is provided for only in respect to stopping and
              starting output as requested by remote equipment.  To utilize
              flow control on remote equipment, the application must monitor
              the conditions requiring flow control (i.e. input buffer free
              space) and take the appropriate action when needed (like sending
              XOFF or dropping a hardware line).

              Handshaking is something that is completely arbitrary and the
              only requirement is that the local and remote equipment must
              agree on the protocol.  RS232.C provides a function for
              determining the status of and controlling hardware handshake
              lines but it is up to the application to determine how it should
              be used.

      >   Compiling:
              If RS232.C can be simply included (whether by "pasting" it
              directly into an applications source code or with a preprocessor
              "#include" directive) no special compiler considerations are
              needed.  If desired, RS232.C can be split into separate header
              and code files to follow more conventional 'C' conventions.
              This is accomplished by splitting the file where indicated.
              Programs using RS232.C can be compiled and linked from the IDE
              if desired.

              Borland's newer compilers have many optimization options and, so
              far, none have caused problems with RS232.C.  One necessity is a
              must when using Turbo C 2.0 or earlier compilers: Stack checking
              must be disabled.  With stack checking enabled in the older
              compilers, stack checking code is generated even in interrupt
              functions.

              Any of the memory models can be used with RS232.C - the only
              drawback is the extra function call overhead and/or memory
              access overhead incurred with the large models.  This may
              prevent an application from being able to use the higher baud
              rates on some machines.

      >   Other Compilers:

              RS232.C will compile and run with other DOS based compilers with
              minor changes.  The following lists types/functions/macros which
              may need attention under compilers other than those produced by
              Borland:

                  function type interrupt - must take care of saving and
                  restoring registers and provide IRET instruction

                  unsigned char inportb(int portid) /* reads a byte from
                                                       a hardware port */

                  void outportb(int portid,unsigned char value) /* writes a
                                                        /* byte to a port */

                  void far *MK_FP(unsigned seg, unsigned ofs) /* takes integer
                                                       segment and offset
                                                       arguments and returns
                                                       far pointer */

              The code is C++ compatible via "#ifdef __cplusplus"
              preprocessor directives.  In order to use RS232.C in
              a C++ program, the header file must be separated from
              the main body of the code (name it RS232.H) and RS232.C
              must be compiled separately (as in a project file).


      >   16550 FIFO mode:
              The 8250A/B and 16450 UARTs found in most machines contain only
              a one byte buffer for input and output.  This means that for
              every byte which is received, an interrupt is generated which
              invokes a routine to retrieve the incoming byte and store it.
              This must take place before the next incoming byte has been
              fully received to avoid loss of data.  The same is true of
              outgoing data - after each byte being transmitted has been
              sent, an interrupt is generated to invoke a routine to write the
              next byte to the transmit register.  In some situations, this is
              simply too much overhead or the interrupt service routines can
              not be allowed to react quickly enough to keep up with the data.
              The more sophisticated 16550 series of UARTs overcome this with
              the inclusion of 16 byte FIFOs (first-in-first-out-registers)
              for both input and output.  Software must be able to recognize
              and enable this feature when it's available, and software
              determines how it is used.  Code in RS232.C checks for the
              presence of FIFO capable UARTs and automatically employs them.
              Outgoing data is written to the UART at 16 bytes per interrupt
              and incoming data signals generates a receive interrupt after 4
              bytes have accumulated in the FIFO - though up to 16 bytes can
              be received before the interrupt service routine is able to
              respond, without losing any data.  These defaults can be changed
              by altering the corresponding constants in the function
              rs_initport (see comments in RS232.C).

      >   Using More Than 1 COM Port Simultaneously:
              While RS232.C provides no direct support for simultaneous serial
              port access, it is easy enough to accomplish.  The solution is
              to include 2 copies of RS232.C in your source code.  Because all
              variable and function names in RS232.C begin with 'rs_', this
              makes it easy.  To allow an application to access 2 ports at
              once you can do the following:

                    Create 2 copies of RS232.C renaming them to RS232A.C and
                    RS232B.C.

                    Using Borland's built in editor (or any editor capable of
                    search and replace), edit RS232A.C performing a global
                    search and replace of the string "rs_" with "rs1_".  Do
                    the same for "RS_" replacing it with "RS1_".

                    Do the same thing with RS232B.C, replacing "rs_" with
                    "rs2_" and "RS_" with "RS2_".

                    Include both modified copies in the source code for your
                    application.  This provides 2 complete sets of functions
                    (the function names now start with "rs1_" or "rs2_",
                    depending on which port is being accessed) allowing access
                    to 2 different ports and simultaneous serial port I/O.
                    While not the most elegant of solutions, it is workable
                    and RS232.C is small enough so as not to make inclusion of
                    2 copies a problem. (RS232.C adds about 3400 bytes to an
                    executable file.)

              Only certain ports can be used simultaneously.  Because COM1
              uses the same hardware interrupt as COM3 and COM2 uses the same
              interrupt as COM4, you will most likely not be able to use COM1
              with COM3 or COM2 with COM4.  The problem arises due to the
              design of the hardware - if a UART has its OUT2 hardware line at
              logic 1 (necessary to enable interrupts), another UART sharing
              the same interrupt will not be able to signal an interrupt.
              This is true of any serial communications software which uses
              interrupts.  A serial mouse driver using COM1 preventing serial
              I/O on COM3 is one example of how this problem may arise even
              when using only one port in an application.  One way to get
              around this problem (other than opening and closing the ports as
              needed using rs_close) is to turn off OUT2 on the UART which is
              NOT currently being utilized.  OUT2 is controlled by bit 3 of
              the modem control register and can be controlled using the
              rs_modctrl function of RS232.C.  The following is an example
              which would allow interrupts to occur on a port opened with
              rs1_initport and reenable interrupts on a port opened with
              rs2_initport when finished:

              rs2_modctrl(RS2_WRTMCR,rs2_modctrl(RS2_GETMCR) & '\xF7');
              rs1_modctrl(RS1_WRTMCR,rs1_modctrl(RS1_GETMCR) | '\x08');
                perform I/O with rs1...
                   .     .   .    .
                   .     .   .    .
                   .     .   .    .
              rs1_modctrl(RS1_WRTMCR,rs1_modctrl(RS1_GETMCR) & '\xF7');
              rs2_modctrl(RS2_WRTMCR,rs2_modctrl(RS2_GETMCR) | '\x08');
                 resume I/O with rs2...

              One very real drawback to this method is that no interrupts
              can occur on the on the disabled port and data could be
              lost.  Some serial adaptor allow for the conflict
              caused by shared interrupts by or'ing the interrupt request
              output of the conflicting UARTs.  Only testing can ascertain
              if this is so.  Another workaround (and only if the hardware
              supports it) is to use an alternate IRQ which does not
              conflict with another device.  See the function description
              for rs_initport for instructions on how to use an alternate
              IRQ and/or base address.

⌨️ 快捷键说明

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