Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:12 03 Dec 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Request: Micromite Modbus CRC CFunction

Author Message
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1647
Posted: 05:36am 02 Dec 2025
Copy link to clipboard 
Print this post

Hello All,

I would like to use the Modbus CRC in a Micromite MK2. I am aware of the MMBasic versions on The Fruit Of The Shed (I put them there) but I would like to use a CFunction for extra speed. I also Know that it is available in the PicoMite but I want to use the Micomite.

Claude AI has written the C code for me but I don't have the software or the knowledge to compile the code.

If there is someone out there who could do that for I would be very grateful.

The code:
/*
* Modbus CRC-16 CFunction for Micromite Mk2 MMBasic
*
* Compile this with MPLAB X and XC32 compiler using the settings:
* - Position independent code (-mno-abicalls -fno-pic)
* - Optimization level -O1 or -O2
* - Target: PIC32MX470F512H (for Micromite Mk2)
*
* After compiling, extract the hex codes and insert into MMBasic as:
*
* CFunction modbus_crc(STRING) INTEGER
*   [hex codes here]
* End CFunction
*
* Usage in MMBasic:
*   data$ = CHR$(&h01) + CHR$(&h03) + CHR$(&h00) + CHR$(&h00) + CHR$(&h00) + CHR$(&h0A)
*   crc% = modbus_crc(data$)
*   PRINT "CRC: "; HEX$(crc%, 4)
*/

#include "CFunction.h"

/*
* Calculate Modbus CRC-16
* Input: Pointer to MMBasic string (first byte = length, followed by data)
* Returns: 16-bit CRC value as long long int
*/
long long int modbus_crc(unsigned char *str) {
   unsigned char len;
   unsigned char *data;
   unsigned short crc;
   int i, j;
   
   // Get string length (first byte)
   len = *str;
   
   // Point to actual data (skip length byte)
   data = str + 1;
   
   // Initialize CRC to 0xFFFF
   crc = 0xFFFF;
   
   // Process each byte
   for (i = 0; i < len; i++) {
       crc = crc ^ data[i];
       
       // Process each bit
       for (j = 0; j < 8; j++) {
           if (crc & 0x0001) {
               crc = (crc >> 1) ^ 0xA001;
           } else {
               crc = crc >> 1;
           }
       }
   }
   
   // Return as long long int (MMBasic integer type)
   return (long long int)crc;
}

/*
* Example usage in MMBasic:
*
* ' Define the CFunction (after compiling and extracting hex codes)
* CFunction modbus_crc(STRING) INTEGER
*   00000000
*   [your hex codes here]
* End CFunction
*
* ' Use it in your program
* data$ = CHR$(&h01) + CHR$(&h03) + CHR$(&h00) + CHR$(&h00) + CHR$(&h00) + CHR$(&h0A)
* crc% = modbus_crc(data$)
*
* PRINT "CRC value: "; HEX$(crc%, 4)
*
* ' Append CRC to message (Modbus uses little-endian: low byte first)
* message$ = data$ + CHR$(crc% AND &hFF) + CHR$((crc% >> 8) AND &hFF)
*
* ' Send the complete message with CRC
* PRINT "Complete message with CRC: ";
* FOR i = 1 TO LEN(message$)
*   PRINT HEX$(ASC(MID$(message$, i, 1)), 2); " ";
* NEXT i
* PRINT
*/


If someone can do it for me I will ask Geoff to include it in the documentation and/or put it on The Fruit Of The Shed.

Thank you in anticipation.

Bill
Keep safe. Live long and prosper.
 
GerryL
Regular Member

Joined: 24/01/2019
Location: Australia
Posts: 42
Posted: 09:35pm 02 Dec 2025
Copy link to clipboard 
Print this post

Hi Bill,
try this, I have not tested it. Compiler set for -mprocessor=32MX470F512H. If it doesn't work let me know and I will look at it further.
CFUNCTION ModbusCRC
   00000000
   
    'main
   90870000 18E00012 3402FFFF 00803021 00873821 2405A001 90C30001 00431026
   24030008 30440001 10800003 00021042 00451026 3042FFFF 2463FFFF 1460FFFA
   30440001 24C60001 54C7FFF4 90C30001 03E00008 00001821
END CFUNCTION


Gerry
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025