-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.c
191 lines (134 loc) · 6.04 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
* main.c
*
* Created on: 26 lip 2015
* Author: Jerzy Maczenski JMS
*/
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"
#include "string.h"
#include "modbus/mb.h"
#include "modbus/mbIO.h"
//macros for led configuration port B pin 5, and switch ON/OFF
#define LED_1_PIN (1<<PB5)
#define LED_1_OFF PORTB &= ~LED_1_PIN //led ON
#define LED_1_ON PORTB |= LED_1_PIN //led OFF
#define LED_1_CHANGE PORTB ^= LED_1_PIN //led SWITCH
//callback functions, for better transparency of code you should put this functions in another files (ex. callbackFunctions.c and callbackFunctions.h)
//function for set LED ON/OFF
uint8_t callbackSetCoil(void) {
uint16_t coilID;
uint16_t stateCoil;
coilID = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn05.coilAddress); //coil address
stateCoil = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn05.coilState); //coil status ==0 => LED OFF, !=0 => LED ON
switch (coilID) {
case 1:
//set LED 1 ON/OFF
if( stateCoil != 0 ) LED_1_ON;
else LED_1_OFF;
break;
case 2:
//to do : set another LED ON/OFF
break;
case 3:
//to do : set another LED ON/OFF
break;
default:
break;
}
return MB_ERR_OK;
}
//function for read holding registers
//register must be defined as a global variable
uint16_t firstRegisterValue;
uint16_t secondRegisterValue[2];
//
#define FIRST_REGISTER_ADDRESS 5
#define SECOND_REGISTER_ADDRESS 7
uint8_t callbackReadHoldingRegisters( void ) {
uint16_t registersStartAddress; //reads from MODBUS request freame
uint16_t registersNb; //reads from MODBUS request freame
uint8_t bytesNb; //calculates from data sending by master
registersStartAddress = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn03.startAddress); // requested register start address
registersNb = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn03.numberRegs); // requested number of registers
bytesNb = registersNb * 2; // number of bytes sending back (if you want 2 regs = 4 bytes, 4 regs = 8 bytes so on...)
switch (registersStartAddress) {
case FIRST_REGISTER_ADDRESS: //send value of first register
if(registersNb == 1) { //check - master want one register pointed by reg sddress?
MB_FRAME_BUFFER.TxFn03.numberBytes = bytesNb; //set number of bytes sending back to master
MB_FRAME_BUFFER.TxFn03.dataUint16[0] = mbUtilSwapUint16(firstRegisterValue); //set value of register
return MB_ERR_OK; //everything is OK we can send response to master
}
else {
MB_PROTOCOL_STATE.codeError = MB_ERR_ILLEGAL_DATA_ADDR; //if number of register+address is outside of the scope send MB_ERR_ILLEGAL_DATA_ADDR
}
break;
case SECOND_REGISTER_ADDRESS:
if(registersNb == 2) { //check - master want two registers pointed by reg sddress?
MB_FRAME_BUFFER.TxFn03.numberBytes = bytesNb; //set number of bytes sending back to master
MB_FRAME_BUFFER.TxFn03.dataUint16[0] = mbUtilSwapUint16(secondRegisterValue[0]); //set value of registers
MB_FRAME_BUFFER.TxFn03.dataUint16[1] = mbUtilSwapUint16(secondRegisterValue[1]);
return MB_ERR_OK; //everything is OK we can send response to master
}
else {
MB_PROTOCOL_STATE.codeError = MB_ERR_ILLEGAL_DATA_ADDR; //if number of register+address is outside of the scope send MB_ERR_ILLEGAL_DATA_ADDR
}
break;
default:
MB_PROTOCOL_STATE.codeError = MB_ERR_ILLEGAL_DATA_ADDR; //if address is not FIRST_REGISTER_ADDRESS nor SECOND_REGISTER_SDDRES send MB_ERR_ILLEGAL_DATA_ADDR
break;
}
return MB_PROTOCOL_STATE.codeError;
}
//function for write holding registers
//register must be defined as a global variable we use register from demo of read holding register function firstRegisterValue
uint8_t callbackWriteHoldingRegisters( void ) {
uint16_t registersStartAddress; //reads from MODBUS request freame
uint16_t registersNb; //reads from MODBUS request freame
registersStartAddress = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn16.startAddress); // write register start address
registersNb = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn16.numberRegs); // number of registers to write
switch (registersStartAddress) {
case FIRST_REGISTER_ADDRESS: //write value of first register
if(registersNb == 1) { //check - master want to write one register pointed by reg sddress?
firstRegisterValue = mbUtilSwapUint16(MB_FRAME_BUFFER.RxFn16.dataUint16[0]); //write value to register
return MB_ERR_OK; //everything is OK we can send response to master
}
else {
MB_PROTOCOL_STATE.codeError = MB_ERR_ILLEGAL_DATA_ADDR; //if number of register+address is outside of the scope send MB_ERR_ILLEGAL_DATA_ADDR
}
break;
default:
MB_PROTOCOL_STATE.codeError = MB_ERR_ILLEGAL_DATA_ADDR; //if address is not FIRST_REGISTER_ADDRESS send MB_ERR_ILLEGAL_DATA_ADDR
break;
}
return MB_PROTOCOL_STATE.codeError;
}
int main(void) {
//pin5 port B as output configuration
DDRB |= LED_1_PIN;
PORTB |= LED_1_PIN;
LED_1_OFF;
//register callback function for handle MB_FN_WRITE_SINGLE_COIL modbus function
mbRegisterFunctionHandler(0, MB_FN_WRITE_SINGLE_COIL, callbackSetCoil);
//register callback function for handle MB_FN_READ_HOLDING_REGISTERS modbus function
mbRegisterFunctionHandler(1, MB_FN_READ_HOLDING_REGISTERS, callbackReadHoldingRegisters);
//register callback function for handle MB_FN_WRITE_HOLDING_REGISTERS modbus function
mbRegisterFunctionHandler(2, MB_FN_WRITE_HOLDING_REGISTERS, callbackWriteHoldingRegisters);
//init protocolo and UART
mbInit();
//enable interrupts
sei();
firstRegisterValue = 11; //initialize first register, it can be writing from MASTER
//never ending loop
while (1 == 1) {
//here you can set registers
secondRegisterValue[0] = 72; //second registers for example data from 18B20 (temperature)
secondRegisterValue[1] = 34;
//poll modbus state-machine
mbPoll();
//here do something else
//...
//---
}
}