Communication between a microcontroller and a PLC is achieved based on the Modbus protocol.
2026-04-06 03:12:10··#1
1 Introduction HMI (Human Machine Interface) is increasingly used in industrial automation systems and equipment due to its small size, high performance and strong real-time characteristics. It has different displays such as letters, Chinese characters, graphics and pictures, and the interface is simple and friendly. It is equipped with a membrane button keyboard with a long life and simple operation. It generally uses a single-chip microcomputer [1] with advantages such as high integration, fast speed, high reliability and low price as its core controller to achieve real-time fast processing. The combination of PLC and single-chip microcomputer can not only improve the data processing capability of PLC, but also bring a friendly and simple interface to users. This article takes the Modbus communication protocol as an example and discusses in detail how to use C51 to realize communication between single-chip microcomputer and PLC in a human machine system. 2 Modbus Communication Protocol The Modbus protocol is a general language applied to electronic controllers. Through this protocol, controllers can communicate with each other and controllers can communicate with other devices via the network. The Modbus protocol provides the master-slave principle, that is, only one device (master device) can initialize transmission (query). Other devices (slave devices) respond accordingly based on the data provided by the master device. The format of the master device query is: device address (or broadcast, in which case no response is required), function code, all data to be sent, and an error detection field. The slave device response message includes an acknowledgment address, function code, any data to be returned, and an error detection field. If an error occurs during message reception, or the slave device cannot execute its command, the slave device will generate an error message and send it out as a response. The controller can be set to two transmission modes: ASCII and RTU. At the same baud rate, RTU can transmit more data than ASCII, so the KTU mode is used. (1) Typical RTU message frame Typical RTU message frames are shown in Table 1. The address field of the RTU message frame contains 8 bits. The possible slave device addresses are 0...127 (decimal). Address 0 is used as the broadcast address so that all slave devices can recognize it. The master device selects the slave device by putting the address of the slave device to be contacted into the address field of the message. When the slave device sends a response message, it puts its own address into the address field of the response so that the master device knows which device responded. The function code field in an RTU message frame contains 8 bits. When a message is sent from the master device to the slave device, the function code field tells the slave device what actions to perform. When the slave device responds, it uses the function code field to indicate whether it is a normal response (error-free) or an error response (called an objection response, typically changing the highest bit of the function code from 0 to 1). The data field of the message sent from the master device to the slave device contains additional information that the slave device must use to perform the actions defined by the function code. This includes things like non-contiguous register addresses, the number of items to be processed, and the actual number of data bytes in the field. If no error occurs, the data field returned by the slave device contains the requested data. If an error occurs, this field contains an objection code that the master device application can use to determine the next action. When RTU mode is used as a character frame, the error detection field contains a 16-bit value (implemented using two 8-bit characters). The content of the error detection field is obtained by performing a Cyclic Redundancy Check (CRC) on the message content. The CRC field is appended to the end of the message, added first the low byte and then the high byte. (2) All Modbus function codes The definition of Modbus function codes is shown in Table 2. 3 Design of common function communication programs This article introduces the design of several common Modbus function programs. The author uses a microcontroller as the host and writes a program on the microcontroller to realize the communication between the microcontroller and the PLC. The microcontroller sends command information to the PLC and the PLC responds automatically. The PLC communicates through the serial communication port of the microcontroller. The program is implemented using C51. The sub-functions of the program and their functions: (1) Serial port initialization void ProtocolInit(void) Function function: The serial port is set to asynchronous communication mode 1 (start bit 1 bit, data bit 8 bits, stop bit 1 bit); the timer/counter 1 is set to baud rate generator, and the communication rate is 9600bps; the serial interrupt is enabled and the serial interrupt is set to high priority. (2) Simple CRC function unsigned char Crc16(unsigned char *puchMsg, unsigned char usDataLen) Function: First, load a 16-bit register with all "1"s. Then, call a procedure to process the values in the current registers of each of the consecutive 8-bit bytes in the message. Each 8-bit character is individually ORed with the register content, and the result is shifted towards the least significant bit, with the most significant bit filled with 0. The LSB is extracted and checked. If the LSB is 1, the register is individually ORed with the preset value. If the LSB is 0, no action is taken. The entire process is repeated 8 times. After the last bit (the 8th bit) is completed, the next 8-bit byte is individually ORed with the current value of the register. The final value in the register is the CRC value after all bytes in the message have been processed. (3) Initialize variable void Initvar(void) Function: Initializes all procedure variables. (4) Serial interrupt service routine void ProtocolSerialProcess(void) interrupt 4 using 2 Function: Send interrupt: Sends the command array formed by the host, and sets the flag after sending; Receive interrupt: Receives the response array returned by the PLC, stores it in the receive array, sets the flag, and assumes the response is correct, leaving it for host processing. (5) Read N bit variables (coils) void ProtocolRead_bit(unsigned char DeviceAddr/* PLC number*/, unsigned char RegType/* Register type*/, unsigned int BitAddr/* Starting address*/, unsigned char SubAddr/* Sub address*/, unsigned int BitNum/* Bit size*/) Function: Based on the function parameters, forms a command array to read N bit variables and starts sending. Waits for the sending and receiving to complete (if the timeout occurs and the receiving is not completed, it will resend). Analyze the receive array: If correct, save the read data; if incorrect, resend. (6) Write a bit variable `void ProtocolSetBit(unsigned char DeviceAddr /* PLC office number */, unsigned char RegType /* register type */, unsigned int BitAddr /* address */, unsigned char SubAddr /* sub-address */, unsigned int ClrSet /* write value "1" or "0" */)`. Function: Based on the function parameters, form a command array to set a bit variable to "1" or "0", and start sending. Wait for the sending and receiving to complete (if the timeout occurs and the receiving is not completed, resend). Analyze the received array: if correct, return; if incorrect, resend. (7) Read N bytes of variable void ProtocolReadByte(unsigned char DeviceAddr /* PLC office number */, unsigned char RegType /* register type */, unsigned int RegAddr /* starting address */, unsigned char SubAddr /* sub-address */, unsigned int RegNum /* number */) Function: Based on the function parameters, form a command array to read N bytes of variable and start sending. Wait for the sending and receiving to complete (if the timeout occurs and the data is not received, resend). Analyze the received array: If correct, save the read data; if incorrect, resend. (8) Write N bytes of variables: void ProtocolSetByte(unsigned char DeviceAddr /* PLC office number */, unsigned char RegType /* register type */, unsigned int RegAddr /* starting address */, unsigned char SubAddr /* sub-address */, unsigned int RegNum /* number */) Function: Based on the function parameters, form a command array to write N word variables (the numbers to be written are read from a parameter array), and start sending. Wait for the sending and receiving to complete (if the timeout occurs and the receiving is not completed, resend). Analyze the received array: if correct, return; if incorrect, resend. 4 Conclusion The above program has been tested and applied to a practical human-machine system. Following a similar method, other programs with different functions can be written to realize different controls and operations on the PLC. By utilizing the complementary advantages of microcontrollers and PLCs, a networked and intelligent industrial control system can be formed. In addition, the entire microcontroller system program is programmed in C51 language, which is concise and easy to read and debug. The combination of a microcontroller and a human-machine interface can display the PLC's working status in real time, and control, set, and adjust the PLC's working status in real time, thereby improving the automation level and real-time performance of industrial control.