DOS serial Programming Chapter 1 Serial Communication Interfaces Serial Communication uses a single data line instead of an 8-bit data line for parallel communication, and the transmission distance is far away. The Communication Interface obtains 8-bit data from the CPU each time, and then converts the data into a serial bit through a shift register that is imported in parallel. Each time one bit is sent, the data is sent out. Similarly, the receiver must also have a serial inbound parallel shift register to receive serial data. And combine them into one byte. The data that enters the data line in a serial mode is composed of 0 and 1. A group of such numbers is called a character. A character may contain 8 or 7 or 6 characters, five digits. During transmission, the start and end bits must be added to each character. The start bits are always one bits and the end bits can be one or two bits. To ensure the correctness of the transmitted data, it sometimes includes a verification bit. Generally, the verification method can be set to odd or invalid for all chips during programming. The data transmission rate of serial communication is represented by BPS (bits per second. In addition, a unit indicating the signal transmission rate is the band rate ). The baud rate is a unit of signal modulation, which is not necessarily the same as BPS. It defines the number of discrete signals transmitted per second. A discrete signal is an uneven, non-continuous, and irrelevant signal. For more information, see related documents. The transmission rate of the communication port ranges from 110bps to 115200bps. Experience shows that the transmission is quite stable when the baud rate is equivalent to 9600bps. Electronics Industrial Association (EIA) established RS-232 interface standards in 1960, and later released a revised version, which is currently widely used in PC serial interface for short-range data communication, connect to some external devices. Is the 9-pin RS-232 plug we often use, Each pin is defined: Pin Direction Name Description Description 1 Input CD Carrier detect Data Carrier Detection 2 Input Rxd Receive data Data receiving end 3 Output Txd Transmit data Data sender 4 Output DTr Data Terminal ready Data Terminal ready (Computer) 5 - SG System ground Signal Location 6 Input DSR Data Set ready Data device ready 7 Output RTS Request to send Request sending (the computer requires sending data) 8 Input CTS Clear to send Clear sending (modem prepares to receive data) 9 Input Ri Ring indicator Ring tone indication The above signals may be used in whole or in part during the communication process. Connect the two computers through the serial port. The simplest communication can be completed only by txd, rxd, and SG. Chapter 2 port settings Ibm pc and 80x86 compatible hosts can connect to four serial ports, namely, COM1 ~ Com4, the number in the corresponding BIOS is com0 ~ But the program can only access one of the ports at a time. When the computer starts, the self-check program will test whether four COM ports exist and write the I/O addresses of each COM port to the BIOS data zone 0040: 0000 ~ 0040: 0007 a total of 8 bytes, each com address occupies 2 bytes. If the system does not connect to the serial port, the content of these units in the BIOS data area becomes 0. Use DEBUG to view the COM port address. C> debug -D 0040: 0000 l08 0040: 0000 F8 03 F8 02 E8 03 E8 02 The preceding example shows that the system has four COM ports and the corresponding I/O addresses are 3f8, 2f8, 3e8, and 2e8 respectively. Each COM port contains a set of 8-bit registers. These four addresses are called base addresses, that is, the I/O addresses of the first register. The addresses of other registers are listed in ascending order. The base address of COM1 is 3f8, the base address of com2 is 2f8, the base address of com3 is 3e8, and the base address of com4 is 2e8. We use these registers to program and control data receiving or sending. COM1 and com3 use PC interrupt 4, com2 and com4 use interrupt 3. Chapter 3 registers 1 register group The register group of COM port is shown in the following table. There are 12 registers and 8 addresses are used. Some registers share one address, which is distinguished by dlab = 0/1. Dlab is the 7th-bit line control register. Base Address Read/write Register abbreviation Description 0 Write - Sending holding register (dlab = 0) 0 Read - Receive data register (dlab = 0) 0 Read/write - 8-bit lower baud rate (dlab = 1) 1 Read/write Ier Interrupt permitted register 1 Read/write - 8-bit high baud rate (dlab = 1) 2 Read IIR Interrupt mark register 2 Write FCR FIFO control register 3 Read/write LCR Line Control Register 4 Read/write MCR Modem Control Register 5 Read LSR Line Status Register 6 Read MSR Modem Status Register 7 Read/write - Scratch register 2 interrupt permitted register (IER) Bit Description 7 Unused 6 Unused 5 Enter low power consumption mode (16750) 4 Enter sleep mode (16750) 3 Allow modem status interruption 2 The status of the receiving line is interrupted. 1 Allow air disconnection of the sender's Referer 0 Allow receiving data ready for interruption When bit0 is set to 1, data may be interrupted when it receives data. When bit1 is set to 1, transmission is allowed to interrupt when the register is null. When bit2 is set to 1, an interruption occurs when the LSR is changed, the corresponding bit3 bit will be interrupted when MSR changes. 3. Interrupt recognition register (IIR) Bit Description Bit6: 7 = 00 No FIFO Bit6: 7 = 01 FIFO allowed, but not available Bit6: 7 = 11 Allow FIFO Bit5 Allow 64-byte FIFO (16750) Bit4 Unused Bit3 16550 timeout interruption Bit2: 1 = 00 Modem status interruption (CTS/RI/DTR/DCD) Bit2: 1 = 01 Send and keep register air disconnected Bit2: 1 = 10 Received data ready for interruption Bit2: 1 = 11 Receiving line status interrupted Bit0 = 0 Interrupted Bit0 = 1 No interruptions The read-only register. bit6: 7 is used to indicate the FIFO status. If the values are 0, there is no FIFO. At this time, the 8250 or 16450 chip is used. If the values are 01, there is a FIFO but not usable, if it is set to 11, the FIFO is valid and can work properly. Bit3 indicates timeout interruption (16550/16750 ). Bit0 is used to indicate whether an interruption occurs. bit1: 2 identifies the specific interruption type. These interruptions have different priority levels, among which the LSR interrupt level is the highest, followed by data ready interruption, then, the sending register is disconnected in the air, while the MSR interrupt level is the lowest. 4. FIFO control register (FCR) Bit Description Bit7: 6 = 00 1 byte interrupt Bit7: 6 = 01 4 byte interrupt Bit7: 6 = 10 8 byte interrupt Bit7: 6 = 11 14byte interrupt Bit5 Allow 64-byte FIFO Bit4 Unused Bit3 DMA mode selection Bit2 Clear sending FIFO Bit1 Clear receiving FIFO Bit0 Allow FIFO FCR can be written but cannot be read. This register is used to control 16550 or 16750 FIFO registers. Bit0 sets 1 to allow sending/receiving FIFO, and bit1 and bit2 sets 1 to clear receiving and sending FIFO respectively. Clearing the receiving and sending FIFO does not affect the shift register. Bit1: 2 can be reset by yourself, so you do not need to use software to clear it. Bit6: 7 is used to set the interrupt level. Sending/receiving interruptions are generated when the number of corresponding bytes is sent/received. 5. Line Control Register (LCR) Bit Description Bit7 = 1 Allowed to access the baud rate factor register Bit7 = 0 Permitted access to the receiving/sending and interrupt permitted registers Bit6 Set intermittent, 0-disabled, 1-Set Bit5: 3 = xx0 No verification Bit5: 3 = 001 Odd check Bit5: 3 = 011 Even Verification Bit5: 3 = 101 Parity is 1 Bit5: 3 = 111 The parity is 0. Bit2 = 0 1-bit stop bit Bit2 = 1 2-bit Stop bits (6-8 bits), 1.5 bits (5 bits) Bit1: 0 = 00 5-Bit Data Bit1: 0 = 01 6-Bit Data Bit1: 0 = 10 7-Bit Data bit Bit1: 0 = 11 8-Bit Data bit LCR is used to set some basic parameters required for communication. Bit7 is valid for the specified baud rate factor register of 1. If it is 0, the specified sender/receiver and ier are valid. If bit6 is set to 1, the sender is set to 0, which causes the receiver to generate a "break ". Bit3-5 is used to set whether to use parity and parity type, bit3 = 1 use parity, bit4 is 0 is odd parity, 1 is even parity, bit5 is forced to verify as 1 or 0, and is determined by bit4 as 0 or 1. Bit2 is used to set the length of the stop bit. 0 indicates one stop bit. If it is 1, 1.5-2 Stop bits are used based on different data lengths. Bit0: 1 is used to set the Data Length. 6 modem control register (MCR) Bit Description Bit7 Unused Bit6 Unused Bit5 Automatic traffic control (16750 only) Bit4 Loop Test Bit3 Secondary output 2 Bit2 Auxiliary output 1 Bit1 Set up RTS Bit0 Set DSR MCR registers are readable and writable, and bit4 = 1 enters the loop test mode. The Bit3-0 is used to control the corresponding pins. 7 line Status Register (LSR) Bit Description Bit7 An error occurred while receiving data in FIFO Bit6 The sending shift register is empty. Bit5 The send keep register is empty. Bit4 Intermittent Bit3 Incorrect frame format Bit2 Parity error Bit1 Beyond Error Bit0 Receiving data ready The LSR is a read-only register. When an error occurs, bit7 is 1, bit6 is 1, indicating that the send keep and send shift register are empty. When bit5 is 1, it indicates that only the send keep register is empty, the next data can be sent by the software. When the line status is 0, bit4 is set to 1, and the frame format is incorrect, bit3 is set to 1, and bit2 and bit1 are set to 1 respectively. If bit0 is set to 1, the received data is ready. In the process of receiving and sending, once the error status bit (1, 2, 3, 4) is set to 1, the received data read is no longer valid data, so in the serial application, check data transmission errors. Parity error: the noise on the communication line (especially when the telephone line is used for transmission) changes some data bit, resulting in parity error. When the parity error is detected, it is required that at least one segment of accepted data should be resending. Exceeding error: if the previous character has not been removed by the CPU and another character is transferred to the data register, the exceeding error will occur. Frame format error: When the receiver/transmitter does not receive the end position of a character data, the frame format is incorrect. This error may be caused by noise on the communication line, or because the receiver and sender do not match the initialization. Intermittent: when there is intermittent, it cannot be regarded as an error. Instead, it sets a "space" status for some special communication environments. When the interval is 1, this indicates that the received "space" status exceeds a complete data word transmission time. 8 modem Status Register (MSR) Bit Description Bit7 Carrier Detection Bit6 Ring tone indication Bit5 DSR ready Bit4 Valid cts Bit3 DCD changed Bit2 RI changed Bit1 DSR changed Bit0 CTS changed The high 4 bits in the MSR register correspond to the status line of the modem. The low 4 bits indicate whether the status line of the modem has changed. At this point, the serial port register has been introduced, and the following describes how to program. Chapter 4 BIOS Serial Communication The BIOS int 14h provides the serial data communication function, including initializing the serial port to a specified byte structure and transmission rate, checking the status of the controller, and reading/writing characters. Serial communication port BIOS function (INT 14 h) Ah Function Call Parameters Response parameters 0 Initialize the serial port Al = initialization parameters DX = communication slogan COM1 = 0, com2 = 1 Com3 = 2, com4 = 3 Ah = line status Al = model Status 1 Write characters to the serial communication port Al = character to be written DX = communication slogan Succeeded in writing: Ah = 0, Al = character. Failed to write characters: In Ah, bit7 = 1, bit6: 0 = line status. 2 Read characters from the serial communication port DX = communication slogan Read successful: In Ah, bit7 = 0; Al = character Read failed: In Ah, bit7 = 1, bit6: 0 = line status 3 Line status DX = communication slogan Ah = line status Al = model Status 1. initialize the serial port The Ah = 0 Function of int 14h initializes the specified serial communication port to the desired baud rate, parity, length, and number of digits of the termination bit. These initialization parameters are set in the Al register, the meanings of these parameters are as follows: Al Meaning Value Bit7: 5 Baud Rate 000 = 110 Port 001 = 150 Port 010 = 300 Port 011 = 600 Potter 100 = 1200 Port 101 = 2400 Port 110 = 4800 Port 111 = 9600 Port Bit4: 3 Verification 1 = 2 Bit2 End bit 0 = 1 Bit1: 0 Font Length 10 = 7 digits 11 = 8 bits For example, the data transmission rate of the COM1 port is 2400 port, the word length is 8 bits, the one-bit termination bits, and there is no parity Verification: _ ASM { MoV ah, 0 MoV Al, 0a03h /// 0a03h = 10100011 MoV dx, 0 // COM1 Int 14 h // call BIOS } 2 send data Char my_data = 65 h; // assume 65 h is sent _ ASM { MoV Al, my_data MoV ah, 1 MoV dx, 1 // sent out through com2 Port Int 14 h } 3. Accept data To receive characters, use int 14 h, Ah = 3 to obtain the status of the COM port. The returned value is in the ah register. Check the 0th bits of AH, which are the data preparation bits. If the bits are 1, the COM port has received the characters. Then you can use the int 14 h, Ah = 2 function to read the characters to the Al register. Char LSR = 0; // line status Char my_data; // the received data _ ASM { MoV ah, 3 MoV dx, 0 // line status of COM1 Int 14 h MoV LSR, ah } If (! (LSR & 01 H) // No data arrives { Printf ("no data arrived "); Goto somewhere; } Else // receives data when data arrives { _ ASM { MoV ah, 2 // read characters MoV dx, 0 Int 14 h MoV my_data, Al // The received characters are stored in my_data } } Chapter 5 I/O register Programming Direct read/write of I/O registers allows you to operate serial communication more flexibly and reliably. Many programs are written in this way. # Define baseaddr1 0x3f8 // The base address of the COM1 register 1. initialize the serial port Void initcom1 () { // Interruption not allowed Outportb (baseaddr1 + 1, 0 ); // Set dlab = 1 to allow access to the baud rate register Outportb (baseaddr1 + 3, 0x80 ); // Set the baud rate of 9600. The parameters can be found in the following table. Outportb (baseaddr1 + 0, 0x0c); // 8-bit lower baud rate Outportb (baseaddr1 + 1, 0x00); // 8-bit high baud rate // Set 8-Bit Data bit, 1-bit stop bit, no verification, dlab = "0" Outportb (baseaddr1 + 3, 0x03 ); } When dlab = 1, set the baud rate required for communication. Common baud rate parameters are shown in the following table: Speed (BPS) 8-bit high baud rate 8-bit lower baud rate 50 09 h 00 h 300 01 H 80 h 600 00 h C0h 1200 00 h 60 h 2400 00 h 30 h 4800 00 h 18 h 9600 00 h 0ch 19200 00 h 06 h 38400 00 h 03 h 57600 00 h 02 h 115200 00 h 01 H 2 send data More languages are not as clear as code, so I still put the code below and make some comments as appropriate. The following function sends a character through the COM1 port. my_data is the character to be sent. If COM1 cannot be sent, a failure is returned. Bool send_com1 (char my_data) { Char status = inportb (baseaddr1 + 5); // check the line status Int COUNT = 10000; // Wait until the sending register is empty or times out. While (! (Status & 0x20) & (count> 0 )) { Count --; Status = inportb (baseaddr1 + 5 ); } If (count> 0) // The sending register is empty. { Outportb (baseaddr1 + 0, my_data); // sending character Return true; } Else Return false; // timeout not sent } 3. receive data The following function reads a character from the COM1 port and saves it to the variable pointed to by pdata. If the COM1 port does not have data, a failure is returned. Bool recv_com1 (char * pdata ); { Char status = inportb (baseaddr1 + 5); // check the line status If (Status & 0x01) // the received data is ready. { * Pdata = inportb (baseaddr1 + 0); // read a character Return true; } Else Return false; // No data arrives } 4. Enable the FIFO Function The so-called FIFO in the serial port, that is, the first-in-first-out queue function, refers to a group of receiving buffer registers and a group of sending and keeping registers. The size of the receiving buffer register and the sending retention register is 16 bytes. When the FIFO function is disabled, the receiving buffer register and the sending retention register can only put one data, which is equivalent to one byte. We 'd better start with receiving and sending data. Data Receiving: the data from the line first enters the receiving shift register (RSR). After a character is received, the data is transferred to the receiving buffer register (RBR ), RBR is actually a 16-byte FIFO queue. When the interrupt is set, the serial controller interrupts the settings based on the FIFO settings and the number of data in the RBR. When the FIFO function is disabled, RBR can only put one data. If the host device cannot read characters from RBR, the next data received by the serial port will overwrite the RBR, and data will be lost. When the FIFO function is enabled, 16 data records can be placed in RBR. When the serial port pushes the completed characters to RBR, the original number of RBR will be moved forward, in this way, the time for the host to read characters becomes longer. Data transmission: the sending and receiving operations are the opposite. The host data is written to the sending and maintaining register (THR), and The thr is also a 16-byte FIFO, and then the data is moved to the sending and shifting register (TSR ), and then sent to the line. When the interrupt is set, the serial port controller will also interrupt according to the number of data in the thr. When the FIFO function is enabled, the host can write 16 bytes of data into the sending and holding registers at one time. Then we can use the FIFO function to improve the previous program. Send data: // Pdata points to the data to be sent. Len indicates the Data Length and returns whether the data is successfully sent. Bool defaults o_send (char * pdata, int Len) { Int count; // Disable FIFO so that the program can immediately detect whether the characters are successfully sent. Outportb (baseaddr1 + 2, 0x00 ); While (LEN> 0) { // Wait until the sending register is empty or times out. Count = 10000; While (! (Inportb (baseaddr1 + 5) & 0x20) & (count> 0 )) Count --; If (count <= 0) // timeout not sent Return false; Outportb (baseaddr1 + 0, * pdata); // sending character Len --; Pdata ++; } // Wait until the sending register is empty or times out again Count = 10000; While (! (Inportb (baseaddr1 + 5) & 0x20) & (count> 0 )) Count --; If (count <= 0) Return false; // timeout not sent Else Return true; // confirmation, sent } Receive data: // Pdata points to the data to be received. Len indicates the Data Length and returns whether the received data is successful. Bool defaults o_recv (char * pdata, int Len) { Int count; // Enable FIFO, clear the receiving FIFO, and clear the sending FIFO Outportb (baseaddr1 + 2, 0x07 ); While (LEN> 0) { // Wait until the received data is ready or times out Count = 10000; While (! (Inportb (baseaddr1 + 5) & 0x01) & (count> 0 )) Count --; If (count <= 0) // timeout is not received Return false; * Pdata = inportb (baseaddr1 + 0); // read a character Len --; Pdate ++ } Return true; } At this point, I/O registers are used to introduce the serial programming methods. I hope to provide some help for our projects, we also need to use it flexibly when using it. Summary For more specific code, refer to the dongsuoying overvoltage program for better connection. As for the interrupted transmission mode, it is suitable for transmitting a large amount of data at a fast speed. Currently, network ports or USB are generally used. This method of serial ports is rarely seen in practical applications, so we will not introduce it here. |