內容包含以下modbus 功能碼的實現01
讀線圈狀態
00001-09999
位操作 單個或多個
02
讀(開關)輸入狀態
10001-19999
位操作 單個或多個
03
讀保持寄存器
40001-49999
字操作 單個或多個
04
讀輸入寄存器
30001-39999
字操作 單個或多個
05
寫單個線圈
00001-09999
位操作 單個
06
寫單個保持寄存器
40001-49999
字操作 單個
15
寫多個線圈
00001-09999
位操作 多個
16
寫多個保持寄存器
40001-49999
字操作 多個
0.png (45.77 KB, 下載次數: 58)
下載附件
2018-8-2 16:37 上傳
單片機源程序如下:
- #include "modbus.h"
- uint16_t modbus_addr[MODBUS_SIZE + 8];
- //
- uint16_t *COIL_ADDR = modbus_addr + 8;
- uint16_t *STATE_ADDR = (modbus_addr + 8 + COIL_SIZE / 16);
- uint16_t *INPUT_ADDR = (modbus_addr + 8 + (COIL_SIZE + STATE_SIZE) / 16);
- uint16_t *HOLD_ADDR = (modbus_addr + 8 + (COIL_SIZE + STATE_SIZE) / 16 + INPUT_SIZE);
- uint16_t read_coil(uint16_t coil_addr,uint16_t reg_type)
- {
- uint16_t i,j;
- if(reg_type == REG_MODBUS)
- coil_addr -= 1;
-
- if(coil_addr >= COIL_SIZE)
- return 0;
-
- i = coil_addr / 16;
- j = coil_addr % 16;
- i = *(COIL_ADDR + i) & (1<<j);
- return (i != 0);
- }
- void write_coil(uint16_t coil_addr, uint16_t on_off, uint16_t reg_type)
- {
- uint16_t i, j, *addr;
- if(reg_type == REG_MODBUS)
- coil_addr -= 1;
- if(coil_addr >= COIL_SIZE)
- return;
- i = coil_addr / 16;
- j = coil_addr % 16;
- j = 1 << j;
- addr = COIL_ADDR + i;
- if(on_off)
- {
- *addr = ( *addr | j);
- }
- else
- {
- *addr = (*addr & (~j));
- }
- }
- uint16_t read_state(uint16_t status_addr, uint16_t reg_type)
- {
- uint16_t i,j;
- if(reg_type == REG_MODBUS)
- status_addr -= 10001;
- if(status_addr >= STATE_SIZE)
- return 0;
-
- i = status_addr / 16;
- j = status_addr % 16;
- i = *(STATE_ADDR + i) & (1<<j);
- return (i != 0);
- }
- void write_state(uint16_t state_addr, uint16_t on_off, uint16_t reg_type)
- {
- uint16_t i, j, *addr;
- if(reg_type == REG_MODBUS)
- state_addr -= 10001;
- if(state_addr >= STATE_SIZE)
- return;
- i = state_addr / 16;
- j = state_addr % 16;
- j = 1 << j;
- addr = STATE_ADDR + i;
- if(on_off)
- {
- *addr = (*addr | j);
- }
- else
- {
- *addr = (*addr & (~j));
- }
- }
- uint16_t read_input(uint16_t input_addr, uint16_t reg_type)
- {
- if(reg_type == REG_MODBUS)
- input_addr -= 30001;
-
- if(input_addr >= INPUT_SIZE)
- return 0;
- return *(INPUT_ADDR + input_addr);
- }
- void write_input(uint16_t input_addr, uint16_t data, uint16_t reg_type)
- {
- if(reg_type == REG_MODBUS)
- input_addr -= 30001;
- if(input_addr >= INPUT_SIZE)
- return;
- *(INPUT_ADDR + input_addr) = data;
- }
- uint16_t read_hold(uint16_t hold_addr,uint16_t reg_type)
- {
- if(reg_type == REG_MODBUS)
- hold_addr -= 40001;
-
- if(hold_addr >= HOLD_SIZE)
- return 0;
- return *(HOLD_ADDR + hold_addr);
- }
- void write_hold(uint16_t hold_addr, uint16_t data, uint16_t reg_type)
- {
- if(reg_type == REG_MODBUS)
- hold_addr -= 40001;
- if(hold_addr >= HOLD_SIZE)
- return;
- *(HOLD_ADDR + hold_addr) = data;
- }
- uint16_t read_reg_n(uint16_t reg_addr)
- {
- if((reg_addr >= 1) && (reg_addr <= COIL_SIZE))
- return read_coil(reg_addr, REG_MODBUS);
- if((reg_addr >=10001) && (reg_addr <=(10000+STATE_SIZE)))
- return read_state(reg_addr ,REG_MODBUS);
- if((reg_addr >=30001) && (reg_addr <=(30000+INPUT_SIZE)))
- return read_input(reg_addr ,REG_MODBUS);
- if((reg_addr >=40001) && (reg_addr <=(40000+HOLD_SIZE)))
- return read_hold(reg_addr ,REG_MODBUS);
- return 0;
- }
- /*???????*/
- void write_reg_n(uint16_t reg_addr ,uint16_t data)
- {
- if((reg_addr >=1) && (reg_addr <=COIL_SIZE))
- write_coil(reg_addr ,data,REG_MODBUS);
- else if((reg_addr >=10001) && (reg_addr <=(10000+STATE_SIZE)))
- write_state(reg_addr ,data,REG_MODBUS);
- else if((reg_addr >=30001) && (reg_addr <=(30000+INPUT_SIZE)))
- write_input(reg_addr ,data,REG_MODBUS);
- else if((reg_addr >=40001) && (reg_addr <=(40000+HOLD_SIZE)))
- write_hold(reg_addr ,data,REG_MODBUS);
- else;
- }
- /*??????? swap=0-???? 1-????*/
- float read_reg_f(uint16_t reg_addr ,uint8_t swap)
- {
- union { uint32_t i; float f; } w;
- if((reg_addr >=30001) && (reg_addr <=(30000+INPUT_SIZE)))
- {
- if(swap==1)
- w.i=(read_input(reg_addr ,REG_MODBUS)<<16)+read_input(reg_addr +1,REG_MODBUS);
- else
- w.i=read_input(reg_addr ,REG_MODBUS)+(read_input(reg_addr +1,REG_MODBUS)<<16);
- return w.f;
- }
- else if((reg_addr >=40001) && (reg_addr <=(40000+HOLD_SIZE)))
- {
- if(swap==1)
- w.i=(read_hold(reg_addr ,REG_MODBUS)<<16)+read_hold(reg_addr +1,REG_MODBUS);
- else
- w.i=read_hold(reg_addr ,REG_MODBUS)+(read_hold(reg_addr +1,REG_MODBUS)<<16);
- return w.f;
- }
- else;
- return 0.0;
- }
- /*??????? swap=0-???? 1-????*/
- void write_reg_f(uint16_t reg_addr ,float data,uint8_t swap)
- {
- union { uint32_t i; float f; } w; /*???????? ??:????ADP3?????!!!*/
- w.f=data;
- if((reg_addr >=30001) && (reg_addr <=(30000+INPUT_SIZE)))
- {
- if(swap==1)
- {
- write_input(reg_addr ,w.i>>16,REG_MODBUS);
- write_input(reg_addr +1,w.i,REG_MODBUS);
- }
- else
- {
- write_input(reg_addr ,w.i,REG_MODBUS);
- write_input(reg_addr +1,w.i>>16,REG_MODBUS);
- }
- }
- else if((reg_addr>=40001) && (reg_addr<=(40000+HOLD_SIZE)))
- {
- if(swap==1)
- {
- write_hold(reg_addr,w.i>>16,REG_MODBUS);
- write_hold(reg_addr+1,w.i,REG_MODBUS);
- }
- else
- {
- write_hold(reg_addr,w.i,REG_MODBUS);
- write_hold(reg_addr+1,w.i>>16,REG_MODBUS);
- }
- }
- else;
- }
- /*???????? swap=0-???? 1-????*/
- uint32_t read_reg_ln(uint16_t reg_addr, uint8_t swap)
- {
- uint32_t i = 0;
- if((reg_addr >= 30001) && (reg_addr <= (30000 + INPUT_SIZE)))
- {
- if(swap == 1)
- i = (read_input(reg_addr, REG_MODBUS) << 16) + read_input(reg_addr + 1, REG_MODBUS);
- else
- i = read_input(reg_addr, REG_MODBUS) + (read_input(reg_addr + 1, REG_MODBUS) << 16);
- }
- else if((reg_addr >= 40001) && (reg_addr <= (40000 + HOLD_SIZE)))
- {
- if(swap == 1)
- i = (read_hold(reg_addr, REG_MODBUS) << 16) + read_hold(reg_addr + 1,REG_MODBUS);
- else
- i = read_hold(reg_addr, REG_MODBUS) + (read_hold(reg_addr + 1, REG_MODBUS) << 16);
- }
- else;
- return i;
- }
- void write_reg_ln(uint16_t reg_addr, uint32_t data, uint8_t swap)
- {
- uint32_t i;
- i = data;
- if((reg_addr >= 30001) && (reg_addr<=(30000 + INPUT_SIZE)))
- {
- if(swap==1)
- {
- write_input(reg_addr, i >> 16,REG_MODBUS);
- write_input(reg_addr + 1, i, REG_MODBUS);
- }
- else
- {
- write_input(reg_addr, i, REG_MODBUS);
- write_input(reg_addr + 1, i >> 16, REG_MODBUS);
- }
- }
- else if((reg_addr >= 40001) && (reg_addr <= (40000 + HOLD_SIZE)))
- {
- if(swap==1)
- {
- write_hold(reg_addr, i >> 16, REG_MODBUS);
- write_hold(reg_addr + 1, i, REG_MODBUS);
- }
- else
- {
- write_hold(reg_addr, i, REG_MODBUS);
- write_hold(reg_addr + 1, i >> 16, REG_MODBUS);
- }
- }
- else;
- }
- uint8_t LRC(uint8_t *auchMsg, uint16_t usDataLen)
- {
- uint8_t uchLRC = 0 ;
- while (usDataLen--) { uchLRC += *auchMsg++ ; }
- return ((uint8_t)(~uchLRC+1));
- }
- static const uint8_t auchCRCHi[]={
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
- 0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40
- };
- static const uint8_t auchCRCLo[]={
- 0x00,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06,0x07,0xc7,0x05,0xc5,0xc4,0x04,
- 0xcc,0x0c,0x0d,0xcd,0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09,0x08,0xc8,
- 0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a,0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,
- 0x14,0xd4,0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3,0x11,0xd1,0xd0,0x10,
- 0xf0,0x30,0x31,0xf1,0x33,0xf3,0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4,
- 0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a,0x3b,0xfb,0x39,0xf9,0xf8,0x38,
- 0x28,0xe8,0xe9,0x29,0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed,0xec,0x2c,
- 0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26,0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,
- 0xa0,0x60,0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67,0xa5,0x65,0x64,0xa4,
- 0x6c,0xac,0xad,0x6d,0xaf,0x6f,0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68,
- 0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e,0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,
- 0xb4,0x74,0x75,0xb5,0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71,0x70,0xb0,
- 0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
- 0x9c,0x5c,0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b,0x99,0x59,0x58,0x98,
- 0x88,0x48,0x49,0x89,0x4b,0x8b,0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,
- 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40
- };
- uint16_t CRC16(uint8_t* puchMsg, uint16_t usDataLen)
- {
- uint8_t uchCRCHi=0xff;
- uint8_t uchCRCLo=0xff;
- uint16_t uIndex;
- while(usDataLen--)
- {
- uIndex=uchCRCHi^*(puchMsg++);
- uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
- uchCRCLo=auchCRCLo[uIndex];
- }
- return uchCRCHi<<8|uchCRCLo;
- }
- uint16_t sx2toi(uint8_t *str)
- {
- uint16_t i=0;
-
- if((str[0]>='0') && (str[0]<='9')) i=(str[0]-'0')<<4;
- else if((str[0]>='A') && (str[0]<='F')) i=(str[0]-'A'+10)<<4;
- else if((str[0]>='a') && (str[0]<='f')) i=(str[0]-'a'+10)<<4;
- else;
- if((str[1]>='0') && (str[1]<='9')) i=i+str[1]-'0';
- else if((str[1]>='A') && (str[1]<='F')) i=i+str[1]-'A'+10;
- else if((str[1]>='a') && (str[1]<='f')) i=i+str[1]-'a'+10;
- else;
-
- return i;
- }
- void itosx2(uint16_t data,uint8_t *str)
- {
- uint16_t i,j;
-
- i=(data & 0xf0)>>4; j=data & 0x0f;
-
- if(i<=9) str[0]='0'+i;
- else str[0]='A'+i-10;
- if(j<=9) str[1]='0'+j;
- else str[1]='A'+j-10;
- }
- uint16_t modbus_asc_hex(uint8_t *asc_buf,uint16_t num)
- {
- uint16_t i;
- num=(num-3)/2;
- for(i=0;i<num;i++)
- { asc_buf[i]=(uint8_t)sx2toi(&asc_buf[i*2+1]); }
- return i;
- }
- uint16_t modbus_hex_asc(uint8_t *hex_buf,uint8_t *asc_buf,uint16_t num)
- {
- uint16_t i;
- asc_buf[0]=':';
- for(i=0;i<num;i++)
- { itosx2((uint16_t)hex_buf[i],&asc_buf[i*2+1]); }
- num=num*2+1;
- asc_buf[num]='\r'; num++;
- asc_buf[num]='\n'; num++;
- return num;
- }
- static const uint32_t crc32tab[] =
- {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
- 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
- 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
- 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
- 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
- 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
- 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
- 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
- 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
- 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
- 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
- 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
- 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
- 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
- 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
- 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
- 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
- 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
- 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
- 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
- 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
- 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
- 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
- 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
- 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
modbus.zip
(1.09 MB, 下載次數: 68)
2018-8-2 16:30 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|