{"id":2649,"date":"2024-07-04T16:27:58","date_gmt":"2024-07-04T16:27:58","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2649"},"modified":"2024-07-04T16:28:02","modified_gmt":"2024-07-04T16:28:02","slug":"getting-started-with-rs-485-and-modbus-rtu-part-2-max485-connection-and-modbus-setup","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2649","title":{"rendered":"Getting Started with RS-485 and Modbus-RTU Part 2: MAX485 Connection and ModBus Setup"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"700\" height=\"271\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1.png\" alt=\"\" class=\"wp-image-2650\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1.png 700w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-300x116.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-400x155.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-250x97.png 250w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=2644\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2644\" target=\"_blank\">here<\/a>), we took a look at RS485 and ModBus in general. In the second part, we shall interface MAX485 and develop driver to transmit data.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>MAX485.<\/li><li>Connection.<\/li><li>Developing driver for MAX485.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. MAX485:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The signal level used during the RS485 communication method typically ranges from -7V to +12V. The microcontroller pins are generally not designed to handle these levels. This is why these signals needs to be converted to low voltages, for eg \u00b13V. The module have the MAX485 chip on it, which does most of the job of conversion.<\/p>\n\n\n\n<p>The pinout of the module is shown below<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"856\" height=\"189\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg.webp\" alt=\"\" class=\"wp-image-2651\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg.webp 856w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg-300x66.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg-768x170.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg-750x166.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg-400x88.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_1.jpeg-250x55.webp 250w\" sizes=\"(max-width: 856px) 100vw, 856px\" \/><\/figure>\n\n\n\n<p>On the left side of the module, the&nbsp;<strong>RO<\/strong>&nbsp;pin connects to the RX pin of the UART, and the&nbsp;<strong>DI<\/strong>&nbsp;pin connects to the TX pin.<\/p>\n\n\n\n<p>The&nbsp;<strong>RE<\/strong>&nbsp;and&nbsp;<strong>DE<\/strong>&nbsp;Pins are responsible for setting the module in Receiver or Transmitter mode.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>When the RE pin is LOW and DE pin is LOW, the Module is set in the Receiver mode.<\/li><li>When the DE pin is HIGH and RE pin is HIGH, the Module is set in the Transmitter mode.<\/li><\/ul>\n\n\n\n<p>The&nbsp;<strong>Pin A<\/strong>&nbsp;and the&nbsp;<strong>Pin B<\/strong>&nbsp;are the output pins which carries the transmission signal.&nbsp;<\/p>\n\n\n\n<p>Let\u2019s take an example where we provide the data,\u00a0<strong>0x95<\/strong>\u00a0(10010101) to the module. If the Module is powered with 5V, the output on pins A and B will be as shown below<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"444\" height=\"212\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_3-2.jpeg\" alt=\"\" class=\"wp-image-2652\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_3-2.jpeg 444w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_3-2-300x143.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_3-2-400x191.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_3-2-250x119.jpeg 250w\" sizes=\"(max-width: 444px) 100vw, 444px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"452\" height=\"215\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_4.jpeg\" alt=\"\" class=\"wp-image-2653\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_4.jpeg 452w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_4-300x143.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_4-400x190.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_4-250x119.jpeg 250w\" sizes=\"(max-width: 452px) 100vw, 452px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"522\" height=\"289\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_5.jpeg\" alt=\"\" class=\"wp-image-2654\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_5.jpeg 522w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_5-300x166.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_5-400x221.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/rs485_5-250x138.jpeg 250w\" sizes=\"(max-width: 522px) 100vw, 522px\" \/><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>Since A is the\u00a0<strong>non-inverting<\/strong>\u00a0pin, it\u2019s output will be in sync to the input. It varies between 0 to +5V\u00a0<\/li><li>B is the\u00a0<strong>inverting<\/strong>\u00a0pin, so the output is inverted and varies between -5V to 0<\/li><li>When the second module receives these as inputs, it decode the data based on the voltage differences.<ul><li>If the voltage difference is maximum, the bit is 1, and if the difference is 0 the bit is 0<\/li><\/ul><\/li><li>This data is then converted to lower voltages (0 to 3V) to suit the MCU requirement.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Connection:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"575\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-1024x575.png\" alt=\"\" class=\"wp-image-2655\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-1024x575.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-300x169.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-768x431.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-1536x863.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-2048x1151.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-1150x647.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-750x422.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-400x225.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-04-at-5.37.46\u202fPM-250x141.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>As shown above, The&nbsp;<strong>RO<\/strong>&nbsp;pin is connected to the PA10 (UART1 RX) and&nbsp;<strong>DI<\/strong>&nbsp;pin is connected to the PA9 (UART1 TX).<\/p>\n\n\n\n<p>The\u00a0<strong>RE<\/strong>\u00a0and\u00a0<strong>DE<\/strong>\u00a0are connected together with the pin PA0, which we have set as the output in the MCU.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Developing the Driver:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by creating new source and header file with name of <strong><em>modbus_crc.<\/em><\/strong>c and <strong><em>modbus_crc.h<\/em><\/strong> respectively.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In the header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef INC_MODBUS_CRC_H_\n#define INC_MODBUS_CRC_H_\n\nuint16_t crc16(uint8_t *buffer, uint16_t buffer_length);\n\n\n#endif \/* INC_MODBUS_CRC_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In the source file:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;\n#include &quot;modbus_crc.h&quot;\n\/* Table of CRC values for high-order byte *\/\nstatic const uint8_t table_crc_hi[] = {\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,\n    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,\n    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,\n    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,\n    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,\n    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,\n    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,\n    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,\n    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,\n    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,\n    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,\n    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,\n    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,\n    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,\n    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40\n};\n\n\/* Table of CRC values for low-order byte *\/\nstatic const uint8_t table_crc_lo[] = {\n    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,\n    0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,\n    0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,\n    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,\n    0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,\n    0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,\n    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,\n    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,\n    0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,\n    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,\n    0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,\n    0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,\n    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,\n    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,\n    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,\n    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,\n    0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,\n    0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,\n    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,\n    0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,\n    0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,\n    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,\n    0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,\n    0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,\n    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,\n    0x43, 0x83, 0x41, 0x81, 0x80, 0x40\n};\n\nuint16_t crc16(uint8_t *buffer, uint16_t buffer_length)\n{\n    uint8_t crc_hi = 0xFF; \/* high CRC byte initialized *\/\n    uint8_t crc_lo = 0xFF; \/* low CRC byte initialized *\/\n    unsigned int i; \/* will index into CRC lookup *\/\n\n    \/* pass through message buffer *\/\n    while (buffer_length--) {\n        i = crc_lo ^ *buffer++; \/* calculate the CRC  *\/\n        crc_lo = crc_hi ^ table_crc_hi[i];\n        crc_hi = table_crc_lo[i];\n    }\n\n    return (crc_hi &lt;&lt; 8 | crc_lo);\n}\n<\/pre><\/div>\n\n\n\n<p>This is taken from modbus documentation.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, create new source and header file with name of MAX485.c and MAX485.h respectively.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Within the header file:<\/p>\n\n\n\n<p>Start by including the header guard as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef MAX485_H_\n#define MAX485_H_\n\n\n\n#endif \/* MAX485_H_ *\/<\/pre><\/div>\n\n\n\n<p>Within the header guard, include stdint library as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following enum to handle switching between transmission and reception as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">typedef enum\n{\n\tReceiver =0,\n\tTransmiter=1\n}RS485State;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Declare the following functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void MAX485_RE_DE_Init(void);\nvoid SetRS485Mode(RS485State state);\nvoid RS485SendData(uint8_t addr, uint8_t FunCode, uint16_t MemAddr, uint16_t size );<\/pre><\/div>\n\n\n\n<p>Hence, the header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef MAX485_H_\n#define MAX485_H_\n\n#include &quot;stdint.h&quot;\n\ntypedef enum\n{\n\tReceiver =0,\n\tTransmiter=1\n}RS485State;\n\n\nvoid MAX485_RE_DE_Init(void);\nvoid SetRS485Mode(RS485State state);\nvoid RS485SendData(uint8_t addr, uint8_t FunCode, uint16_t MemAddr, uint16_t size );\n\n#endif \/* MAX485_H_ *\/<\/pre><\/div>\n\n\n\n<p>In the source file, we start by including the MAX485 header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;MAX485.h&quot;<\/pre><\/div>\n\n\n\n<p>Also, include the STM32F4 main header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f4xx.h&quot;<\/pre><\/div>\n\n\n\n<p>Include both crc and uart header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;modbus_crc.h&quot;\n#include &quot;uart1.h&quot;<\/pre><\/div>\n\n\n\n<p>We start by configuring the PA0 to handle the change between transmission and reception as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void MAX485_RE_DE_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0_1;\n}<\/pre><\/div>\n\n\n\n<p>To change the mode function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SetRS485Mode(RS485State state)\n{\n\tswitch (state)\n\t{\n\t case Receiver: GPIOA-&gt;BSRR=GPIO_BSRR_BR0; break;\n\t case Transmiter: GPIOA-&gt;BSRR=GPIO_BSRR_BS0; break;\n\t default: GPIOA-&gt;BSRR=GPIO_BSRR_BR0; break;\n\t}\n}<\/pre><\/div>\n\n\n\n<p>The function shall take RS485State as argument. Then the function set the pin low if the mode is reception or high if transmission. In case incorrect parameter has been passed, the function shall set MAX485 in reception mode.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now for transmission the data:<\/p>\n\n\n\n<p>When the master request to read data, the data frame as following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"697\" height=\"192\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/stm_4.webp\" alt=\"\" class=\"wp-image-2656\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/stm_4.webp 697w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/stm_4-300x83.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/stm_4-400x110.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/stm_4-250x69.webp 250w\" sizes=\"(max-width: 697px) 100vw, 697px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>First byte is the address of the slave device.<\/p>\n\n\n\n<p>Function code for read\/write.<\/p>\n\n\n\n<p>Register address high and low.<\/p>\n\n\n\n<p>Number of the data to be read.<\/p>\n\n\n\n<p>CRC value.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence the transmission function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void RS485SendData(uint8_t addr, uint8_t FunCode, uint16_t MemAddr, uint16_t size )\n{\n\tuint8_t data[8]={0};\n\tdata[0]=addr;\n\tdata[1]=FunCode;\n\tdata[2]=((MemAddr&gt;&gt;8)&amp;0xFF);\n\tdata[3]=((MemAddr)&amp;0xFF);\n\tdata[4]=((size&gt;&gt;8)&amp;0xFF);\n\tdata[5]=((size)&amp;0xFF);\n\tuint16_t tmp_crc=crc16(data,6);\n\tdata[6]=tmp_crc&amp;0xFF;\n\tdata[7]=(tmp_crc&gt;&gt;8)&amp;0xFF;\n\tSetRS485Mode(Transmiter);\n\tUART1_TX(data, 8);\n\tSetRS485Mode(Receiver);\n\n}<\/pre><\/div>\n\n\n\n<p>First, declare buffer to hold the data to be transmitted as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t data[8]={0};<\/pre><\/div>\n\n\n\n<p>First byte for the address:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">data[0]=addr;<\/pre><\/div>\n\n\n\n<p>Function code:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">data[1]=FunCode;<\/pre><\/div>\n\n\n\n<p>Memory address:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">data[2]=((MemAddr&gt;&gt;8)&amp;0xFF);\ndata[3]=((MemAddr)&amp;0xFF);<\/pre><\/div>\n\n\n\n<p>Size of the data:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">data[4]=((size&gt;&gt;8)&amp;0xFF);\ndata[5]=((size)&amp;0xFF);<\/pre><\/div>\n\n\n\n<p>Last two bytes for the CRC as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint16_t tmp_crc=crc16(data,6);\ndata[6]=tmp_crc&amp;0xFF;\ndata[7]=(tmp_crc&gt;&gt;8)&amp;0xFF;<\/pre><\/div>\n\n\n\n<p>Set the module into transmission mode:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">SetRS485Mode(Transmiter);<\/pre><\/div>\n\n\n\n<p>Send the data:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">UART1_TX(data, 8);<\/pre><\/div>\n\n\n\n<p>Put it back to reception mode:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">SetRS485Mode(Receiver);<\/pre><\/div>\n\n\n\n<p>Hence, the source code as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;MAX485.h&quot;\n#include &quot;stm32f4xx.h&quot;\n#include &quot;modbus_crc.h&quot;\n#include &quot;uart1.h&quot;\n\n\nvoid MAX485_RE_DE_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0_1;\n}\n\n\nvoid SetRS485Mode(RS485State state)\n{\n\tswitch (state)\n\t{\n\t case Receiver: GPIOA-&gt;BSRR=GPIO_BSRR_BR0; break;\n\t case Transmiter: GPIOA-&gt;BSRR=GPIO_BSRR_BS0; break;\n\t default: GPIOA-&gt;BSRR=GPIO_BSRR_BR0; break;\n\t}\n}\n\nvoid RS485SendData(uint8_t addr, uint8_t FunCode, uint16_t MemAddr, uint16_t size )\n{\n\tuint8_t data[8]={0};\n\tdata[0]=addr;\n\tdata[1]=FunCode;\n\tdata[2]=((MemAddr&gt;&gt;8)&amp;0xFF);\n\tdata[3]=((MemAddr)&amp;0xFF);\n\tdata[4]=((size&gt;&gt;8)&amp;0xFF);\n\tdata[5]=((size)&amp;0xFF);\n\tuint16_t tmp_crc=crc16(data,6);\n\tdata[6]=tmp_crc&amp;0xFF;\n\tdata[7]=(tmp_crc&gt;&gt;8)&amp;0xFF;\n\tSetRS485Mode(Transmiter);\n\tUART1_TX(data, 8);\n\tSetRS485Mode(Receiver);\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In part 3, we shall start communicating with RS485 ModBus enabled device.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at RS485 and ModBus in general. In the second part, we shall interface MAX485 and develop driver to transmit data. In this guide, we shall cover the following: MAX485. Connection. Developing driver for MAX485. 4. MAX485: The signal level used during the RS485 communication method typically [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2649","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2649"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2649"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2649\/revisions"}],"predecessor-version":[{"id":2657,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2649\/revisions\/2657"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}