Переглянути джерело

New API modbus_read_float() and modbus_write_float() for float values

Stéphane Raimbault 15 роки тому
батько
коміт
22a6898198
5 змінених файлів з 59 додано та 1 видалено
  1. 2 1
      NEWS
  2. 21 0
      src/modbus.c
  3. 6 0
      src/modbus.h
  4. 27 0
      tests/unit-test-master.c
  5. 3 0
      tests/unit-test.h

+ 2 - 1
NEWS

@@ -1,5 +1,6 @@
-libmodbus 2.2.0 (2009-06-01)
+libmodbus 2.2.0 (2009-XX-01)
 ============================
+- New API to read and write float values
 - New API for slave server (see MIGRATION)
 - New slave server able to handle multiple connections
 - Slave only replies to broadcast queries or queries with its slave ID

+ 21 - 0
src/modbus.c

@@ -1964,3 +1964,24 @@ uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits)
 
         return value;
 }
+
+/* Read a float from 4 bytes in Modbus format */
+float modbus_read_float(const uint16_t *src)
+{
+        float real;
+        uint32_t ireal = (src[1] << 16) + src[0];
+        real = *((float *)&ireal);
+
+        return real;
+}
+
+/* Write a float to 4 bytes in Modbus format */
+void modbus_write_float(float real, uint16_t *dest)
+{
+        uint32_t ireal;
+
+        ireal = *((uint32_t *)&real);
+        /* Implicit mask 0xFFFF */
+        dest[0] = ireal;
+        dest[1] = ireal >> 16;
+}

+ 6 - 0
src/modbus.h

@@ -344,6 +344,12 @@ void set_bits_from_bytes(uint8_t *dest, int address, int nb_bits,
    To obtain a full byte, set nb_bits to 8. */
 uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits);
 
+/* Read a float from 4 bytes in Modbus format */
+float modbus_read_float(const uint16_t *src);
+
+/* Write a float to 4 bytes in Modbus format */
+void modbus_write_float(float real, uint16_t *dest);
+
 #ifdef __cplusplus
 }
 #endif

+ 27 - 0
tests/unit-test-master.c

@@ -36,6 +36,7 @@ int main(void)
         int address;
         int nb_points;
         int ret;
+        float real;
 
         /* RTU parity : none, even, odd */
 /*      modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1, SLAVE); */
@@ -253,6 +254,30 @@ int main(void)
         printf("OK\n");
 
 
+        printf("\nTEST FLOATS\n");
+        /** FLOAT **/
+        printf("1/2 Write float: ");
+        modbus_write_float(UT_REAL, tab_rp_registers);
+        if (tab_rp_registers[1] == (UT_IREAL >> 16) &&
+            tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) {
+                printf("OK\n");
+        } else {
+                printf("FAILED (%x != %x)\n",
+                       *((uint32_t *)tab_rp_registers), UT_IREAL);
+                goto close;
+        }
+
+        printf("2/2 Read float: ");
+        real = modbus_read_float(tab_rp_registers);
+        if (real == UT_REAL) {
+                printf("OK\n");
+        } else {
+                printf("FAILED (%f != %f)\n", real, UT_REAL);
+                goto close;
+        }
+
+        printf("\nAt this point, error messages doesn't mean the test has failed\n");
+
         /** ILLEGAL DATA ADDRESS **/
         printf("\nTEST ILLEGAL DATA ADDRESS:\n");
 
@@ -465,6 +490,8 @@ int main(void)
         }
         free(tab_rp_registers_bad);
 
+        printf("\nALL TESTS PASS WITH SUCCESS.\n");
+
 close:
         /* Free the memory */
         free(tab_rp_status);

+ 3 - 0
tests/unit-test.h

@@ -42,4 +42,7 @@ const uint16_t UT_INPUT_REGISTERS_ADDRESS = 0x08;
 const uint16_t UT_INPUT_REGISTERS_NB_POINTS = 0x1;
 const uint16_t UT_INPUT_REGISTERS_TAB[] = { 0x000A };
 
+const float UT_REAL = 916.540649;
+const uint32_t UT_IREAL = 0x4465229a;
+
 #endif /* _UNIT_TEST_H_ */