Example code for modbus serial

Dependencies:   mbed

Committer:
vsupacha
Date:
Wed Mar 14 06:17:48 2018 +0000
Revision:
0:f306cb0263a6
Child:
1:0007712e84a8
Code example for Lab 7

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vsupacha 0:f306cb0263a6 1 #include "mbed.h"
vsupacha 0:f306cb0263a6 2 #include "modbus.h"
vsupacha 0:f306cb0263a6 3
vsupacha 0:f306cb0263a6 4 uint8_t nodeId = 0;
vsupacha 0:f306cb0263a6 5 uint16_t regValue[ADDR_RANGE];
vsupacha 0:f306cb0263a6 6
vsupacha 0:f306cb0263a6 7 enum state {IDLE, RECEPTION, END} protState = IDLE;
vsupacha 0:f306cb0263a6 8
vsupacha 0:f306cb0263a6 9 int process_buffer(char *buf, uint8_t *frame)
vsupacha 0:f306cb0263a6 10 {
vsupacha 0:f306cb0263a6 11 int status = 0;
vsupacha 0:f306cb0263a6 12 uint8_t sum = 0;
vsupacha 0:f306cb0263a6 13 uint8_t lrc, i;
vsupacha 0:f306cb0263a6 14 char tmpbuf[] = {0, 0, 0};
vsupacha 0:f306cb0263a6 15
vsupacha 0:f306cb0263a6 16 if (strlen(buf) == 14) {
vsupacha 0:f306cb0263a6 17 for (i = 0; i < 6; i++) {
vsupacha 0:f306cb0263a6 18 tmpbuf[0] = buf[i*2];
vsupacha 0:f306cb0263a6 19 tmpbuf[1] = buf[i*2 + 1];
vsupacha 0:f306cb0263a6 20 frame[i] = strtoul(tmpbuf, NULL, 16);
vsupacha 0:f306cb0263a6 21 }
vsupacha 0:f306cb0263a6 22 tmpbuf[0] = buf[12]; tmpbuf[1] = buf[13];
vsupacha 0:f306cb0263a6 23 lrc = strtoul(tmpbuf, NULL, 16);
vsupacha 0:f306cb0263a6 24 for (i = 0; i < 6; i++) {
vsupacha 0:f306cb0263a6 25 sum += frame[i];
vsupacha 0:f306cb0263a6 26 }
vsupacha 0:f306cb0263a6 27 if ((sum + lrc) == 0) {
vsupacha 0:f306cb0263a6 28 status = 1;
vsupacha 0:f306cb0263a6 29 }
vsupacha 0:f306cb0263a6 30 }
vsupacha 0:f306cb0263a6 31
vsupacha 0:f306cb0263a6 32 return status;
vsupacha 0:f306cb0263a6 33 }
vsupacha 0:f306cb0263a6 34
vsupacha 0:f306cb0263a6 35 void modbus_init(uint8_t id)
vsupacha 0:f306cb0263a6 36 {
vsupacha 0:f306cb0263a6 37 nodeId = id;
vsupacha 0:f306cb0263a6 38 }
vsupacha 0:f306cb0263a6 39
vsupacha 0:f306cb0263a6 40 uint16_t modbus_read(uint16_t offset)
vsupacha 0:f306cb0263a6 41 {
vsupacha 0:f306cb0263a6 42 if (offset < ADDR_RANGE) {
vsupacha 0:f306cb0263a6 43 return regValue[offset];
vsupacha 0:f306cb0263a6 44 }
vsupacha 0:f306cb0263a6 45 return 0xFFFF;
vsupacha 0:f306cb0263a6 46 }
vsupacha 0:f306cb0263a6 47
vsupacha 0:f306cb0263a6 48 uint16_t modbus_update(uint8_t offset, uint16_t val)
vsupacha 0:f306cb0263a6 49 {
vsupacha 0:f306cb0263a6 50 uint16_t tmp;
vsupacha 0:f306cb0263a6 51
vsupacha 0:f306cb0263a6 52 if (offset < ADDR_RANGE) {
vsupacha 0:f306cb0263a6 53 tmp = regValue[offset];
vsupacha 0:f306cb0263a6 54 regValue[offset] = val;
vsupacha 0:f306cb0263a6 55 return tmp;
vsupacha 0:f306cb0263a6 56 }
vsupacha 0:f306cb0263a6 57 return 0xFFFF;
vsupacha 0:f306cb0263a6 58 }
vsupacha 0:f306cb0263a6 59
vsupacha 0:f306cb0263a6 60 int modbus_parser(char ch, uint8_t *frame)
vsupacha 0:f306cb0263a6 61 {
vsupacha 0:f306cb0263a6 62 static char buf[514];
vsupacha 0:f306cb0263a6 63 static int idx = 0;
vsupacha 0:f306cb0263a6 64 static int status = 0;
vsupacha 0:f306cb0263a6 65
vsupacha 0:f306cb0263a6 66 switch(protState) {
vsupacha 0:f306cb0263a6 67 case IDLE:
vsupacha 0:f306cb0263a6 68 if (ch == ':') {
vsupacha 0:f306cb0263a6 69 protState = RECEPTION;
vsupacha 0:f306cb0263a6 70 idx = 0;
vsupacha 0:f306cb0263a6 71 status = 0;
vsupacha 0:f306cb0263a6 72 }
vsupacha 0:f306cb0263a6 73 break;
vsupacha 0:f306cb0263a6 74 case RECEPTION:
vsupacha 0:f306cb0263a6 75 if ((ch >= '0') && (ch <= '9')) {
vsupacha 0:f306cb0263a6 76 buf[idx++] = ch;
vsupacha 0:f306cb0263a6 77 } else if ((ch >= 'a') && (ch <= 'f')) {
vsupacha 0:f306cb0263a6 78 buf[idx++] = ch;
vsupacha 0:f306cb0263a6 79 } else if ((ch >= 'A') && (ch <= 'F')) {
vsupacha 0:f306cb0263a6 80 buf[idx++] = ch;
vsupacha 0:f306cb0263a6 81 } else if (ch == '\r') {
vsupacha 0:f306cb0263a6 82 buf[idx] = 0;
vsupacha 0:f306cb0263a6 83 protState = END;
vsupacha 0:f306cb0263a6 84 } else {
vsupacha 0:f306cb0263a6 85 protState = IDLE;
vsupacha 0:f306cb0263a6 86 }
vsupacha 0:f306cb0263a6 87 break;
vsupacha 0:f306cb0263a6 88 case END:
vsupacha 0:f306cb0263a6 89 if (ch == '\n') {
vsupacha 0:f306cb0263a6 90 if (process_buffer(buf, frame)) {
vsupacha 0:f306cb0263a6 91 if ((frame[0] == nodeId) && (frame[1] == FUNC_CODE)) {
vsupacha 0:f306cb0263a6 92 status = 1;
vsupacha 0:f306cb0263a6 93 }
vsupacha 0:f306cb0263a6 94 }
vsupacha 0:f306cb0263a6 95 }
vsupacha 0:f306cb0263a6 96 protState = IDLE;
vsupacha 0:f306cb0263a6 97 break;
vsupacha 0:f306cb0263a6 98 default:
vsupacha 0:f306cb0263a6 99 protState = IDLE;
vsupacha 0:f306cb0263a6 100 }
vsupacha 0:f306cb0263a6 101
vsupacha 0:f306cb0263a6 102 return status;
vsupacha 0:f306cb0263a6 103 }