2024-08-20 11:02:49 +08:00
|
|
|
|
#include "b6x.h"
|
|
|
|
|
#include "drvs.h"
|
|
|
|
|
#include "dbg.h"
|
|
|
|
|
#include "sftmr.h"
|
|
|
|
|
|
|
|
|
|
#include "app_modbus.h"
|
|
|
|
|
#include "CRCxx.h"
|
|
|
|
|
#include "app_ota.h"
|
|
|
|
|
#include "sys_config.h"
|
|
|
|
|
|
|
|
|
|
#define ModbusCRC16_EN 0
|
|
|
|
|
|
|
|
|
|
#define DEBUG_MODBUS 1
|
|
|
|
|
|
|
|
|
|
#if DEBUG_MODBUS
|
|
|
|
|
#define DEBUG(fmt, args...) debug("[modbus]" fmt, ##args)
|
|
|
|
|
#else
|
|
|
|
|
#define DEBUG(fmt, args...)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define MODBUS_MAX_LEN 64
|
|
|
|
|
|
|
|
|
|
static uint8_t MODBUS_ReceCount =0;
|
|
|
|
|
static uint8_t MODBUS_Rece_BUF[MODBUS_MAX_LEN];
|
|
|
|
|
static uint8_t MODBUS_Sent_BUF[MODBUS_MAX_LEN];
|
|
|
|
|
|
|
|
|
|
// 需掉电不丢失数据12*2字节//40027-40030//40514-40520
|
|
|
|
|
uint16_t MODBUS_FLASH_DAT[12] ={
|
|
|
|
|
[0]=1,//MODBUS从机地址
|
|
|
|
|
[1]=1,// 出厂模式状态 //写入 1,设备将重置进入出厂模式
|
|
|
|
|
[2]=100,// 固件版本
|
|
|
|
|
[3]=1,// 硬件版本
|
|
|
|
|
|
|
|
|
|
[4]=30,//30*100ms // 代码过期时间
|
|
|
|
|
[5]=30,//30*100ms// 输出继电器的关闭时间
|
|
|
|
|
[6]=100,//100*100ms// Led 激活时间
|
|
|
|
|
[7]=10,//10*10ms// 蜂鸣器激活时间
|
|
|
|
|
|
|
|
|
|
[8]=0x001f,// Led 键盘颜色//RGB565 格式
|
|
|
|
|
[9]=0xf800,// Led Mifare 读卡颜色//RGB565 格式
|
|
|
|
|
[10]=0x07E0,// Led 状态灯0颜色//RGB565 格式
|
|
|
|
|
[11]=0x07ff,// Led 状态灯1颜色//RGB565 格式
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool app_modbus_CheckData(uint8_t *dat , uint8_t len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//发送数据并计算CRC
|
|
|
|
|
void app_modbus_SendData(uint8_t *dat ,uint8_t len){
|
|
|
|
|
if(0 == len){
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
uint16_t CRC16=crc16_modbus(dat ,len);
|
|
|
|
|
|
|
|
|
|
dat[len++] =CRC16 & 0xff;// CRC低字节在前
|
|
|
|
|
dat[len++] =CRC16 >> 8;
|
|
|
|
|
|
|
|
|
|
uart_send(UART1_PORT ,len ,dat);
|
|
|
|
|
while(len){//清空发送数据缓存
|
|
|
|
|
dat[--len] =0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 01 功能码
|
|
|
|
|
void FunctionalCode_01(uint16_t reg_addr){//ID寄存器地址//返回7字节
|
|
|
|
|
uint8_t len_count=0;
|
|
|
|
|
|
|
|
|
|
// DEBUG("FuncCode_01:0x%X\n",reg_addr);
|
|
|
|
|
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =MODBUS_ADDR;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =0x01;
|
|
|
|
|
switch(reg_addr){
|
|
|
|
|
case 0x0005:
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
len_count =0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 03 功能码 # 读 - 保持寄存器
|
|
|
|
|
// 06 功能码 # 写 - 单个寄存器
|
|
|
|
|
void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_num){//寄存器地址//返回8字节或15字节
|
|
|
|
|
|
|
|
|
|
uint8_t len_count=0;
|
|
|
|
|
|
|
|
|
|
// DEBUG("FuncCode_03:0x%X\n",reg_addr);
|
|
|
|
|
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =MODBUS_ADDR;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =CMDCode;
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
len_count++;
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =(reg_addr >> 8) & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =reg_addr & 0xff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(reg_addr){
|
|
|
|
|
case 0x0001: // 设备的 Modbus地址
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =0x00;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =MODBUS_ADDR & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
MODBUS_ADDR =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =MODBUS_ADDR >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =MODBUS_ADDR & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
{ // 0x0101-0x0002
|
|
|
|
|
case 0x0101: // // 读写系统配置
|
|
|
|
|
if(CMDCode == 0x03){ // # 读 - 保持寄存器
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}else if(CMDCode == 0x06){ // # 写 - 单个寄存器
|
|
|
|
|
write_cfg(&sys_conf); //保存写入配置
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0102: // 管理员模式油门极限寄存器(Unit:%)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Manager_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Manager_sLim & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Manager_sLim =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Manager_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Manager_sLim & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0103: // 游客模式油门极限寄存器(Unit:%)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Tourist_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Tourist_sLim & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Tourist_sLim =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Tourist_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Tourist_sLim & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0104: // 减速油门极限寄存器(Unit:%)(自动减速时油门极限)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_sLim & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Speed_Cut_sLim =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_sLim >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_sLim & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0105: // 刹车距离寄存器(前进)(Unit:mm)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Brake_DLimit =reg_val_num;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0106: // 减速距离寄存器(Unit:mm)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Speed_Cut_DLimit =reg_val_num;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0107: // 刹车距离极限寄存器(后退)(Unit:mm)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit_B >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit_B & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Brake_DLimit_B =reg_val_num;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit_B >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Brake_DLimit_B & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0108: // 减速距离极限寄存器(Unit:mm)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit_B >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit_B & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_conf.Speed_Cut_DLimit_B =reg_val_num;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit_B >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_conf.Speed_Cut_DLimit_B & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{ // 0x0109-0x010D
|
|
|
|
|
case 0x0201: //PAD模式寄存器
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_sta.Pmode =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0202: //系统模式寄存器(只读)
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Smode >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.Smode & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
// sys_sta.Smode =reg_val_num & 0xff;
|
|
|
|
|
// MODBUS_Sent_BUF[len_count++] =sys_sta.Smode >> 8;
|
|
|
|
|
// MODBUS_Sent_BUF[len_count++] =sys_sta.Smode & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0203: //输入输出状态寄存器
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.IO_STA >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.IO_STA & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){// 输入输出状态寄存器可写
|
|
|
|
|
// sys_sta.I_STA =reg_val_num & 0xff;//输入寄存器不可写
|
|
|
|
|
sys_sta.IO_STA =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.IO_STA >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.IO_STA & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0204: //输入状态寄存器
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.I_STA >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.I_STA & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
// sys_sta.I_STA =reg_val_num & 0xff;//输入寄存器不可写
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.I_STA >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.I_STA & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0205: //0 关闭12V输出//1 开启12V输出
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.O_12V >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.O_12V & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
sys_sta.O_12V =reg_val_num & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.O_12V >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =sys_sta.O_12V & 0xff;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{ // 0x0201-0x0203
|
|
|
|
|
case 0x0301: // 电池状态
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0302: // 电池电压
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Voltage >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Voltage & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0303: // 电池电量
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0304: // 剩余充电时间
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Remain_Time >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Remain_Time & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x0305: // 雷达距离信息
|
|
|
|
|
if(CMDCode == 0x03){
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =radar_data.distance >> 8;
|
|
|
|
|
MODBUS_Sent_BUF[len_count++] =radar_data.distance & 0xff;
|
|
|
|
|
MODBUS_Sent_BUF[2] +=2;
|
|
|
|
|
if(0 == --reg_val_num){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(CMDCode == 0x06){
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
len_count =0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
app_modbus_SendData(MODBUS_Sent_BUF ,len_count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool app_modbus_CheckData(uint8_t *dat , uint8_t len){//检查数据
|
|
|
|
|
uint16_t CRC16;
|
|
|
|
|
|
|
|
|
|
// DEBUG("len:%d\n",len);
|
|
|
|
|
if(len > 8){
|
|
|
|
|
len = 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(dat[0] ==MODBUS_ADDR){//验证从机地址
|
|
|
|
|
CRC16 =crc16_modbus(dat ,len-2);//计算CRC
|
|
|
|
|
DEBUG("CRC16:0x%X\n",CRC16);
|
|
|
|
|
#if !ModbusCRC16_EN
|
|
|
|
|
CRC16 =((uint16_t)(dat[len-1])<<8) + dat[len-2];
|
|
|
|
|
#endif
|
|
|
|
|
if(CRC16 ==((uint16_t)(dat[len-1])<<8) + dat[len-2]){//CRC低字节在前
|
|
|
|
|
switch(dat[1]){//功能码
|
|
|
|
|
case 0x01:// 功能码 01
|
|
|
|
|
FunctionalCode_01(((uint16_t)dat[2]<<8) + dat[3]);
|
|
|
|
|
break;
|
|
|
|
|
case 0x03:// 功能码03 # 读 - 保持寄存器
|
|
|
|
|
FunctionalCode_03_06(0x03,((uint16_t)dat[2]<<8) + dat[3] ,((uint16_t)dat[4]<<8) + dat[5]);
|
|
|
|
|
// FunctionalCode_03(((uint16_t)dat[2]<<8) + dat[3] ,((uint16_t)dat[4]<<8) + dat[5]);
|
|
|
|
|
break;
|
|
|
|
|
case 0x06:// 功能码06 # 写 - 单个寄存器
|
|
|
|
|
FunctionalCode_03_06(0x06,((uint16_t)dat[2]<<8) + dat[3] ,((uint16_t)dat[4]<<8) + dat[5]);
|
|
|
|
|
// FunctionalCode_06(((uint16_t)dat[2]<<8) + dat[3] ,((uint16_t)dat[4]<<8) + dat[5]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !defined(Modbus_RBUF_SIZE)
|
|
|
|
|
#define Modbus_RBUF_SIZE 0x100
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define Modbus_FIFO_RXTL 8
|
|
|
|
|
|
|
|
|
|
#undef RBUF_SIZE
|
|
|
|
|
#define RBUF_SIZE Modbus_RBUF_SIZE
|
|
|
|
|
#include "rbuf.h"
|
|
|
|
|
|
|
|
|
|
/// RingBuffer for modbus1
|
|
|
|
|
static rbuf_t ModbusRbRx;
|
|
|
|
|
|
|
|
|
|
void app_modbus_Rb_Reset(void){
|
|
|
|
|
rbuf_init(&ModbusRbRx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t app_modbus_Rb_Len(void){
|
|
|
|
|
return rbuf_len(&ModbusRbRx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t app_modbus_Rb_Read(uint8_t *buff, uint16_t max){
|
|
|
|
|
return rbuf_gets(&ModbusRbRx, buff, max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define Rx_timeout _MS(20) // 接收超时时间
|
|
|
|
|
static tmr_tk_t Rx_timeout_id=0;
|
|
|
|
|
|
|
|
|
|
static tmr_tk_t Rx_timeout_handler(tmr_id_t id){
|
|
|
|
|
(void)(id);
|
|
|
|
|
|
|
|
|
|
MODBUS_ReceCount = app_modbus_Rb_Read(&MODBUS_Rece_BUF[0], MODBUS_MAX_LEN);
|
|
|
|
|
|
|
|
|
|
DEBUG("RC:%d\n",MODBUS_ReceCount);
|
2024-08-20 14:05:50 +08:00
|
|
|
|
|
|
|
|
|
app_PAD_CheckData(MODBUS_Rece_BUF, MODBUS_ReceCount);//PAD数据解析
|
2024-08-20 11:02:49 +08:00
|
|
|
|
|
|
|
|
|
app_modbus_CheckData(MODBUS_Rece_BUF, MODBUS_ReceCount);//modbus数据解析
|
2024-08-20 14:05:50 +08:00
|
|
|
|
|
2024-08-20 11:02:49 +08:00
|
|
|
|
app_otas_rxd(MODBUS_ReceCount ,MODBUS_Rece_BUF);//otas数据解析
|
2024-08-20 14:05:50 +08:00
|
|
|
|
|
2024-08-20 11:02:49 +08:00
|
|
|
|
while(MODBUS_ReceCount){
|
|
|
|
|
MODBUS_Rece_BUF[--MODBUS_ReceCount] = 0;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void app_modbus_Init(uint32_t baudrate, uint8_t io_tx, uint8_t io_rx){
|
|
|
|
|
|
|
|
|
|
uart_init(UART1_PORT, io_tx, io_rx);
|
|
|
|
|
uart_conf(UART1_PORT, BRR_BAUD(baudrate), LCR_BITS(8, 1, none));
|
|
|
|
|
|
|
|
|
|
// 使能FIFO 接收8字节时触发、使能超过20字节触发超时中断
|
|
|
|
|
uart_fctl(UART1_PORT, FCR_FIFOEN_BIT | FCR_RXTL_8BYTE,
|
|
|
|
|
20/*bits_rto*/, UART_IR_RXRD_BIT | UART_IR_RTO_BIT);
|
|
|
|
|
|
|
|
|
|
// empty buffer
|
|
|
|
|
rbuf_init(&ModbusRbRx);
|
|
|
|
|
|
|
|
|
|
DEBUG("MODBUS init success!\n");
|
|
|
|
|
|
|
|
|
|
NVIC_EnableIRQ(UART1_IRQn);
|
|
|
|
|
Rx_timeout_id =sftmr_start(10, Rx_timeout_handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UART1_IRQHandler(void){
|
|
|
|
|
uint32_t state = UART1->IFM.Word; // UART1->RIF.Word;
|
|
|
|
|
|
|
|
|
|
if (state & 0x01){ //(BIT_RXRD)
|
|
|
|
|
UART1->IDR.RXRD = 1; // Disable RXRD Interrupt
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < Modbus_FIFO_RXTL; i++){
|
|
|
|
|
rbuf_putc(&ModbusRbRx, UART1->RBR);
|
|
|
|
|
}
|
|
|
|
|
sftmr_Refresh(Rx_timeout_id ,Rx_timeout);
|
|
|
|
|
UART1->ICR.RXRD = 1; // Clear RXRD Interrupt Flag
|
|
|
|
|
UART1->IER.RXRD = 1; // Enable RXRD Interrupt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state & 0x10){ //(BIT_RTO)
|
|
|
|
|
|
|
|
|
|
UART1->IDR.RTO = 1; // Disable RTO Interrupt
|
|
|
|
|
|
|
|
|
|
while (UART1->SR.RFNE){
|
|
|
|
|
rbuf_putc(&ModbusRbRx, UART1->RBR);
|
|
|
|
|
if(0 ==UART1->SR.RFNE){
|
|
|
|
|
sftmr_Refresh(Rx_timeout_id ,Rx_timeout);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UART1->ICR.RTO = 1; // Clear RTO Interrupt Flag
|
|
|
|
|
UART1->IER.RTO = 1; // Enable RTO Interrupt
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|