g0b1vetx-board/middleware/Freemodbus/modbus/modbus.h
2023-04-29 09:09:12 +08:00

444 lines
16 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _ECBM_MODBUS_H_
#define _ECBM_MODBUS_H_
/*-------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2023 奈特
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
免责说明:
本软件库以MIT开源协议免费向大众提供。作者只保证原始版本是由作者在维护修BUG
其他通过网络传播的版本也许被二次修改过由此出现的BUG与作者无关。而当您使用原始
版本出现BUG时请联系作者解决。
**************************
* 联系方式进群778916610 *
* 若1群满人进群927297508*
**************************
------------------------------------------------------------------------------------*/
//-----------------以下是图形设置界面可在Configuration Wizard界面设置-----------------
//<<< Use Configuration Wizard in Context Menu >>>
//<q>使能IO控制读写功能
//<i>使能后需要自己定义实现接口函数函数内部放控制IO的语句IO电平由形参传入
//<i>当modbus需要控制IO的时候会调用这个接口函数
//<i>void ecbm_modbus_rtu_set_io(emu8 dat)
//<i>{
//<i> gpio_out_fast(GPIO_P5, GPIO_PIN_5, dat);
//<i> //gpio_out(RS485_ENA,dat);
//<i>}
#define ECBM_MODBUS_IO_EN 0
//<h>MODBUS_RTU
#define ECBM_MODBUS_VERSION "V1.0.4"
//<i>这是modbus协议的RTU模式。
//<o>本机地址/ID
//<1-247>
//<i>8位的地址可使用的范围是1~2470作为广播地址。
#define ECBM_MODBUS_RTU_ID_ADRESS 1
//<o>超时时间
//<i>单位为定时器中断次数。比如500就是定时器中断500次若每次中断的间隔是1ms那么就是500mS超时。
#define ECBM_MODBUS_RTU_TIME_MAX 5
//<h>线圈读写功能设置
//<e>线圈缓存
//<i>勾选后会定义一个数组作为缓存,线圈指令操作都会指向这个数组,适合新项目的开始。可以使用读写函数获取数组内部的值。
//<i>不勾选的话可以通过移植两个读写函数将读写线圈功能映射到任意的地方。适合为老项目增加modbus功能。
#define ECBM_MODBUS_RTU_BIT_BUF_EN 0
//<o>线圈起始地址
//<i>有时候为了适配别人的协议地址不一定是从0开始的在这里可以设置一个偏移。
#define ECBM_MODBUS_RTU_BIT_START_ADDR 0
//<o>线圈缓存总数
//<i>单位是字节8位请根据需求填写。比如设备要有10个线圈因为至少需要两个字节才能存完10个那么就应该填2。
#define ECBM_MODBUS_RTU_BIT_BUF_SIZE 3
//</e>
//<h>线圈指令使能
//<i>如果和线圈有关的指令都没有被使能,那么线圈读写相关的函数和缓存都将被优化掉。
//<q>[01]读线圈
#define ECBM_MODBUS_RTU_CMD01_EN 1
//<q>[05]写单个线圈
#define ECBM_MODBUS_RTU_CMD05_EN 1
//</h>
//</h>
//<h>寄存器读写功能设置
//<e>寄存器缓存
#define ECBM_MODBUS_RTU_REG_BUF_EN 0
//<o>寄存器起始地址
//<i>有时候为了适配别人的协议地址不一定是从0开始的在这里可以设置一个偏移。
#define ECBM_MODBUS_RTU_REG_START_ADDR 0
//<o>寄存器缓存总数
//<i>单位是字16位请根据需求填写。
#define ECBM_MODBUS_RTU_REG_BUF_SIZE 40
//</e>
//<h>寄存器指令使能
//<i>如果和寄存器有关的指令都没有被使能,那么线圈读写相关的函数和缓存都将被优化掉。
//<q>[03]读寄存器
#define ECBM_MODBUS_RTU_CMD03_EN 1
//<q>[06]写单个寄存器
#define ECBM_MODBUS_RTU_CMD06_EN 1
//<e>[10]写多个寄存器
#define ECBM_MODBUS_RTU_CMD10_EN 1
//<o>寄存器写入缓存总数
//<i>单位是字节8位由于CRC的存在在多字节写入的时候不能立刻把数据存入需要用一个缓存存起来待CRC验证完毕之后才能一起写入。
#define ECBM_MODBUS_RTU_BUF_SIZE 10
//</e>
//</h>
//</h>
//<h>IO系统指令使能
//<i>如果和IO系统有关的指令都没有被使能那么IO相关的函数和缓存都将被优化掉。
//<q>[02]读离散量输入
#define ECBM_MODBUS_RTU_CMD02_EN 1
//<q>[04]读输入寄存器
#define ECBM_MODBUS_RTU_CMD04_EN 1
//</h>
#define ECBM_MODBUS_RTU_CMD_BIT_EN (ECBM_MODBUS_RTU_CMD01_EN+ECBM_MODBUS_RTU_CMD05_EN)
#define ECBM_MODBUS_RTU_CMD_REG_EN (ECBM_MODBUS_RTU_CMD03_EN+ECBM_MODBUS_RTU_CMD06_EN+ECBM_MODBUS_RTU_CMD10_EN)
#define ECBM_MODBUS_RTU_CMD_IO_EN (ECBM_MODBUS_RTU_CMD02_EN+ECBM_MODBUS_RTU_CMD04_EN)
#define ECBM_MODBUS_RTU_CMD_ALL_EN (ECBM_MODBUS_RTU_CMD_BIT_EN+ECBM_MODBUS_RTU_CMD_REG_EN+ECBM_MODBUS_RTU_CMD_IO_EN)
//<<< end of configuration section >>>
//-----------------以上是图形设置界面可在Configuration Wizard界面设置-----------------
/*-----------------------------------数据类型宏定义--------------------------------*/
#define fast_type idata //快速内存区。
#define large_type xdata //大容量内存区。
typedef unsigned char emu8; //8位无符号型变量。
typedef unsigned short emu16; //16位无符号型变量。
typedef unsigned long emu32; //32位无符号型变量。
/*------------------------------------状态机宏定义---------------------------------*/
#define ECBM_MODBUS_RTU_READY 0 //就绪态此时可以接受一帧modbus数据。
#define ECBM_MODBUS_RTU_WAIT 1 //等待态,当发生错误之后,在此等待当前数据帧结束。
#define ECBM_MODBUS_RTU_ID_ERR 2 //ID错误当接收到的ID不是本机也不是广播地址时会到这里。
#define ECBM_MODBUS_RTU_FUN_NUM 3 //读取功能码,在此读取功能码。
#define ECBM_MODBUS_RTU_FUN_NUM_ERR 4 //功能码错误功能码原则上小于128超过就会到这里。
#define ECBM_MODBUS_RTU_FUN_NUM_VOID 5 //功能码不存在,主要原因是本机不支持该功能码。
#define ECBM_MODBUS_RTU_ADDRH 6 //读取地址高8位。
#define ECBM_MODBUS_RTU_ADDRL 7 //读取地址低8位。
#define ECBM_MODBUS_RTU_DATA_COUNTH 8 //读取数据或者个数的高8位。
#define ECBM_MODBUS_RTU_DATA_COUNTL 9 //读取数据或者个数的低8位。
#define ECBM_MODBUS_RTU_COUNT_ERR 10 //读取个数错误。
#define ECBM_MODBUS_RTU_CRCH 11 //读取CRC的高8位。
#define ECBM_MODBUS_RTU_CRCL 12 //读取CRC的低8位。
#define ECBM_MODBUS_RTU_CRC_ERR 13 //CRC错误当接收到的数据的CRC和传输的CRC不一致时会报错。
#define ECBM_MODBUS_RTU_DO 14 //处理态,在该状态下处理数据。
#define ECBM_MODBUS_RTU_DATAH 15 //读取地址高8位。
#define ECBM_MODBUS_RTU_DATAL 16 //读取地址低8位。
#define ECBM_MODBUS_RTU_BYTE_COUNT 17 //读取字节数量。
#define ECBM_MODBUS_RTU_BYTE_ERR 18 //读取字节数量对应不上。
/*-------------------------------------返回值定义----------------------------------*/
#define ECBM_MODBUS_RTU_OK 0 //正常。
#define ECBM_MODBUS_RTU_BIT_ADDR_ERR 1 //比特位地址错误。
#define ECBM_MODBUS_RTU_REG_ADDR_ERR 2 //寄存器地址错误。
#define ECBM_MODBUS_RTU_IO_ADDR_ERR 3 //IO地址错误。
/*-------------------------------220709增加使能脚控制功能----------------------------*/
#define ECBM_MODBUS_READ 0 //读使能
#define ECBM_MODBUS_WRITE 1 //写使能
/*--------------------------------------变量定义-----------------------------------*/
extern emu16 fast_type ecbm_modbus_rtu_crc; //初始化CRC变量各位为1。
extern emu8 fast_type ecbm_modbus_rtu_status; //状态机使用的变量。
extern emu8 fast_type ecbm_modbus_rtu_id; //本机的设备ID。
extern emu8 fast_type ecbm_modbus_rtu_fun_code; //功能码。
extern emu8 fast_type ecbm_modbus_rtu_fun_err_num; //异常码。
extern emu16 fast_type ecbm_modbus_rtu_address; //数据地址。
extern emu16 fast_type ecbm_modbus_rtu_data_count; //数据/个数。
extern emu16 fast_type ecbm_modbus_rtu_crc_buf; //CRC缓存。
extern emu16 fast_type ecbm_modbus_rtu_timeout; //超时计算。
extern emu16 fast_type ecbm_modbus_rtu_uart_crc; //CRC计算缓存。
extern emu8 fast_type ecbm_modbus_rtu_cmd_count; //指令缓存计数。
extern emu8 fast_type ecbm_modbus_rtu_broadcast_en; //广播模式。
#if ECBM_MODBUS_RTU_BIT_BUF_EN
extern emu8 large_type ecbm_modbus_rtu_bit_buf[ECBM_MODBUS_RTU_BIT_BUF_SIZE];//比特线圈存放变量。
#endif
#if ECBM_MODBUS_RTU_REG_BUF_EN
extern emu16 large_type ecbm_modbus_rtu_reg_buf[ECBM_MODBUS_RTU_REG_BUF_SIZE];//寄存器存放变量。
#endif
#if ECBM_MODBUS_RTU_CMD10_EN
extern emu16 large_type ecbm_modbus_rtu_cmd_buf[ECBM_MODBUS_RTU_BUF_SIZE];//指令缓存。
#endif
/*--------------------------------------函数定义-----------------------------------*/
/**
* @brief 设置485芯片的读写IO脚,220709
*
* @param dat 电平状态
*/
extern void ecbm_modbus_rtu_set_io(emu8 dat);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_set_data
描 述:发送数据函数。需要用户移植。
输 入:
dat 要发送的数据
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_set_data(emu8 dat);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_get_data
描 述:数据接收函数。需要用户移植。
输 入:无
输 出:无
返回值:接收到的数据。
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
-------------------------------------------------------*/
extern emu8 ecbm_modbus_rtu_get_data(void);
/*-------------------------------------------------------
函数名ECBM_MODBUS_RTU_TIMEOUT_RUN
描 述:走时宏定义,为了加快运行速度,所以做成了宏定义。需要用户移植。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-10
修改记录:
-------------------------------------------------------*/
#define ECBM_MODBUS_RTU_TIMEOUT_RUN() \
do{\
if(ecbm_modbus_rtu_timeout>0)/*不为0的时候才增加。*/\
ecbm_modbus_rtu_timeout++;/*时间往上加。*/\
if(ecbm_modbus_rtu_timeout>ECBM_MODBUS_RTU_TIME_MAX){/*超时的时候,*/\
ecbm_modbus_rtu_status=ECBM_MODBUS_RTU_READY;/*回到就绪态。*/\
ecbm_modbus_rtu_timeout=0;/*同时关闭时间累积。*/\
}\
}while(0)
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_crc16
描 述CRC16计算函数。
输 入:
buf 需要计算CRC的数据
输 出:
ecbm_modbus_rtu_crc 计算的结果
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-10
修改记录:
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_crc16(emu8 buf);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_check_fun_num
描 述:检测功能码函数。
输 入:
fun_num 功能码
输 出:无
返回值功能码存在返回本身不存在返回0x80+功能码。
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
-------------------------------------------------------*/
extern emu8 ecbm_modbus_rtu_check_fun_num(emu8 fun_num);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_read_io_bit
描 述:读输入离散量函数。
输 入:
addr 离散量地址
输 出:
dat 比特值
返回值:读取结果
创建者:奈特
调用例程:无
创建日期2021-03-15
修改记录:
-------------------------------------------------------*/
extern emu8 ecbm_modbus_cmd_read_io_bit(emu16 addr,emu8 * dat);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_read_io_reg
描 述:读输入寄存器函数。
输 入:
addr 寄存器地址
输 出:
dat 寄存器值
返回值:读取结果
创建者:奈特
调用例程:无
创建日期2021-03-15
修改记录:
-------------------------------------------------------*/
extern emu8 ecbm_modbus_cmd_read_io_reg(emu16 addr,emu16 * dat);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_write_bit
描 述:写比特数据函数。
输 入:
addr 比特位地址
dat 比特值
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-16取消返回值优化运行速度。
-------------------------------------------------------*/
extern void ecbm_modbus_cmd_write_bit(emu16 addr,emu8 dat);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_read_bit
描 述:读比特数据函数。
输 入:
addr 比特位地址
输 出:
dat 比特值
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-16取消返回值优化运行速度。
-------------------------------------------------------*/
extern void ecbm_modbus_cmd_read_bit(emu16 addr,emu8 * dat);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_write_reg
描 述:写寄存器数据函数。
输 入:
addr 寄存器地址
dat 寄存器值
输 出:无
返回值:读取结果
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-16取消返回值优化运行速度。
-------------------------------------------------------*/
extern void ecbm_modbus_cmd_write_reg(emu16 addr,emu16 dat);
/*-------------------------------------------------------
函数名ecbm_modbus_cmd_read_reg
描 述:读寄存器函数。
输 入:
addr 寄存器地址
输 出:
dat 寄存器值
返回值:读取结果
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-16取消返回值优化运行速度。
-------------------------------------------------------*/
extern void ecbm_modbus_cmd_read_reg(emu16 addr,emu16 * dat);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x01
描 述1号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验。
2021-03-15修改了异常码02的触发条件。
2021-03-16新增异常码04的触发条件。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_cmd_0x01(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x02
描 述2号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-15
修改记录:
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_cmd_0x02(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x03
描 述3号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_cmd_0x03(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x05
描 述5号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验。
2021-03-16新增异常码04的触发条件优化了部分执行代码。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_cmd_0x05(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x06
描 述6号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_cmd_0x06(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_cmd_0x10
描 述16号功能码处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-12
修改记录:
-------------------------------------------------------*/
void ecbm_modbus_rtu_cmd_0x10(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_receive
描 述modbus接收处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验。
2021-03-12新增0x10指令相关处理,新增0xff广播地址。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_receive(void);
/*-------------------------------------------------------
函数名ecbm_modbus_rtu_run
描 述modbus主循环处理函数。
输 入:无
输 出:无
返回值:无
创建者:奈特
调用例程:无
创建日期2021-03-05
修改记录:
2021-03-09新增CRC校验相关代码。
2021-03-12新增0x10指令相关处理。
-------------------------------------------------------*/
extern void ecbm_modbus_rtu_run(void);
#endif