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

📄 interfacing the serial - rs-232 port part 3-4.htm

📁 Parallel Port description of the communication port
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0045)http://www.beyondlogic.org/serial/serial1.htm -->
<HTML><HEAD><TITLE>Interfacing The Serial / RS-232 Port</TITLE>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<META 
content="Describes interfacing the Serial (RS-232) Port in relation to both Hardware and Software. Gives Practical Examples using CDP6402 UART and Software Examples in C." 
name=description>
<META 
content="RS232, RS-232, Serial, CPD6402, AY-5-1015, 8250, 16450, 16550, 16650, 16750, UART, MAX-232, COMMS, COM Port, Serial Port, Terminal, Programming in C, Serial Programming, RS-232 Programming" 
name=keywords>
<META content="MSHTML 5.00.3315.2870" name=GENERATOR></HEAD>
<BODY 
background="Interfacing The Serial - RS-232 Port Part 3-4_files/bgyellow.gif" 
leftMargin=0 topMargin=0 FACE="ARIAL" BASEFONT marginwidth="0" marginheight="0">
<STYLE type=text/css>#TITLEBLOCK {
	COLOR: #ffffff; TEXT-DECORATION: none
}
TD {
	FONT-FAMILY: Arial
}
P {
	FONT-FAMILY: Arial
}
FONT {
	FONT-FAMILY: Arial
}
A {
	FONT-FAMILY: Arial
}
LI {
	FONT-FAMILY: Arial
}
B {
	FONT-FAMILY: Arial
}
PRE {
	COLOR: #100080
}
TT {
	COLOR: #100080
}
</STYLE>

<SCRIPT language=javascript 
src="Interfacing The Serial - RS-232 Port Part 3-4_files/beyondmenu.js"></SCRIPT>

<CENTER><BR><BR><FONT color=green size=5>Interfacing the Serial / RS-232 
Port</FONT> <BR><BR></CENTER>
<P><FONT size=+2>
<CENTER>Table of Contents</CENTER></FONT>
<P></P>
<P>
<CENTER><FONT size=+1><B>Part 1 : Hardware (PC's)</B></FONT><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#1">Hardware 
Properties</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#2">Serial Pinouts (D25 and D9 
connectors)<BR><A href="http://www.beyondlogic.org/serial/serial.htm#3">Pin 
Functions </A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#4">Null 
Modems </A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#5">Loopback 
Plugs</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#6">DTE/DCE 
Speeds</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#7">Flow 
Control </A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#8">The 
UART (8250's and Compatibles) </A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#9">Type of UARTS (For PC's) 
</A><BR><FONT size=+1><B>Part 2 : Serial Ports' Registers 
(PC's)</B></FONT><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#12">Port Addresses and 
IRQ's</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#13">Table of 
Registers</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#14">DLAB 
? </A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#15">Interrupt 
Enable Register (IER)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#16">Interrupt Identification 
Register (IIR)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#17">First In / First Out 
Control Register (FCR)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#18">Line Control Register 
(LCR)</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#19">Modem 
Control Register (MCR)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#20">Line Status Register 
(LSR)</A><BR><A href="http://www.beyondlogic.org/serial/serial.htm#21">Modem 
Status Register (MSR)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial.htm#22">Scratch 
Register</A><BR><FONT size=+1><B>Part 3 : Programming (PC's)</B></FONT><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#30">Polling or Interrupt 
Driven?</A><BR><A href="http://www.beyondlogic.org/serial/termpoll.c">Source 
Code - Termpoll.c (Polling Version)</A><BR><A 
href="http://www.beyondlogic.org/serial/buff1024.c">Source Code - Buff1024.c 
(ISR Version) </A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#31">Interrupt 
Vectors</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#32">Interrupt Service 
Routine</A><BR><A href="http://www.beyondlogic.org/serial/serial1.htm#33">UART 
Configuration</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#34">Main Routine 
(Loop)</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#35">Determining the type of 
UART via Software</A><BR><FONT size=+1><B>Part 4 : External Hardware - 
Interfacing Methods</B></FONT><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#40">RS-232 
Waveforms</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#41">RS-232 Level 
Converters</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#42">Making use of the Serial 
Format</A><BR><A href="http://www.beyondlogic.org/serial/serial1.htm#43">8250 
and compatible UART's</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#44">CDP6402, AY-5-1015 / 
D36402R-9 etc UARTs</A><BR><A 
href="http://www.beyondlogic.org/serial/serial1.htm#46">Microcontrollers</A><BR>
<P></P></CENTER>
<CENTER>
<TABLE width="95%">
  <TBODY>
  <TR>
    <TD>
      <P><A name=Part3></A>
      <HR>
      </A><I><FONT size=+2>Part 3 : Programming (PC's)</FONT></I>
      <HR>

      <P></P>
      <UL><A name=30><FONT size=+1>Polling or Interrupt Driven?</FONT><BR>
        <HR>
        </A>
        <P>When writing a communications program you have two methods available 
        to you. You can poll the UART, to see if any new data is available or 
        you can set up an interrupt handler to remove the data from the UART 
        when it generates a interrupt. Polling the UART is a lot slower method, 
        which is very CPU intensive thus can only have a maximum speed of around 
        34.8 KBPS before you start losing data. Some newer Pentium Pro's may be 
        able to achieve better rates that this. The other option is using a 
        Interrupt handler, and that's what we have used here. It will very 
        easily support 115.2K BPS, even on low end computers. </P>
        <P>
        <CENTER><A 
        href="http://www.beyondlogic.org/serial/termpoll.c">Termpoll.c - Simple 
        Terminal Program using the Polling Method.</A> </CENTER>
        <P></P>
        <P>Polling the UART should not be dismissed totally. It's a good method 
        for diagnostics. If you have no idea of what address your card is at or 
        what IRQ you are using you can poll the UART at several different 
        addresses to firstly find which port your card is at and which one your 
        modem is attached to. Once you know this information, then you can set 
        up the Interrupt routines for the common IRQs and by enabling one IRQ at 
        a time using the Programmable Interrupt Controller you can find out your 
        IRQ, You don't even need a screw driver! </P>
        <P>
        <CENTER><A 
        href="http://www.beyondlogic.org/serial/buff1024.c">Buff1024.c - Simple 
        Terminal Program using Interrupt Requests.</A> </CENTER>
        <P></P>
        <P>
        <CENTER>
        <TABLE width="90%">
          <TBODY>
          <TR>
            <TD vAlign=top>Note:</TD>
            <TD><I>The source code above is not a really good example on how 
              to program but is rather cut down to size giving quick results, 
              and making it easier to understand. Upon executing your 
              communications program, it would be wise to store the status of 
              the UART registers, so that they all can be restored before you 
              quit the program. This is to cause the least upset to other 
              programs which may also be trying to use the communications ports. 
              </I></TD></TR></TBODY></TABLE></CENTER>
        <P>The first step to using interrupts is to work out which interrupt 
        services your serial card. Table 13 shows the base addresses and IRQ's 
        of some standard ports. IRQ's 3 and 4 are the two most commonly used. 
        IRQ 5 and 7 are sometimes used. </P><A name=31><FONT size=+1>Interrupt 
        Vectors</FONT><BR>
        <HR>
        </A>
        <P>Once we know the IRQ the next step is to find it's interrupt vector 
        or software interrupt as some people may call it. Basically any 8086 
        processor has a set of 256 interrupt vectors numbered 0 to 255. Each of 
        these vectors contains a 4 byte code which is an address of the 
        Interrupt Service Routine (ISR). Fortunately C being a high level 
        language, takes care of the addresses for us. All we have to know is the 
        actual interrupt vector. </P>
        <CENTER>
        <TABLE border=1 width="80%">
          <TBODY>
          <TR>
            <TD>
              <CENTER><B>INT (Hex)</B></CENTER></TD>
            <TD><B>
              <CENTER>IRQ</CENTER></B></TD>
            <TD><B>Common Uses</B></TD></TR>
          <TR>
            <TD>
              <CENTER>08</CENTER></TD>
            <TD>
              <CENTER>0</CENTER></TD>
            <TD>System Timer</TD></TR>
          <TR>
            <TD>
              <CENTER>09</CENTER></TD>
            <TD>
              <CENTER>1</CENTER></TD>
            <TD>Keyboard</TD></TR>
          <TR>
            <TD>
              <CENTER>0A</CENTER></TD>
            <TD>
              <CENTER>2</CENTER></TD>
            <TD>Redirected</TD></TR>
          <TR>
            <TD>
              <CENTER>0B</CENTER></TD>
            <TD>
              <CENTER>3</CENTER></TD>
            <TD>Serial Comms. COM2/COM4</TD></TR>
          <TR>
            <TD>
              <CENTER>0C</CENTER></TD>
            <TD>
              <CENTER>4</CENTER></TD>
            <TD>Serial Comms. COM1/COM3 </TD></TR>
          <TR>
            <TD>
              <CENTER>0D</CENTER></TD>
            <TD>
              <CENTER>5</CENTER></TD>
            <TD>Reserved/Sound Card </TD></TR>
          <TR>
            <TD>
              <CENTER>0E</CENTER></TD>
            <TD>
              <CENTER>6</CENTER></TD>
            <TD>Floppy Disk Controller </TD></TR>
          <TR>
            <TD>
              <CENTER>0F</CENTER></TD>
            <TD>
              <CENTER>7</CENTER></TD>
            <TD>Parallel Comms. </TD></TR>
          <TR>
            <TD>
              <CENTER>70</CENTER></TD>
            <TD>
              <CENTER>8</CENTER></TD>
            <TD>Real Time Clock</TD></TR>
          <TR>
            <TD>
              <CENTER>71</CENTER></TD>
            <TD>
              <CENTER>9</CENTER></TD>
            <TD>Reserved</TD></TR>
          <TR>
            <TD>
              <CENTER>72</CENTER></TD>
            <TD>
              <CENTER>10</CENTER></TD>
            <TD>Reserved</TD></TR>
          <TR>
            <TD>
              <CENTER>73</CENTER></TD>
            <TD>
              <CENTER>11</CENTER></TD>
            <TD>Reserved</TD></TR>
          <TR>
            <TD>
              <CENTER>74</CENTER></TD>
            <TD>
              <CENTER>12</CENTER></TD>
            <TD>PS/2 Mouse</TD></TR>
          <TR>
            <TD>
              <CENTER>75</CENTER></TD>
            <TD>
              <CENTER>13</CENTER></TD>
            <TD>Maths Co-Processor</TD></TR>
          <TR>
            <TD>
              <CENTER>76</CENTER></TD>
            <TD>
              <CENTER>14</CENTER></TD>
            <TD>Hard Disk Drive</TD></TR>
          <TR>
            <TD>
              <CENTER>77</CENTER></TD>
            <TD>
              <CENTER>15</CENTER></TD>
            <TD>Reserved </TD></TR></TBODY></TABLE><FONT size=-1>Table 14 : 
        Interrupt Vectors (Hardware Only) </FONT></CENTER>
        <P>The above table shows only the interrupts which are associated with 
        IRQ's. The other 240 are of no interest to us when programming RS-232 
        type communications. </P>
        <P>For example if we were using COM3 which has a IRQ of 4, then the 
        interrupt vector would be 0C in hex. Using C we would set up the vector 
        using the instruction <FONT color=#400080><TT>setvect(0x0C, 
        PORT1INT);</TT></FONT> where PORT1INT would lead us to a set of 
        instructions which would service the interrupt. </P>
        <P>However before we proceed with that I should say that it is wise to 
        record the old vectors address and then restore that address once the 
        program is finished. This is done using <FONT 
        color=#400080><TT>oldport1isr = getvect(INTVECT);</TT></FONT> where 
        oldport1isr is defined using <FONT color=#400080><TT>void interrupt 
        (*oldport1isr)(); </TT></FONT></P>
        <P>Not only should you store the old vector addresses, but also the 
        configuration the UART was in. Why you Ask? Well it's simple, I wrote a 
        communications program which was fully featured in the chat side of 
        things. It had line buffering, so no body could see my spelling mistakes 
        or how slowly I typed. It included anti-bombing routines and the list 
        goes on. However I couldn't be bothered to program any file transfer 
        protocols such as Zmodem etc into my communications program. Therefore I 
        either had to run my communications program in the background of 
        Telemate using my communications program for chat and everything else it 
        was designed for and using Telemate to download files. Another method 
        was to run, say Smodem as a external protocol to my communications 
        program. </P>
        <P>Doing this however would mean that my communications program would 
        override the original speed, parity etc and then when I returned to the 
        original communications program, everything stopped. Therefore by saving 
        the old configuration, you can revert back to it before you hand the 
        UART back over to the other program. Makes sense? However if you don't 
        have any of these programs you can save yourself a few lines of code. 
        This is what we have done here. </P><A name=32><FONT size=+1>Interrupt 
        Service Routine (ISR)</FONT><BR>
        <HR>
        </A>
        <P>Now, could we be off track just a little? Yes that's right, PORT1INT 
        is the label to our interrupt handler called a Interrupt Service Routine 
        (ISR). You can put just about anything in here you want. However calling 
        some DOS routines can be a problem. </P><FONT color=#400080><PRE>void interrupt PORT1INT()
{
 int c;
 do { c = inportb(PORT1 + 5);
      if (c &amp; 1) {
                  buffer[bufferin] = inportb(PORT1);
                  bufferin++;
                  if (bufferin == 1024) bufferin = 0;
                 } 
    } while (c &amp; 1);

⌨️ 快捷键说明

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