C语言表示类似Long.MAX_VALUE和Long.MIN_VALUE

#include <limits.h>
long maxValue = LONG_MAX;
long minValue = LONG_MIN;

class PositionController: def init(self, dt=0.004, ): “”“初始化位置控制器 运行周期在20US之下 参数: dt: 控制周期(秒), 默认为4ms “”” # 控制参数 self.dt = dt # 控制周期(4ms) self.pos_kp = 1.2 # 位置环比例系数 self.pos_ip = 0.5 # 位置环积分系数 self.pos_dp = 0.5 # 位置环微分系数 self.pos_integral = 0 # self.pos_prev_error = 0 self.reached_target = False # 是否到达目标位置 self.position_tolerance = 1 # 0.01 位置死区 self.velocity_tolerance = 1 # 速度死区 self.dec_mode = False # 减速中 self.stopSignal = False # 停止信号 self.stopEdge = False # 停止信号上升 self.max_accel = 100000 # 最大加速度(mm/s²) self.max_decel = 100000 # 最大减速度(mm/s²) self.stop_decel = 100000 # 最大减速度(mm/s²) self.max_vel = 500.0 # 最大速度(mm/s) self.decModeMaxVel = self.max_vel # 停止衰减速度 self.change_vels = deque(maxlen=5) self.change_poss = deque(maxlen=5) self.reached = 0 # 到达周期 # 系统状态 self.actual_pos = 0 # 实际位置(mm) self.actual_vel = 0.0 # 实际速度(mm/s) self.target_pos = 0.0 # 目标位置(mm) self.target_vel = 0.0 # 目标速度(mm/s) self.lock = threading.Lock() def update_target(self, new_pos, new_vel=None): """动态更新目标位置速度 参数: new_pos: 新的目标位置(mm) new_vel: 新的目标速度(mm/s), 可选 """ # 之前的位置误差 ord_error = abs(self.target_pos - self.actual_pos) # 新的目标位置 self.target_pos = new_pos # 新的位置误差 new_error = abs(self.target_pos - self.actual_pos) if new_error != 0: self.reached = 0 # 误差变大 if new_error > ord_error: self.dec_mode = False # 重新判断减速距离 if self.stopSignal is False: # 停止信号刷新 self.stopEdge = False # 重新计算停止距离 if new_vel is not None: self.max_vel = abs(new_vel) def position_control(self): """位置环控制计算""" # 计算位置误差 pos_error = self.target_pos - self.actual_pos # PID计算 self.pos_integral += pos_error * self.dt derivative = (pos_error - self.pos_prev_error) / self.dt # 控制输出 output = (self.pos_kp * pos_error + self.pos_ip * self.pos_integral + self.pos_dp * derivative) # 更新状态 # self.pos_prev_error = pos_error # 别用 超调严重,响应慢 return output def calculate_acceleration(self, vel_cmd): """计算加速度命令""" # 计算速度误差 vel_error = vel_cmd - self.actual_vel # 计算停止距离 if self.dec_mode is False: stop_distance = self.actual_vel ** 2 / (2 * self.max_decel) pos_error = self.target_pos - self.actual_pos # 到减速模式,减到底 在 误差<减速距离 or 误差< 位置死区*3 进入减速模式 if abs(pos_error) <= abs(stop_distance) or (abs(pos_error) <self.velocity_tolerance): self.dec_mode = True if self.stopSignal: # 停止阶段 if self.stopEdge is False: self.stopEdge = True stop_distance = self.actual_vel ** 2 / (2 * self.max_decel) self.target_pos = self.actual_pos + stop_distance decel = -np.sign(self.actual_vel) * self.stop_decel self.dec_mode = True return decel # 进入减速阶段 elif self.dec_mode: # abs(pos_error) <= abs(stop_distance) and abs(pos_error) > 0.001: # 减速阶段: 应用最大减速度 decel = -np.sign(self.actual_vel) * self.max_decel return decel else: # 加速/匀速阶段 self.dec_mode = False # 计算所需加速度 accel = vel_error / self.dt # 衰减速度 self.decModeMaxVel = self.max_vel # 加速度限幅 if accel > 0: return min(accel, self.max_accel) else: return max(accel, -self.max_decel) # return max(accel, -self.max_accel) def update_state(self, accel): """更新系统状态""" # 更新速度 self.actual_vel += accel * self.dt # 位置误差计算 # pos_error = self.target_pos - self.actual_pos # pos_done = abs(pos_error) <= self.position_tolerance # vel_done = abs(self.actual_vel) <= self.velocity_tolerance if self.dec_mode: # 减速模式 # 速度限幅 last_maxvel = self.decModeMaxVel # 速度限幅 self.decModeMaxVel = min(abs(self.actual_vel), abs(self.max_vel), self.decModeMaxVel) if last_maxvel == self.decModeMaxVel: # 等幅振荡 # 等幅振荡 等比例衰减 self.decModeMaxVel *= 0.1 # 更新最小速度 self.actual_vel = np.clip(self.actual_vel, -self.decModeMaxVel, self.decModeMaxVel) # 更新位置 # arange_dec = int(self.actual_vel * self.dt) arange_dec = int(self.actual_vel * self.dt) self.actual_pos += arange_dec # # 在死区范围内 pos_done = abs(self.target_pos - self.actual_pos) <= self.position_tolerance pos_done2 = abs(self.target_pos - self.actual_pos) <= self.position_tolerance * 2.2 vel_done = abs(self.actual_vel) <= self.velocity_tolerance # if vel_done and pos_done2: done = pos_done or vel_done return done, arange_dec, self.actual_vel, pos_done2, vel_done else: # 更新位置 # 速度限幅 self.actual_vel = np.clip(self.actual_vel, -self.max_vel, self.max_vel) # 更新位置 arange_dec = int(self.actual_vel * self.dt) self.actual_pos += arange_dec # self.actual_vel * self.dt # # 在死区范围内 pos_done = abs(self.target_pos - self.actual_pos) <= self.position_tolerance pos_done2 = abs(self.target_pos - self.actual_pos) <= self.position_tolerance*2.2 vel_done = abs(self.actual_vel) <= self.velocity_tolerance done = pos_done and vel_done return done, arange_dec, self.actual_vel, pos_done2, vel_done def run_cycle(self, current_time=None): """运行一个控制周期""" # 位置环控制 vel_cmd = self.position_control() # 计算加速度 accel = self.calculate_acceleration(vel_cmd) # 更新系统状态 旧控制代码返回的是增量,为保持一致 done, arange_dec, actual_vel, pos_done, vel_done = self.update_state(accel) if self.reached == 1: if pos_done: # 在位置死区,直接变成目标位置 arange = int(self.target_pos - self.actual_pos) arange_dec += arange self.actual_pos += arange return True, arange_dec, actual_vel if done: self.reached = 1 if not pos_done: # 不在二倍死区内,多更新一个死区距离 # 更新位置 arange_pos = self.position_tolerance * (1.5 if self.target_pos - self.actual_pos > 0 else -1.5) arange_dec += arange_pos self.actual_pos += arange_pos # self.actual_vel * self.dt return False, arange_dec, actual_vel # 记录数据 # self.time_log = np.append(self.time_log, current_time) # self.target_pos_log = np.append(self.target_pos_log, self.target_pos) # self.actual_pos_log = np.append(self.actual_pos_log, self.actual_pos) # self.target_vel_log = np.append(self.target_vel_log, self.max_vel) # # self.target_vel_log = np.append(self.target_vel_log, self.dec) # self.actual_vel_log = np.append(self.actual_vel_log, self.actual_vel) # yield arange_dec # def visualize(self): # """可视化位置速度曲线""" # plt.figure(figsize=(12, 8)) # # # 位置曲线 # plt.subplot(2, 1, 1) # plt.plot(self.time_log, self.target_pos_log, 'r-', label='目标位置') # plt.plot(self.time_log, self.actual_pos_log, 'b-', label='实际位置') # plt.xlabel('时间 (s)') # plt.ylabel('位置 (mm)') # plt.title('位置跟踪曲线') # plt.legend() # plt.grid(True) # # # 速度曲线 # plt.subplot(2, 1, 2) # plt.plot(self.time_log, self.target_vel_log, 'r-', label='目标速度') # plt.plot(self.time_log, self.actual_vel_log, 'g-', label='实际速度') # plt.xlabel('时间 (s)') # plt.ylabel('速度 (mm/s)') # plt.title('速度跟踪曲线') # plt.legend() # plt.grid(True) # # plt.tight_layout() # plt.show() 转成c 注意 操作的是dec 所有的位置 速度 全是整数
12-19
from collections import deque import numpy as np import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei', 'sans-serif'] rcParams['axes.unicode_minus'] = False class VelocityController: def __init__(self, dt=0.004): """初始化速度控制器 25US之下 参数: dt: 控制周期(秒), 默认为4ms """ # 控制参数 self.dt = 0.004 # 控制周期(4ms) # 速度环 self.vel_kp = 18.5 # 速度环比例系数 self.vel_ip = 1 # 速度环积分系数 self.vel_dp = 0.20 # 速度环微分系数 self.vel_kf = 1.2 # 前馈补偿(基于目标变化率) self.prev_target = 0 # 前馈输入 self.vel_integral = 0 # 累计误差 self.vel_prev_error = 0 # # 阻尼 self.init_vel = 0 # 用于计算阈值 阈值=|实际速度 - 目标速度| / |初始速度 - 目标速度| self.overshoot_threshold = 0.49 # 过冲检测阈值 (5%) (数值越小,代表越接近目标,最大是1) self.adaptive_factor = 0.45 # 自适应调节因子 在这个比例进行衰减,直到衰减系数到0 self.adaptive = False # 自适应 开关 # 加速类型 self.accel_type = "T" # "PID" # or "T" # 衰减极致 self.vel_min_kp = 6 # 最小的 比例系数,如果衰减到0 将代表没有误差, self.vel_max_dp = 1 # 最大的 微分系数, 太大滞后严重 # 积分直接 = 0 (过大的比例已经会引起超调,再加入积分将更严重) self.pid_param = {"p": self.vel_kp, "i": self.vel_ip, "d": self.vel_dp, "f": self.vel_kf, "adaptive_factor": self.adaptive_factor} # self.vel_kp = 1.2 # 速度环比例系数 self.max_accel = 10000000 # 最大加速度(mm/s²) self.max_jerk = 200000000 # 最大加加速度 (m/s³) self.stop_decel = 7000000.0 # 最大减速度(mm/s²) 受限于最大加速度 # 停止(追踪速度到0) self.__stopSignal = False # 停止信号 self.stop_start_vel = 0.0 self.stop_phase = "NORMAL" # 减速阶段: NORMAL, DECEL, CRAWL self.crawl_threshold = 0 # 进入低速爬行模式的速度阈值(m/s) self.position_tolerance = 0.1 # 位置死区 在速度环中无用 self.velocity_tolerance = 0.1 # 速度死区 self.stopModeMaxVel = 0 self.stopMaxVel_factor = 0.5 self.safety_distance = 2000 # 安全停止距离 # 系统状态 self.actual_pos = 0 # 实际位置(mm) self.actual_vel = 0.0 # 实际速度(mm/s) self.target_vel = 0.0 # 目标速度(mm/s) self.actual_acc = 0.0 # 实际加速度 # self.lock = threading.Lock() # 数据记录 self.time_log = np.array([], dtype=np.float32) self.target_pos_log = np.array([], dtype=np.float32) self.actual_pos_log = np.array([], dtype=np.float32) self.target_vel_log = np.array([], dtype=np.float32) self.actual_vel_log = np.array([], dtype=np.float32) self.actual_acc_log = np.array([], dtype=np.float32) self.actual_overshoot_log = np.array([], dtype=np.float32) self.actual_overshoot2_log = np.array([], dtype=np.float32) @property def stopSignal(self): return self.__stopSignal @stopSignal.setter def stopSignal(self, value): if (not self.__stopSignal) and value: self.target_vel = 0 # 将目标速度设为0 print("将目标速度设为0") self.reset_pid() self.stop_phase = "NORMAL" self.stop_start_vel = abs(self.actual_vel) # 计算需要的减速度 (v² = u² + 2as, 设s=0.5m为安全距离) if self.stop_start_vel > 0: required_decel = int((self.stop_start_vel ** 2) / (2 * self.safety_distance)) self.stop_decel = min(self.max_accel, required_decel) self.stopModeMaxVel = abs(self.actual_vel) # 衰减最大速度 else: self.stop_decel = self.max_accel self.__stopSignal = value def update_target(self, new_vel=None, **kwargs): """动态更新目标位置速度 参数: new_vel: 新的目标速度(mm/s), 可选 """ # 目标发生变化 if self.target_vel != new_vel: # 记录初始速度 self.init_vel = self.actual_vel # 重置pid self.reset_pid() if new_vel == 0: self.stopSignal = True else: self.stopSignal = False self.target_vel = new_vel def set_pid(self, p, i, d, f, adaptive_factor): """ 速度环 pid 参数 :param p: 速度环比例系数 :param i: 速度环积分系数 :param d: 速度环微分系数 :param f: 前馈补偿(基于目标变化率) :param adaptive_factor: 自适应调节因子 :return: """ self.vel_kp = p # 速度环比例系数 self.vel_ip = i # 速度环积分系数 self.vel_dp = d # 速度环微分系数 self.vel_kf = f # 前馈补偿(基于目标变化率) self.adaptive_factor = adaptive_factor # 自适应调节因子 self.pid_param = {"p": p, "i": i, "d": d, "f": f, "adaptive_factor": adaptive_factor} def reset_pid(self): """ 由于自动增加阻尼,会修改参数,每次更新速度会重置参数。 :return: """ self.vel_kp = self.pid_param["p"] # 速度环比例系数 self.vel_ip = self.pid_param["i"] # 速度环积分系数 self.vel_dp = self.pid_param["d"] # 速度环微分系数 self.vel_kf = self.pid_param["f"] # 前馈补偿(基于目标变化率) self.adaptive_factor = self.pid_param["adaptive_factor"] # 自适应调节因子 def detect_overshoot(self, current_vel, target_vel): """检测速度过冲并调整参数""" if abs(target_vel) > 0.1 or self.adaptive_factor > 0: # 忽略零速度附近 overshoot_ratio = abs(current_vel - target_vel) / abs(target_vel - self.init_vel) if overshoot_ratio < self.overshoot_threshold: # self.overshoot_count += 1 # 自适应调整增益 if self.adaptive_factor < 0.01: self.adaptive_factor = 0 else: self.adaptive_factor *= 0.9 # 减小10% # 临时增加阻尼 self.vel_dp *= (1 + self.adaptive_factor) # 增加微分增益(Kd)以抑制超调 self.vel_kp *= (1 - self.adaptive_factor) # 减小比例增益(Kp)降低响应速度 self.vel_dp = min(self.vel_dp, self.vel_max_dp) self.vel_kp = max(self.vel_kp, self.vel_min_kp) self.vel_ip = 0 # 积分项直到0 return True return False def run_cycle(self, current_time=None): """运行一个控制周期""" # 硬件中的控制算法(模拟行为) if self.__stopSignal: # 停止模式 - T型减速 # print("T") current_vel = abs(self.actual_vel) # self.actual_vel -= np.sign(self.actual_vel) * self.stop_decel * self.dt # self.actual_vel = np.clip(self.actual_vel, -self.max_accel, self.max_accel) # 阶段1: 正常减速 (匀减速) if self.stop_phase == "NORMAL": # 应用固定减速度 self.actual_vel -= np.sign(self.actual_vel) * self.stop_decel * self.dt # 检查是否进入低速爬行阶段 if current_vel <= self.crawl_threshold: self.stop_phase = "CRAWL" # 阶段2: 低速爬行 (线性减速到零) elif self.stop_phase == "CRAWL": # 计算线性衰减因子 decay_factor = current_vel / self.crawl_threshold # 应用线性减速 # direction = 1 if self.actual_vel > 0 else -1 self.actual_vel -= np.sign(self.actual_vel) * self.stop_decel * decay_factor * self.dt # 振荡衰减 if abs(self.actual_vel) > 0.1: last_maxvel = self.stopModeMaxVel self.stopModeMaxVel = min(abs(self.actual_vel), self.stopModeMaxVel) if last_maxvel == self.stopModeMaxVel: # 等幅振荡 # 等幅振荡 等比例衰减 self.stopModeMaxVel *= self.stopMaxVel_factor # 0.5 self.actual_vel = np.clip(self.actual_vel, -self.stopModeMaxVel, self.stopModeMaxVel) if abs(self.actual_vel) <= self.velocity_tolerance: self.actual_acc = (self.actual_vel - current_vel) / self.dt self.actual_vel = 0.0 self.stop_phase = "NORMAL" arange_dec = int(self.actual_vel * self.dt) self.actual_pos += arange_dec # return abs(self.actual_vel) <= self.velocity_tolerance, arange_dec, self.actual_vel elif self.accel_type == "PID": vel_error = self.target_vel - self.actual_vel # 检测过冲并自适应调整 if self.adaptive: self.detect_overshoot(self.actual_vel, self.target_vel) self.vel_integral += vel_error * self.dt derivative = (vel_error - self.vel_prev_error) / self.dt # 控制输出 output = (self.vel_kp * vel_error + self.vel_ip * self.vel_integral + self.vel_dp * derivative) self.vel_prev_error = vel_error # 前馈通道, 应变目标速度的突变 feedforward = self.vel_kf * (self.target_vel - self.prev_target) / self.dt output += feedforward # 模拟加速度生成(带加加速度限制) # 加速度限制 desired_accel = np.clip(output, -self.max_accel, self.max_accel) # 加速度变化率限制(确保加速度连续) jerk = (desired_accel - self.actual_acc) / self.dt jerk = np.clip(jerk, -self.max_jerk, self.max_jerk) self.actual_acc += jerk * self.dt # 更新速度位置 self.actual_vel += self.actual_acc * self.dt self.prev_target = self.target_vel # 更新 位置 arange_dec = int(self.actual_vel * self.dt) self.actual_pos += arange_dec return False, arange_dec, self.actual_vel elif self.accel_type == "T": # T型加速控制策略 vel_error = self.target_vel - self.actual_vel # 确定加速度方向大小 if abs(vel_error) > 0: # 确定加速度方向(加速或减速) accel_direction = 1 if vel_error > 0 else -1 # 计算所需加速度(使用最大加速度/减速度) required_accel = abs(vel_error) / self.dt target_accel = min(required_accel, self.max_accel # if accel_direction > 0 else self.max_decel ) * accel_direction # 更新加速度(带平滑过渡) if abs(self.actual_acc) < abs(target_accel): self.actual_acc += accel_direction * self.max_jerk * self.dt self.actual_acc = np.clip(self.actual_acc, -self.max_accel, self.max_accel) else: self.actual_acc = target_accel # 更新速度 self.actual_vel += self.actual_acc * self.dt # 防止超调 if (vel_error > 0 and self.actual_vel > self.target_vel) or \ (vel_error < 0 and self.actual_vel < self.target_vel): self.actual_vel = self.target_vel self.actual_acc = 0.0 else: self.actual_acc = 0 self.jerk = 0 # 更新 位置 arange_dec = int(self.actual_vel * self.dt) self.actual_pos += arange_dec # return False, arange_dec, self.actual_vel pass else: pass # 更新 位置 # arange_dec = self.actual_vel * self.dt # self.actual_pos += arange_dec # return True, 0, 0 # return False, arange_dec, self.actual_vel # 死区 # if abs(self.target_vel - self.actual_vel) < self.velocity_tolerance: # return True, arange_dec, self.actual_vel # else: # return False, arange_dec, self.actual_vel # return arange_dec, self.actual_vel # 记录数据 self.time_log = np.append(self.time_log, current_time) self.target_pos_log = np.append(self.target_pos_log, self.actual_pos) # self.target_pos) self.actual_pos_log = np.append(self.actual_pos_log, self.actual_acc) self.target_vel_log = np.append(self.target_vel_log, self.target_vel) # self.max_vel) # self.target_vel_log = np.append(self.target_vel_log, self.dec) self.actual_vel_log = np.append(self.actual_vel_log, self.actual_vel) self.actual_acc_log = np.append( self.actual_acc_log, self.actual_acc) # # yield arange_dec # # return arange_dec # def visualize(self): # return """可视化位置速度曲线""" plt.figure(figsize=(12, 8)) # 位置曲线 plt.subplot(3, 1, 1) plt.plot(self.time_log, self.target_pos_log, 'r-', label='实际位置') plt.plot(self.time_log, self.actual_pos_log, 'b-', label='实际位置') plt.xlabel('时间 (s)') plt.ylabel('位置 (mm)') plt.title('位置跟踪曲线') plt.legend() plt.grid(True) plt.subplot(3, 1, 2) plt.plot(self.time_log, self.actual_acc_log, 'r-', label='实际加速度') # plt.plot(self.time_log, self.actual_pos_log, 'g-', label='实际加速度') plt.xlabel('时间 (s)') plt.ylabel('加速度 (mm/s2)') plt.title('加速度曲线') plt.legend() plt.grid(True) # 速度曲线 plt.subplot(3, 1, 3) plt.plot(self.time_log, self.target_vel_log, 'r-', label='目标速度') plt.plot(self.time_log, self.actual_vel_log, 'g-', label='实际速度') plt.xlabel('时间 (s)') plt.ylabel('速度 (mm/s)') plt.title('速度跟踪曲线') plt.legend() plt.grid(True) plt.tight_layout() plt.show() if __name__ == "__main__": VelCon = VelocityController(0.001) dt = VelCon.dt # VelCon.update_target(new_vel=60 * 61000) ctyle = int(5 / dt) for i in range(ctyle): t_s = i * dt if t_s<1: VelCon.update_target(new_vel=60 * 61000) elif t_s < 2: # VelCon.stopSignal = True # VelCon.update_target(new_vel=0) VelCon.update_target(new_vel=-60 * 61000) elif t_s<3: # VelCon.stopSignal = True # VelCon.stopSignal = False # print("d") VelCon.update_target(new_vel=0) # print(VelCon.target_vel) VelCon.run_cycle(t_s) # if t_s>=3: # print(VelCon.target_vel) VelCon.visualize() 转成C 控制的是dec 所有参数类型设置成int64_t (原本 位置是int32_t 不需要担心溢出),定点数运算的缩放因子 设置成1000
最新发布
12-27
import tkinter as tk from tkinter import scrolledtext, ttk, messagebox import os import logging from datetime import datetime import sys import locale import traceback # 在文件开头添加编码设置 if sys.platform == "win32": # 设置Windows系统的标准输出编码 sys.stdout.reconfigure(encoding='utf-8') # Python 3.7+ # 设置系统区域设置 locale.setlocale(locale.LC_ALL, '') # 对于Python 3.7以下版本 if sys.version_info < (3, 7): import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') class SimpleCLexer: def __init__(self): self.tokens = [] def tokenize(self, input_str): tokens = [] pos = 0 line = 1 column = 0 length = len(input_str) # 定义C语言的关键词类型 keywords = { 'void', 'int', 'char', 'float', 'double', 'short', 'long', 'signed', 'unsigned', 'struct', 'union', 'enum', 'typedef', 'static', 'extern', 'auto', 'register', 'const', 'volatile', 'return', 'if', 'else', 'switch', 'case', 'default', 'for', 'while', 'do', 'break', 'continue', 'goto', 'sizeof' } # 扩展类型别名识别 types = {'U1', 'U2', 'U4', 'S1', 'S2', 'S4', 'BOOL', 'BYTE', 'WORD', 'DWORD'} while pos < length: char = input_str[pos] # 跳过空白字符 if char in ' \t': pos += 1 column += 1 continue # 处理换行 if char == '\n': line += 1 column = 0 pos += 1 continue # 处理单行注释 if pos + 1 < length and input_str[pos:pos+2] == '//': end = input_str.find('\n', pos) if end == -1: end = length pos = end continue # 处理多行注释 if pos + 1 < length and input_str[pos:pos+2] == '/*': end = input_str.find('*/', pos + 2) if end == -1: end = length else: end += 2 pos = end continue # 处理标识符 if char.isalpha() or char == '_': start = pos pos += 1 while pos < length and (input_str[pos].isalnum() or input_str[pos] == '_'): pos += 1 token_text = input_str[start:pos] token_type = 'IDENTIFIER' # 检查是否为关键字或类型 if token_text in keywords: token_type = 'KEYWORD' elif token_text in types: token_type = 'TYPE' tokens.append({ 'type': token_type, 'text': token_text, 'line': line, 'column': column }) column += (pos - start) continue # 处理数字 if char.isdigit(): start = pos pos += 1 while pos < length and (input_str[pos].isdigit() or input_str[pos] in '.xXabcdefABCDEF'): pos += 1 tokens.append({ 'type': 'NUMBER', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理字符串 if char == '"': start = pos pos += 1 while pos < length and input_str[pos] != '"': if input_str[pos] == '\\' and pos + 1 < length: pos += 2 else: pos += 1 if pos < length and input_str[pos] == '"': pos += 1 tokens.append({ 'type': 'STRING', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理字符 if char == "'": start = pos pos += 1 while pos < length and input_str[pos] != "'": if input_str[pos] == '\\' and pos + 1 < length: pos += 2 else: pos += 1 if pos < length and input_str[pos] == "'": pos += 1 tokens.append({ 'type': 'CHAR', 'text': input_str[start:pos], 'line': line, 'column': column }) column += (pos - start) continue # 处理运算符标点符号 operators = { '(', ')', '{', '}', '[', ']', ';', ',', '.', '->', '++', '--', '&', '*', '+', '-', '~', '!', '/', '%', '<<', '>>', '<', '>', '<=', '>=', '==', '!=', '^', '|', '&&', '||', '?', ':', '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '&=', '^=', '|=', ',' } # 尝试匹配最长的运算符 matched = False for op_len in range(3, 0, -1): if pos + op_len <= length and input_str[pos:pos+op_len] in operators: tokens.append({ 'type': 'OPERATOR', 'text': input_str[pos:pos+op_len], 'line': line, 'column': column }) pos += op_len column += op_len matched = True break if matched: continue # 无法识别的字符 tokens.append({ 'type': 'UNKNOWN', 'text': char, 'line': line, 'column': column }) pos += 1 column += 1 return tokens class FunctionAnalyzer: def __init__(self): self.function_name = "" self.parameters = set() self.local_vars = [] self.global_vars = [] self.function_calls = [] self.current_function = None self.in_function = False self.in_function_body = False self.brace_depth = 0 self.variable_declarations = {} self.control_structures = {"if", "for", "while", "switch", "return", "else"} self.macro_definitions = set() self.recorded_globals = set() self.storage_classes = {"static", "extern", "auto", "register"} # 定义允许的类型(修复错误) self.basic_types = {'void', 'int', 'char', 'float', 'double', 'short', 'long', 'signed', 'unsigned'} self.type_aliases = {"U1", "U2", "U4", "S1", "S2", "S4"} self.allowed_types = self.basic_types | self.type_aliases self.inside_expression = False # 添加新状态跟踪 self.debug_level = 3 # 1=基本, 2=详细, 3=非常详细 self.all_variables = [] # 记录所有找到的变量 self.expression_depth = 0 # 表达式嵌套深度 self.in_expression = False # 是否在表达式中 # 添加函数前缀识别 self.function_prefixes = { "vd_": "void", "u1_": "U1", "u2_": "U2", "u4_": "U4", "s1_": "S1", "s2_": "S2", "s4_": "S4" } def log(self, message, level="info", debug_level=1): """增强版日志方法""" if level == "debug" and debug_level > self.debug_level: return prefix = { 1: "[DEBUG1]", 2: "[DEBUG2]", 3: "[DEBUG3]" }.get(debug_level, "[DEBUG]") full_message = f"{prefix} {message}" if self.log_to_gui: self.log_to_gui(full_message, level) else: print(f"{level.upper()}: {full_message}") def analyze(self, tokens): self.tokens = tokens self.pos = 0 self.current_line = 0 self.inside_expression = False self.brace_depth = 0 # 添加大括号深度跟踪 # 第一步:识别宏定义 self._identify_macros() self.log("开始分析函数体", "debug", 1) while self.pos < len(self.tokens): token = self.tokens[self.pos] self.current_line = token['line'] # 更新表达式状态 if token['text'] in {'(', '{', '['}: self.expression_depth += 1 self.in_expression = self.expression_depth > 0 elif token['text'] in {')', '}', ']'}: self.expression_depth = max(0, self.expression_depth - 1) self.in_expression = self.expression_depth > 0 # 跟踪大括号深度 if token['text'] == '{': self.brace_depth += 1 if self.in_function and self.brace_depth == 1: self.in_function_body = True self.log(f"进入函数体,brace_depth={self.brace_depth}", "debug", 2) elif token['text'] == '}': self.brace_depth -= 1 if self.brace_depth == 0 and self.in_function: self.in_function = False self.in_function_body = False self.log("离开函数体", "debug", 2) # 检测函数定义 if token['text'] in self.storage_classes or token['text'] in self.allowed_types: if self._is_function_definition(): self._handle_function_definition() continue # 检测变量声明 - 只在函数体内处理 #if self.in_function_body and token['text'] in self.allowed_types: # 检查下一个token是否是标识符(变量名) if self.pos + 1 < len(self.tokens) and \ self.tokens[self.pos + 1]['type'] == 'IDENTIFIER': # 确保不是函数返回类型 if self.pos + 2 < len(self.tokens) and self.tokens[self.pos + 2]['text'] != '(': self._handle_variable_declaration() continue # 检测函数调用 if token['type'] == 'IDENTIFIER' and self.pos + 1 < len(self.tokens): next_token = self.tokens[self.pos + 1] if next_token['text'] == '(': self._handle_function_call() continue # 检测变量使用 if token['type'] == 'IDENTIFIER': self._handle_identifier_use(token) self.pos += 1 self.log("分析完成", "debug", 1) return self def _identify_macros(self): """识别宏定义(全大写标识符或带参数的宏)""" for i, token in enumerate(self.tokens): if token['type'] == 'IDENTIFIER' and token['text'].isupper(): # 检查是否是带参数的宏 if i + 1 < len(self.tokens) and self.tokens[i+1]['text'] == '(': self.macro_definitions.add(token['text']) else: self.macro_definitions.add(token['text']) def _is_function_definition(self): pos = self.pos storage_class = None # 检测存储类说明符 if self.tokens[pos]['text'] in self.storage_classes: storage_class = self.tokens[pos]['text'] pos += 1 # 检测返回类型 if pos >= len(self.tokens) or self.tokens[pos]['text'] not in self.allowed_types: return False return_type = self.tokens[pos]['text'] pos += 1 # 处理指针声明 if pos < len(self.tokens) and self.tokens[pos]['text'] == '*': return_type += '*' pos += 1 # 检测函数名 if pos < len(self.tokens) and self.tokens[pos]['type'] == 'IDENTIFIER': func_name = self.tokens[pos]['text'] pos += 1 else: return False # 检测参数列表开头的'(' if pos < len(self.tokens) and self.tokens[pos]['text'] == '(': pos += 1 else: return False # 参数列表必须包含至少一个参数或void if pos < len(self.tokens) and self.tokens[pos]['text'] == ')': # 空参数列表 pos += 1 else: # 非空参数列表 depth = 1 while pos < len(self.tokens) and depth > 0: if self.tokens[pos]['text'] == '(': depth += 1 elif self.tokens[pos]['text'] == ')': depth -= 1 pos += 1 # 检测函数体开头的'{' (允许最多5个token的间隔) found_brace = False for i in range(min(5, len(self.tokens) - pos)): if self.tokens[pos + i]['text'] == '{': found_brace = True break return found_brace def _handle_function_definition(self): self.log(">>> 进入函数定义处理", "debug", 2) start_pos = self.pos storage_class = None # 处理存储类说明符 if self.tokens[self.pos]['text'] in self.storage_classes: storage_class = self.tokens[self.pos]['text'] self.pos += 1 # 获取返回类型 return_type = self.tokens[self.pos]['text'] self.pos += 1 # 处理指针声明 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*': return_type += '*' self.pos += 1 # 获取函数名 if self.pos < len(self.tokens) and self.tokens[self.pos]['type'] == 'IDENTIFIER': func_name = self.tokens[self.pos]['text'] self.pos += 1 else: self.pos = start_pos return # 记录函数名 self.function_name = func_name self.current_function = func_name self.variable_declarations[func_name] = True # 跳过 '(' if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '(': self.pos += 1 # 提取参数 params = [] current_param = [] depth = 1 param_line = self.current_line while self.pos < len(self.tokens) and depth > 0: token = self.tokens[self.pos] if token['text'] == '(': depth += 1 elif token['text'] == ')': depth -= 1 if depth == 0: break elif token['text'] == ',' and depth == 1: # 提取参数类型名称 param_type, param_name = self._extract_param_info(current_param) if param_type and param_name: params.append({ 'type': param_type, 'name': param_name, 'line': param_line }) self.variable_declarations[param_name] = True current_param = [] param_line = token['line'] self.pos += 1 continue current_param.append(token) self.pos += 1 # 处理最后一个参数 if current_param: param_type, param_name = self._extract_param_info(current_param) if param_type and param_name: params.append({ 'type': param_type, 'name': param_name, 'line': param_line }) self.variable_declarations[param_name] = True # 记录参数 self.parameters = params param_names = [p['name'] for p in params] if params else [] # 查找函数体开头的'{' while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] != '{': self.pos += 1 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '{': self.in_function = True self.in_function_body = False self.brace_depth = 0 self.pos += 1 # 添加函数名到变量列表 func_info = { 'name': func_name, 'type': 'function', 'line': self.current_line, 'scope': 'function' } self.all_variables.append(func_info) self.log(f"添加函数: {func_name}", "info") self.log("<<< 退出函数定义处理", "debug", 2) return param_names def _extract_param_info(self, tokens): """从参数token列表中提取类型名称""" param_type = [] param_name = None for token in tokens: if token['type'] in ('KEYWORD', 'TYPE') or token['text'] in self.allowed_types: param_type.append(token['text']) elif token['type'] == 'IDENTIFIER' and not token['text'].isupper(): param_name = token['text'] return ' '.join(param_type), param_name def _handle_variable_declaration(self): self.log(">>> 进入变量声明处理", "debug", 2) start_pos = self.pos current_line = self.current_line # 获取变量类型 var_type = self.tokens[self.pos]['text'] self.log(f"检测到变量声明类型: {var_type}", "debug") self.pos += 1 # 处理指针声明 pointer_level = 0 while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*': var_type += '*' pointer_level += 1 self.pos += 1 var_names = [] in_array_declaration = False in_initialization = False paren_depth = 0 # 处理变量名声明 while self.pos < len(self.tokens): token = self.tokens[self.pos] self.log(f"处理变量声明token: {token['text']} (类型:{token['type']})", "debug", 3) # 结束声明 if token['text'] == ';' and paren_depth == 0 and not in_initialization and not in_array_declaration: self.pos += 1 break # 标识符 - 变量名 if token['type'] == 'IDENTIFIER' and not token['text'].isupper() and not in_initialization: var_name = token['text'] # 跳过宏定义 if var_name not in self.macro_definitions: self.log(f"找到变量名: {var_name}", "debug") var_names.append(var_name) self.variable_declarations[var_name] = True self.pos += 1 continue # 逗号 - 多个变量声明 elif token['text'] == ',' and paren_depth == 0 and not in_initialization and not in_array_declaration: self.pos += 1 # 处理指针声明 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*': var_type += '*' self.pos += 1 continue # 结束声明 elif token['text'] == ';': self.pos += 1 break # 数组声明 - 跳过数组大小 elif token['text'] == '[': self.pos += 1 depth = 1 while self.pos < len(self.tokens) and depth > 0: t = self.tokens[self.pos] if t['text'] == '[': depth += 1 elif t['text'] == ']': depth -= 1 self.pos += 1 continue # 初始化 - 跳过初始化表达式 elif token['text'] == '=': self.log("跳过初始化表达式", "debug") self.pos += 1 depth = 0 while self.pos < len(self.tokens): t = self.tokens[self.pos] if t['text'] in {'(', '['}: depth += 1 elif t['text'] in {')', ']'}: depth -= 1 elif t['text'] in {',', ';'} and depth == 0: break self.pos += 1 continue # 类型转换 - 跳过 elif token['text'] == '(' and self.pos + 1 < len(self.tokens): # 尝试识别类型转换 next_token = self.tokens[self.pos + 1] if next_token['text'] in self.allowed_types: self.log(f"跳过类型转换: ({next_token['text']})", "debug") # 跳过类型转换 self.pos += 2 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')': self.pos += 1 continue # 其他情况 self.log(f"跳过token: {token['text']} (类型: {token['type']})", "debug") self.pos += 1 # 添加到局部变量 (跳过宏定义参数) for var_name in var_names: # 检查是否在参数列表中 is_param = any(param['name'] == var_name for param in self.parameters) if not is_param and var_name not in self.macro_definitions: var_info = { 'type': var_type, 'name': var_name, 'line': current_line, 'scope': 'local' } self.local_vars.append(var_info) self.all_variables.append(var_info) self.variable_declarations[var_name] = True self.log(f"添加局部变量: {var_type} {var_name} (行:{current_line})", "info") # 如果未找到变量名,回退位置 if not var_names: self.pos = start_pos self.log("未找到变量名,回退位置", "debug") self.log("<<< 退出变量声明处理", "debug", 2) def _handle_identifier_use(self, token): var_name = token['text'] line = token['line'] self.log(f"处理标识符: {var_name} (行:{line})", "debug", 3) # 跳过已处理的标识符 skip_conditions = ( var_name in self.variable_declarations, var_name in self.macro_definitions, var_name in self.control_structures, var_name in self.type_aliases, var_name in self.recorded_globals, any(call['name'] == var_name for call in self.function_calls), # 添加:跳过函数名 var_name == self.function_name ) if any(skip_conditions): self.log(f"跳过标识符: {var_name} (已处理)", "debug", 3) return # 添加到全局变量 var_info = { 'name': var_name, 'line': line, 'scope': 'global' } self.global_vars.append(var_info) self.all_variables.append(var_info) self.recorded_globals.add(var_name) self.log(f"添加全局变量: {var_name} (行:{line})", "info") def _infer_variable_type(self, var_name): """根据命名约定推断变量类型""" if var_name.startswith("u1_"): return "U1" if var_name.startswith("u2_"): return "U2" if var_name.startswith("u4_"): return "U4" if var_name.startswith("s1_"): return "S1" if var_name.startswith("s2_"): return "S2" if var_name.startswith("s4_"): return "S4" if var_name.startswith("vd_"): return "void" return "unknown" def _handle_function_call(self): self.log(">>> 进入函数调用处理", "debug", 2) # 提取函数名 func_name = self.tokens[self.pos]['text'] line = self.current_line self.pos += 2 # 跳过函数名 '(' # 提取参数 params = [] depth = 1 current_param = [] # 保存所有参数token用于后续分析 param_tokens = [] while self.pos < len(self.tokens) and depth > 0: token = self.tokens[self.pos] if token['text'] == '(': depth += 1 elif token['text'] == ')': depth -= 1 if depth == 0: break elif token['text'] == ',' and depth == 1: params.append(''.join([t['text'] for t in current_param]).strip()) param_tokens.extend(current_param) # 保存token current_param = [] self.pos += 1 continue current_param.append(token) self.pos += 1 if current_param: params.append(''.join([t['text'] for t in current_param]).strip()) param_tokens.extend(current_param) # 保存token # 跳过 ')' 如果还在范围内 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')': self.pos += 1 # 处理参数中的标识符 for token in param_tokens: if token['type'] == 'IDENTIFIER' and not token['text'].isupper(): self._handle_identifier_use(token) # 确定返回类型 return_type = "unknown" if func_name.startswith("vd_"): return_type = "void" elif func_name.startswith(("u1_", "u2_", "u4_", "s1_", "s2_", "s4_")): prefix = func_name.split("_")[0] return_type = prefix.upper() # 添加到函数调用列表 func_info = { 'name': func_name, 'return_type': return_type, 'type': "function_call", 'params': ", ".join(params), # 将参数列表转换为字符串,用逗号分隔 'line': line, 'scope': 'call' } self.function_calls.append(func_info) self.all_variables.append(func_info) self.log(f"添加函数调用: {func_name} (行:{line})", "info") self.log("<<< 退出函数调用处理", "debug", 2) class FunctionParserApp: def __init__(self, root): self.root = root self.root.title("C语言函数解析器 (内置解析器版)") self.root.geometry("900x700") self.setup_logging() # 创建输入区域 input_frame = tk.LabelFrame(root, text="输入C语言函数体", padx=5, pady=5) input_frame.pack(fill="both", expand=True, padx=10, pady=5) self.input_text = scrolledtext.ScrolledText(input_frame, width=100, height=20) self.input_text.pack(fill="both", expand=True, padx=5, pady=5) # 按钮区域 btn_frame = tk.Frame(root) btn_frame.pack(fill="x", padx=10, pady=5) # 解析按钮 parse_btn = tk.Button(btn_frame, text="解析函数", command=self.parse_function, bg="#4CAF50", fg="white") parse_btn.pack(side="left", padx=5) # 保存日志按钮 save_log_btn = tk.Button(btn_frame, text="保存日志", command=self.save_logs) save_log_btn.pack(side="right", padx=5) # 进度条 self.progress = ttk.Progressbar(btn_frame, orient="horizontal", length=300, mode="determinate") self.progress.pack(side="left", padx=10, fill="x", expand=True) # 创建输出区域 output_frame = tk.LabelFrame(root, text="解析结果", padx=5, pady=5) output_frame.pack(fill="both", expand=True, padx=10, pady=5) self.output_text = scrolledtext.ScrolledText(output_frame, width=100, height=15) self.output_text.pack(fill="both", expand=True, padx=5, pady=5) self.output_text.config(state=tk.DISABLED) # 日志区域 log_frame = tk.LabelFrame(root, text="日志信息", padx=5, pady=5) log_frame.pack(fill="both", expand=True, padx=10, pady=5) self.log_text = scrolledtext.ScrolledText(log_frame, width=100, height=8) self.log_text.pack(fill="both", expand=True, padx=5, pady=5) self.log_text.config(state=tk.DISABLED) # 添加调试级别控制 debug_frame = tk.Frame(btn_frame) debug_frame.pack(side="left", padx=10) tk.Label(debug_frame, text="调试级别:").pack(side="left") self.debug_level = tk.IntVar(value=1) ttk.Combobox(debug_frame, textvariable=self.debug_level, values=[1, 2, 3], width=3).pack(side="left") # 添加示例按钮 example_btn = tk.Button(btn_frame, text="加载示例", command=self.load_example) example_btn.pack(side="right", padx=5) # 示例函数体 self.example_code = """static void Diag21_PID_C9(U1 u1_a_num) { U1 u1_t_cmplt; U1 u1_t_cnt; if((U1)DIAG_CNT_ZERO == u1_t_swrstcnt) /* Determine if a software reset is in progress */ { for(u1_t_cnt = (U1)DIAG21_ZERO; u1_t_cnt < (U1)DIAG21_PIDC9_FLAG; u1_t_cnt ++) { u1_t_cmplt = u1_g_InspSoftwareVersion(u4_g_cmd, &u4_g_data, (U1)TRUE); } vd_s_Diag21_U2ToU1(u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG); } else { /* Do Nothing */ } }""" def setup_logging(self): """配置日志系统""" self.log_filename = f"parser_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log" # 创建文件处理器并指定UTF-8编码 file_handler = logging.FileHandler(self.log_filename, encoding='utf-8') file_handler.setLevel(logging.INFO) file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")) # 配置根日志器 root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) root_logger.addHandler(file_handler) # 添加控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) console_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")) root_logger.addHandler(console_handler) logging.info("应用程序启动") def log_to_gui(self, message, level="info"): """将日志信息显示在GUI中""" try: self.log_text.config(state=tk.NORMAL) timestamp = datetime.now().strftime("%H:%M:%S") # 确保消息是字符串 if not isinstance(message, str): message = str(message) self.log_text.insert(tk.END, f"[{timestamp}] {message}\n") self.log_text.see(tk.END) self.log_text.config(state=tk.DISABLED) if level == "info": logging.info(message) elif level == "warning": logging.warning(message) elif level == "error": logging.error(message) except Exception as e: # 如果GUI日志失败,回退到控制台日志 print(f"GUI日志错误: {str(e)}") logging.error(f"GUI日志错误: {str(e)}") def save_logs(self): """保存日志到文件""" try: log_content = self.log_text.get("1.0", tk.END) filename = f"saved_log_{datetime.now().strftime('%H%M%S')}.txt" # 使用UTF-8编码保存文件 with open(filename, "w", encoding='utf-8') as f: f.write(log_content) self.log_to_gui(f"日志已保存到: {filename}", "info") messagebox.showinfo("保存成功", f"日志已保存到:\n{filename}") except Exception as e: self.log_to_gui(f"保存日志失败: {str(e)}", "error") messagebox.showerror("保存失败", f"无法保存日志:\n{str(e)}") def update_progress(self, value): """更新进度条""" self.progress['value'] = value self.root.update_idletasks() def load_example(self): """加载示例函数体""" self.input_text.delete(1.0, tk.END) self.input_text.insert(tk.END, self.example_code) self.log_to_gui("已加载示例函数体") def parse_function(self): """使用内置解析器解析C语言函数体""" try: code = self.input_text.get(1.0, tk.END) if not code.strip(): self.log_to_gui("错误: 没有输入函数体", "error") messagebox.showerror("错误", "请输入要解析的C语言函数体") return self.log_to_gui("开始解析函数体...") self.output_text.config(state=tk.NORMAL) self.output_text.delete(1.0, tk.END) self.update_progress(0) # 使用内置词法分析器 self.log_to_gui("执行词法分析...") lexer = SimpleCLexer() tokens = lexer.tokenize(code) self.update_progress(30) # 使用内置语法分析器 self.log_to_gui("执行语法分析...") analyzer = FunctionAnalyzer() analyzer.log_to_gui = self.log_to_gui analyzer.debug_level = self.debug_level.get() # 设置调试级别 analyzer.analyze(tokens) # 显示结果 self.log_to_gui("生成解析报告...") self.display_results( analyzer.local_vars, analyzer.global_vars, analyzer.function_calls, analyzer.function_name, analyzer.parameters ) self.update_progress(100) self.output_text.config(state=tk.DISABLED) self.log_to_gui("解析完成!") messagebox.showinfo("完成", "函数体解析成功完成!") except Exception as e: self.log_to_gui(f"解析错误: {str(e)}", "error") self.log_to_gui(f"错误详情: {traceback.format_exc()}", "error") messagebox.showerror("解析错误", f"发生错误:\n{str(e)}") self.update_progress(0) def display_results(self, local_vars, global_vars, function_calls, func_name, func_params): """增强版结果显示,包含所有变量信息""" # 显示函数签名 if func_name: self.output_text.insert(tk.END, "=== 函数签名 ===\n") self.output_text.insert(tk.END, f"函数名: {func_name}\n") if func_params: param_list = [] for param in func_params: param_list.append(f"{param['type']} {param['name']}") # 添加参数到变量列表 param_info = { 'name': param['name'], 'type': param['type'], 'line': param['line'], 'scope': 'parameter' } self.log_to_gui(f"添加参数: {param['type']} {param['name']} (行:{param['line']})") self.output_text.insert(tk.END, f"参数: {', '.join(param_list)}\n\n") else: self.output_text.insert(tk.END, "参数: 无\n\n") else: self.output_text.insert(tk.END, "=== 函数签名 ===\n") self.output_text.insert(tk.END, "警告: 无法识别函数签名\n\n") self.log_to_gui("无法识别函数签名", "warning") # 显示所有找到的变量 self.output_text.insert(tk.END, "=== 所有变量分析 ===\n") self.output_text.insert(tk.END, "类型 | 名称 | 作用域 | 行号\n") self.output_text.insert(tk.END, "-" * 50 + "\n") # 先显示参数 for param in func_params: self.output_text.insert(tk.END, f"参数 | {param['name']} | 参数 | {param['line']}\n") # 显示局部变量 for var in local_vars: self.output_text.insert(tk.END, f"变量 | {var['name']} | 局部 | {var['line']}\n") # 显示全局变量 for var in global_vars: self.output_text.insert(tk.END, f"变量 | {var['name']} | 全局 | {var['line']}\n") # 显示函数调用 for func in function_calls: self.output_text.insert(tk.END, f"函数调用 | {func['name']} | 调用 | {func['line']}\n") self.output_text.insert(tk.END, "\n") # 显示局部变量 if local_vars: self.output_text.insert(tk.END, "=== 局部变量 ===\n") for var in local_vars: self.output_text.insert(tk.END, f"{var['type']} {var['name']} (行号: {var['line']})\n") self.log_to_gui(f"找到局部变量: {var['type']} {var['name']}") self.output_text.insert(tk.END, "\n") else: self.output_text.insert(tk.END, "未找到局部变量\n\n") self.log_to_gui("未找到局部变量", "warning") # 显示使用的全局变量 if global_vars: self.output_text.insert(tk.END, "=== 使用的全局变量 ===\n") for var in global_vars: self.output_text.insert(tk.END, f"{var['name']} (行号: {var['line']})\n") self.log_to_gui(f"找到全局变量: {var['name']}") self.output_text.insert(tk.END, "\n") else: self.output_text.insert(tk.END, "未使用全局变量\n\n") self.log_to_gui("未使用全局变量", "warning") # 显示函数调用 if function_calls: self.output_text.insert(tk.END, "=== 函数调用 ===\n") for func in function_calls: self.output_text.insert(tk.END, f"函数名: {func['name']} (行号: {func['line']})\n") self.output_text.insert(tk.END, f"返回类型: {func['return_type']}\n") self.output_text.insert(tk.END, f"参数: {func['params']}\n") self.output_text.insert(tk.END, "-" * 50 + "\n") self.log_to_gui(f"找到函数调用: {func['name']}") else: self.output_text.insert(tk.END, "未调用任何函数\n\n") self.log_to_gui("未调用任何函数", "warning") # 添加变量统计 self.output_text.insert(tk.END, "=== 变量统计 ===\n") self.output_text.insert(tk.END, f"参数数量: {len(func_params)}\n") self.output_text.insert(tk.END, f"局部变量数量: {len(local_vars)}\n") self.output_text.insert(tk.END, f"全局变量数量: {len(global_vars)}\n") self.output_text.insert(tk.END, f"函数调用数量: {len(function_calls)}\n") self.output_text.insert(tk.END, f"总变量数量: {len(func_params) + len(local_vars) + len(global_vars) + len(function_calls)}\n") self.output_text.insert(tk.END, "\n") if __name__ == "__main__": root = tk.Tk() app = FunctionParserApp(root) root.mainloop() 这个代码能够正确执行通常的代码分析逻辑,并且返回的结果正确,但是代码太多了,请删除一些没有用的代码,没有使用的功能。 1、使界面更加美观 2、使之能够处理结构体,不要将结构体识别为变量
07-18
//#include "LPC177x_8x.h" // Device header #include "includes.h" /* ADS1232 配置增益 #define GainX1 GAIN0_0;GAIN1_0; #define GainX2 GAIN0_1;GAIN1_0; #define GainX64 GAIN0_0;GAIN1_1; 目前使用 #define GainX128 GAIN0_1;GAIN1_1; */ uint16_t trace_s; uint8_t FirstUp; uint32_t liu_wen; uint8_t liu_count; uint8_t big_count; ADS1232 ADS_coef; extern struct COM com4; extern struct BALANCEDATA BaData; INT8U Amountadding[10];//质量变化数组//ly20241104 #define WINDOW_SIZE_MAX 20 #define WINDOW_LEISURE_SIZE 12 #define WINDOW_FILL 4 #define WINDOW_CARDINAL 6 #define ADCa_t 1 #define FIXED_VALUE (214748364.8 / 2 / 5) #define SAMPLE_RATE_HZ 80 // ADC采样率 #define FILTER_CUTOFF_HZ 15 // 滤波器截止频率 #define M_PI 3.14159265358979323846f // 单精度浮点版本 // 平滑窗口结构体定义 typedef struct { uint32_t buffer[WINDOW_SIZE_MAX]; // 窗口数据存储 uint8_t index; // 当前写入位置 uint32_t sum; // 窗口数据总 uint32_t mean; // 窗口数据取极值平均值 uint32_t window_number; // 窗口个数 uint8_t WINDOW_SIZE; // 采集个数 uint8_t EXCLUDE_NUM; // 去除最大/最小值数量 } SlidingFilter; SlidingFilter SF; SlidingFilter SF_W; // IIR滤波器结构体 typedef struct { float alpha; float prev_output; } IIR_Filter; IIR_Filter weight_filter; // IIR滤波器实例 IIR_Filter fill_filter; // 观测维度定义为1(仅AD测量值) #define OBS_DIM 1 // 状态维度:假设我们估计的是重量值及其变化率(速度) #define STATE_DIM 2 // 强跟踪滤波器结构体 typedef struct { double x[STATE_DIM]; // 状态向量 [位置, 速度] double P[STATE_DIM][STATE_DIM]; // 状态协方差矩阵 double Q[STATE_DIM][STATE_DIM]; // 过程噪声协方差 double R; // 观测噪声协方差 double F[STATE_DIM][STATE_DIM]; // 状态转移矩阵 double H[OBS_DIM][STATE_DIM]; // 观测矩阵 } STKF; STKF filter; // 初始化滤波器 void stkf_init(STKF *filter, double init_pos, double init_vel, double q_pos, double q_vel, double r) { int i, j, k; // 初始状态 filter->x[0] = init_pos; filter->x[1] = init_vel; // 状态协方差初始化 for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = 0.0; } } filter->P[0][0] = 1e-1; filter->P[1][1] = 1e-3; // 过程噪声协方差 Q filter->Q[0][0] = q_pos; filter->Q[1][1] = q_vel; // 观测噪声协方差 R filter->R = r; // 状态转移矩阵 F(假设匀速模型) filter->F[0][0] = 1.0; filter->F[0][1] = 0.05; // dt = 1 filter->F[1][0] = 0.0; filter->F[1][1] = 1.0; // 观测矩阵 H filter->H[0][0] = 1.0; filter->H[0][1] = 0.0; } // 预测步骤 void stkf_predict(STKF *filter) { int i, j, k; double x_new[STATE_DIM]; double P_new[STATE_DIM][STATE_DIM]; if(ADS_coef.Valve_change)//开/关阀瞬间 { filter->Q[0][0] = 2000; filter->Q[1][1] = 50e6; filter->R = 36000; } else if(Filling.State == FUELING)//加注中 { // 过程噪声协方差 Q filter->Q[0][0] = 10000; filter->Q[1][1] = 50e6; // 观测噪声协方差 R //filter->R = 160000; } else // 空闲状态 { filter->Q[0][0] = 1000; filter->Q[1][1] = 1e6; //filter->R = 1000; } // x = F * x x_new[0] = filter->F[0][0] * filter->x[0] + filter->F[0][1] * filter->x[1]; x_new[1] = filter->F[1][0] * filter->x[0] + filter->F[1][1] * filter->x[1]; // P = F * P * F^T + Q double FP[STATE_DIM][STATE_DIM]; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { FP[i][j] = 0.0; for (k = 0; k < STATE_DIM; k++) { FP[i][j] += filter->F[i][k] * filter->P[k][j]; } } } for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { P_new[i][j] = 0.0; for (k = 0; k < STATE_DIM; k++) { P_new[i][j] += FP[i][k] * filter->F[j][k]; // F * P * F^T } P_new[i][j] += filter->Q[i][j]; } } // 更新状态协方差 for (i = 0; i < STATE_DIM; i++) { filter->x[i] = x_new[i]; for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = P_new[i][j]; } } } // 更新步骤(带强跟踪机制) void stkf_update(STKF *filter, double z) { int i, j, k; double y[OBS_DIM]; // 新息 double S[OBS_DIM][OBS_DIM]; // 新息协方差 double K[STATE_DIM][OBS_DIM]; // 卡尔曼增益 double temp[STATE_DIM][OBS_DIM]; double temp2[OBS_DIM][OBS_DIM]; // 计算新息 y = z - H * x y[0] = z - (filter->H[0][0] * filter->x[0] + filter->H[0][1] * filter->x[1]); // 计算 S = H * P * H^T + R double PHt[STATE_DIM][OBS_DIM]; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < OBS_DIM; j++) { PHt[i][j] = 0.0; for (k = 0; k < STATE_DIM; k++) { PHt[i][j] += filter->P[i][k] * filter->H[j][k]; } } } for (i = 0; i < OBS_DIM; i++) { for (j = 0; j < OBS_DIM; j++) { S[i][j] = 0.0; for (k = 0; k < STATE_DIM; k++) { S[i][j] += filter->H[i][k] * PHt[k][j]; } if (i == j) S[i][j] += filter->R; } } // 强跟踪因子:计算 β double beta = 1.0; double yTy = y[0] * y[0]; double trace_S = S[0][0]; if (yTy > 2.0 * trace_S) { beta = trace_S / yTy; } // 计算卡尔曼增益 K = P * H^T * inv(S) double inv_S = 1.0 / S[0][0]; for (i = 0; i < STATE_DIM; i++) { K[i][0] = PHt[i][0] * inv_S; } // 更新状态 x = x + beta * K * y for (i = 0; i < STATE_DIM; i++) { filter->x[i] += beta * K[i][0] * y[0]; } // 更新协方差 P = (I - beta * K * H) * P double I_KH[STATE_DIM][STATE_DIM]; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { I_KH[i][j] = (i == j ? 1.0 : 0.0) - beta * K[i][0] * filter->H[0][j]; } } double P_new[STATE_DIM][STATE_DIM]; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { P_new[i][j] = 0.0; for (k = 0; k < STATE_DIM; k++) { P_new[i][j] += I_KH[i][k] * filter->P[k][j]; } } } for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = P_new[i][j]; } } } uint32_t division_value(uint32_t AD) { uint32_t i = 0; i = AD / 25; return i * 25; } uint32_t division_value100(uint32_t AD) { uint32_t i = 0; i = AD / 50; return i * 50; } uint32_t uabs_diff(uint32_t value1, uint32_t value2) { return (value1 >= value2) ? (value1 - value2) : (value2 - value1); } /** *一阶滤波算法 *@param new_value 新采样值 *@param old_value 上次滤波结果 *@param cof(一级滤波系数cof / 256) *@return 本次滤波结果 */ uint32_t first_filter(uint32_t new_value, uint32_t old_value, uint8_t cof) { unsigned long temp; if (new_value < old_value) { temp = old_value - new_value; temp = temp * cof / 256; temp = old_value - temp; } else if (new_value > old_value) { temp = new_value - old_value; temp = temp * cof / 256; temp = old_value + temp; } else { temp = old_value; } return temp; } // 高级滑动滤波器 int compare_floats(const void *a, const void *b) { return *(uint32_t *)a > *(uint32_t *)b ? 1 : -1; } float advanced_sliding_filter(SlidingFilter *SF_t) { uint32_t sorted[SF_t->WINDOW_SIZE]; // 排序去极值 memset(sorted, 0, sizeof(sorted)); memcpy(sorted, SF_t->buffer, sizeof(sorted)); qsort(sorted, SF_t->WINDOW_SIZE, sizeof(uint32_t), compare_floats); SF_t->sum = 0; for (int i = SF_t->EXCLUDE_NUM; i < SF_t->WINDOW_SIZE - SF_t->EXCLUDE_NUM; i++) { SF_t->sum += sorted[i]; } SF_t->mean = (SF_t->sum / (SF_t->WINDOW_SIZE - 2 * SF_t->EXCLUDE_NUM)); if (Filling.State == FUELING && uabs_diff(SF_t->mean, sorted[1]) > 400) //加注中 { SF_t->mean = sorted[1]; } //SF_t.mean = division_value(SF_t.mean); return SF_t->mean; } // IIR滤波器实现 void IIR_Filter_Init(IIR_Filter *filter, float alpha) { filter->alpha = alpha; filter->prev_output = 0.0f; } float IIR_Filter_Update(IIR_Filter *filter, float input) { // 根据重量变化率动态调整截止频率 if (0 > (ADS_coef.weight * ADS_coef.weight_Last)) { float delta_weight = fabsf(ADS_coef.weight - ADS_coef.weight_Last); float dynamic_cutoff = FILTER_CUTOFF_HZ * (1.0 - fminf(0.7, delta_weight / 100.0)); filter->alpha = 1.0f - expf(-2 * M_PI * dynamic_cutoff / SAMPLE_RATE_HZ); } filter->prev_output = filter->alpha * input + (1.0f - filter->alpha) * filter->prev_output; return filter->prev_output; } unsigned long i_us; unsigned long AD_dat = 0x00; /******************************************************************************* 函数:Read_Ads1232() 功能: 从ADS1232芯片中读取24位数据值(3字节) 参数: Calibration 返回: AD_dat *******************************************************************************/ unsigned long read_Ads1232(uint8_t Calibration) // 读取数值,并校准 { unsigned char x = 0; AD_dat = 0x00; ADS_SCLK_L; // SCLK_L while (ADS_DOUT_Read) { i_us++; delay_us(100); if (i_us > 0x1ffff) return 0; } // 等待数据线拉低,表示可以读取数据 for (x = 0; x < 24; x++) // 连续读取24位数据 { AD_dat <<= 1; // 左移 1位 ADS_SCLK_H; // SCLK_H delay_us(10); ADS_SCLK_L; // SCLK_Ladvanced if (ADS_DOUT_Read) // 获取数据口线的值 { AD_dat |= 0x00000001; } else { AD_dat &= 0xfffffffe; } delay_us(10); } if (Calibration) // 增加一个脉冲,芯片校准 { ADS_SCLK_H; // SCLK_H delay_us(10); ADS_SCLK_L; // SCLK_L } return division_value100(AD_dat & 0x00ffffff); // 防止数据溢出 // return (AD_dat&0x00ffffff);//防止数据溢出 } // 将AD值转换为差分电压并放大ADS_coef.precision倍 uint32_t ADtoDiffVolt(uint32_t AD_Data) { return division_value((AD_Data / FIXED_VALUE) * ADS_coef.magnification); } // 将差分电压与零点之差计算重量单位g float DiffVoltTOg(uint32_t DiffVolt) { float NetZero = (ADS_coef.zero_coef + ADS_coef.NetWeight_coef); uint32_t AD_Diff = (DiffVolt >= NetZero) ? (DiffVolt - NetZero) : (NetZero - DiffVolt); if (DiffVolt >= NetZero) { ADS_coef.Symbol = 0x00; //正值 BaData.TotalSymbol = 0x00; BaData.NetSymbol = 0x00; } else { ADS_coef.Symbol = 0x01; //负值 BaData.TotalSymbol = 0x01; BaData.NetSymbol = 0x01; } return ADS_coef.k * AD_Diff; } // 返回值为差分电压放大值 uint32_t Read_Ads1232(uint8_t Calibration) { static uint8_t i = 0; static uint8_t index_last = 0; uint32_t temp; uint32_t ADTemp; if (Filling.State == FUELING) //加注中 { if (SF.WINDOW_SIZE > WINDOW_FILL && SF.index > 0) { SF.index = 0; memset(SF.buffer, 0, sizeof(SF.buffer)); } SF.WINDOW_SIZE = WINDOW_FILL; SF.EXCLUDE_NUM = 0; // 更新数据缓冲区 if (SF.index > 0) { SF.buffer[SF.index] = first_filter(read_Ads1232(Calibration), SF.buffer[index_last], ADS_coef.coff); SF.buffer[SF.index] = IIR_Filter_Update(&fill_filter, (float)SF.buffer[SF.index]); if (SF.buffer[index_last] != 0 && uabs_diff(SF.buffer[SF.index], SF.buffer[index_last]) > (SF.buffer[index_last] - ADS_coef.zero_coef) / 3) { SF.buffer[SF.index] = SF.buffer[index_last]; } } else { SF.buffer[SF.index] = read_Ads1232(Calibration); if (SF.buffer[index_last] != 0 && uabs_diff(SF.buffer[SF.index], SF.buffer[index_last]) > (SF.buffer[index_last] - ADS_coef.zero_coef) / 3) { SF.buffer[SF.index] = SF.buffer[index_last]; } } if (SF.buffer[SF.index] >= 0x5FFFFF || SF.buffer[SF.index] <= 0X100) { ADS_PDWN_L; // PDWN_L delay_us(20); ADS_PDWN_H; // PDWN_H delay_ms(50); // 去电复位 SF.buffer[SF.index] = read_Ads1232(Calibration); if (SF.buffer[SF.index] >= 0x5FFFFF || SF.buffer[SF.index] <= 0X100) // 传感器异常 { ADS_coef.Blance_Abnormal = 1; SetBit((uint8 *)&FillAlarm.STS, 6, 0); // 6-称传感器异常 } } else { ADS_coef.Blance_Abnormal = 0; } index_last = SF.index; SF.index = (SF.index + 1) % SF.WINDOW_SIZE; if (index_last == (SF.WINDOW_SIZE - 1) && ADS_coef.k > 0.0f && ADS_coef.k < 1.0f) { ADS1232_Processing(Calibration); } } else { // 更新数据缓冲区 if (i == 0) // 第一个先存起来,根据情况赋值 { temp = read_Ads1232(Calibration); if (Filling.State != IDLE && SF.buffer[index_last] != 0 && uabs_diff(temp, SF.buffer[index_last]) > (SF.buffer[index_last] - ADS_coef.zero_coef) / 3) { temp = SF.buffer[index_last]; } } else { temp = read_Ads1232(Calibration); if (Filling.State != IDLE && SF.buffer[index_last] != 0 && uabs_diff(temp, SF.buffer[index_last]) > (SF.buffer[index_last] - ADS_coef.zero_coef) / 3) temp = SF.buffer[index_last]; // if (uabs_diff(temp, SF.buffer[index_last]) > (0x250)) // SF.buffer[SF.index] = read_Ads1232(Calibration); // else SF.buffer[SF.index] = first_filter(temp, SF.buffer[index_last], ADS_coef.coff); } if ((SF.buffer[SF.index] >= 0x5FFFFF) || !(temp | 0X00)) // 改为传感器异常?? { ADS_PDWN_L; // PDWN_L delay_us(20); ADS_PDWN_H; // PDWN_H delay_ms(50); // 去电复位 SF.buffer[SF.index] = read_Ads1232(Calibration); if (SF.buffer[SF.index] >= 0x5FFFFF || SF.buffer[SF.index] <= 0X100) // 传感器异常 { ADS_coef.Blance_Abnormal = 1; SetBit((uint8 *)&FillAlarm.STS, 6, 0); // 6-称传感器异常 } } else { ADS_coef.Blance_Abnormal = 0; } if (i == 0) { if (uabs_diff(ADtoDiffVolt(temp), ADS_coef.ADC_VALUE_Last) > (0x200)) // 差分值变化大 { SF.WINDOW_SIZE = WINDOW_CARDINAL; SF.EXCLUDE_NUM = 1; SF.index = 0; SF.buffer[SF.index] = temp; } else { if (WINDOW_FILL == SF.WINDOW_SIZE || 0x00 == SF.buffer[0]) // 从加注中模式切换过来,第一个 { SF.WINDOW_SIZE = WINDOW_CARDINAL; SF.EXCLUDE_NUM = 1; SF.index = 0; SF.buffer[SF.index] = temp; } else { if (SF.WINDOW_SIZE == WINDOW_CARDINAL) { SF.index = WINDOW_CARDINAL; SF.buffer[WINDOW_CARDINAL] = temp; SF.WINDOW_SIZE = WINDOW_CARDINAL * 2; } else { SF.buffer[SF.index] = temp; SF.EXCLUDE_NUM = 1; } } } } index_last = SF.index; SF.index = (SF.index + 1) % SF.WINDOW_SIZE; if (i >= (WINDOW_CARDINAL - 1) && ADS_coef.k > 0.0f && ADS_coef.k < 1.0f) ADS1232_Processing(Calibration); i = (i + 1) % WINDOW_CARDINAL; } if (ADS_coef.k < 0.0f || ADS_coef.k > 1.0f) SetBit((uint8 *)&FillAlarm.STS, 4, 0); // 6-电子秤标定异常 // 预测与更新 // kalman_predict(&kf); // kalman_update(&kf, ADtoDiffVolt(SF.buffer[index_last])); stkf_predict(&filter); stkf_update(&filter, (double)ADtoDiffVolt(SF.buffer[index_last])); if(filter.x[0] != 0) return filter.x[0]; else return SF.buffer[index_last]; } // 零点标记 uint8_t zero_calibration() { LPC_GPIOINT->IO2IntEnF &= (~ADS_DOUT);//禁止ADS_DOUT中断 uint8_t i = 0; FillFlag.ZeroBiaoding = 4; // 标记中 ADS_coef.zero_coef = 0x00; for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (ADS_coef.zero_coef == 0x00) { ADS_coef.zero_coef = ADS_coef.ADC_VALUE_Last; } else { ADS_coef.zero_coef = (ADS_coef.zero_coef + ADS_coef.ADC_VALUE_Last) / 2; } } ADS_coef.zero_trace = ADS_coef.zero_coef; if (1 != ADS_coef.Blance_Abnormal) { ADS_coef.NetWeight_coef = 0; //FillPara.ADS1232_zero = ADS_coef.zero_coef; FillFlag.ZeroBiaoding = 2; // 标定成功 Write_ADS1232(); // 保存 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 2; } else { LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 3; } } // 加载标记 uint8_t Loading_calibration(uint32_t loading_value) { uint8_t i = 0; LPC_GPIOINT->IO2IntEnF &= (~ADS_DOUT);//禁止ADS_DOUT中断 for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (ADS_coef.Loading_coef == 0x00) { ADS_coef.Loading_coef = ADS_coef.ADC_VALUE_Last; } else { ADS_coef.Loading_coef = (ADS_coef.Loading_coef + ADS_coef.ADC_VALUE_Last) / 2; } } // 计算k值 ADS_coef.k = ((float)(loading_value * 10) / (ADS_coef.Loading_coef - ADS_coef.zero_coef)); if (ADS_coef.k > 0.0f && ADS_coef.k < 1.0f && 1 != ADS_coef.Blance_Abnormal) { ClrBit((uint8*)&FillAlarm.STS, 4); //FillPara.ADS1232_k = (ADS_coef.k * 1000000000); Write_ADS1232(); // 保存 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 2; // 标定成功 } else { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 3; // 标定失败 } } //去皮标定 uint8_t NetWeight_calibration() { uint8_t i = 0; float NetTemp; for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (NetTemp == 0x00) { NetTemp = ADS_coef.ADC_VALUE_Last; } else { NetTemp = (NetTemp + ADS_coef.ADC_VALUE_Last) / 2; } } ADS_coef.NetWeight_coef = NetTemp - ADS_coef.zero_coef; } void FillingStream() { char Temp, i; INT32U temp1; INT8U TotalOffset; if ((Filling.State == FUELING) && (BaData.TotalSymbol == 0)) //ly20240410 zxl20241210 { //计算加注速率 if (FillFlag.ReadBalanceTimes < 50) { FillFlag.ReadBalanceTimes++; } FillFlag.Readflag = 0; Temp = uabs_diff(Filling.TotalWeight, Filling.OldTotalWeight); //ly20241218 if ((Filling.PotType == FORTY_EIGHTKG) || (Filling.PotType == FIVTYKG)) //ly20250107 { TotalOffset = 80; } else { TotalOffset = 50; } if (Temp > 0) { if ((Temp < TotalOffset) || (FillFlag.Calculateflag == 0) || (FillFlag.ReadBalanceTimes < 30)) //ly20241221 { Amountadding[FillFlag.Index] = Temp; FillFlag.OldAddTotal = Temp; Filling.OldTotalWeight = Filling.TotalWeight; Filling.TotalAbnormalTimes = 0; } else { Filling.TotalAbnormalTimes++;//ly20241221 if (Filling.TotalAbnormalTimes < 4) { Filling.TotalWeight = Filling.OldTotalWeight; //ly20241220 Amountadding[FillFlag.Index] = FillFlag.OldAddTotal; Filling.OldTotalWeight += FillFlag.OldAddTotal; } else { Filling.State = SUSPEND; //保存数据 DCF_OUT_CTRL(DCF_V1, OFF); //关阀 DCF_OUT_CTRL(DCF_V2, OFF); //关阀 ADS_coef.Valve_change = VALUE_VIBRATION; WriteWork_status(SUSPEND); LogDispose("Goto Suspend4 \n", strlen("Goto Suspend4 \n")); show.dislist = 59; Filling.Abnormalstopflag = 1; //ly20240920 Filling.TotalAbnormalTimes = 0; } } } else { Filling.OldTotalWeight = Filling.TotalWeight; Amountadding[FillFlag.Index] = 0x00; } FillFlag.Index++; if (FillFlag.Index >= 10) { FillFlag.Calculateflag = 1; FillFlag.Index = 0; } if (FillFlag.Calculateflag == 1) //ly20241104 { temp1 = 0; for (i = 0; i < 10; i++) { temp1 += Amountadding[i]; } Filling.FillingSpeed = temp1 * 5; //计算流速平均值标识Ng/600ms流速 if (Filling.FillingSpeed > Filling.FillingMaxSpeed) { Filling.FillingMaxSpeed = Filling.FillingSpeed; } if (Filling.FillingSpeed > 350) { Filling.FillingSpeed = Filling.FillingoldSpeed; } else { Filling.FillingoldSpeed = Filling.FillingSpeed; } } if (Filling.State == FUELING) { FuelingOperation(); } } } uint32_t WeightShow_10(float weight) { uint32_t show_value = weight / 10; uint8_t units_digit = (uint32_t)weight % 10; if (0 == show_value && units_digit < 8) { ADS_coef.weight_show = show_value * 10; } else { if (units_digit >= 5) { ADS_coef.weight_show = (show_value + 1) * 10; } else { ADS_coef.weight_show = show_value * 10; } } Filling.TotalWeight = ADS_coef.weight_show / 10; BaData.TotalWeight = ADS_coef.weight_show / 10; BaData.LastData = BaData.TotalWeight; Filling.NetWeight = ADS_coef.weight_show / 10; BaData.NetWeight = ADS_coef.weight_show / 10; FillingStream(); BaData.DataUpdateflag = 1; } uint32_t WeightShow_20(float weight) { uint32_t show_value = weight / 20; uint8_t units_digit = (uint32_t)weight % 20; if (weight > 15 && ADS_coef.wen_flag >= 30 && (fabsf(weight - ADS_coef.weight_show) < 15)) {} else { if (0 == show_value && units_digit < 15) { ADS_coef.weight_show = show_value * 20; } else { if (units_digit >= 10) { ADS_coef.weight_show = (show_value + 1) * 20; } else { ADS_coef.weight_show = show_value * 20; } } } Filling.TotalWeight = ADS_coef.weight_show / 10; BaData.TotalWeight = ADS_coef.weight_show / 10; BaData.LastData = BaData.TotalWeight; Filling.NetWeight = ADS_coef.weight_show / 10; BaData.NetWeight = ADS_coef.weight_show / 10; FillingStream(); BaData.DataUpdateflag = 1; } // 初始化 void ADS1232_init() { uint8_t i = 0; uint32 int32Temp; // 初始化 FirstUp = 1; ADS_coef.magnification = 10000000; ADS_coef.coff = 180; ADS_coef.NetWeight_coef = 0; ADS_coef.Valve_change = 0; ADS_PDWN_L; // PDWN_L delay_us(20); ADS_PDWN_H; // PDWN_H delay_us(40); // 去电复位 // 读取几次,待数据稳定后再读取输出 for (i = 0; i < 12; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); delay_us(20); } //读取铁电保存值 ReadContinuumeMBRS64A((uint8 *)(&RealTimeData.ADS1232[0]) - & (RealTimeData.Head), (void *)&RealTimeData.ADS1232[0], 12, FillFlag.FmDeviceType); int32Temp = ComputeCRC32((uint32_t *)(&RealTimeData.ADS1232[0]), 2); if (int32Temp != RealTimeData.ADS1232[2]) { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 } else { ADS_coef.zero_coef = RealTimeData.ADS1232[0]; ADS_coef.k = ((float)RealTimeData.ADS1232[1] / 1000000000.0); if (ADS_coef.k > 0.0f && ADS_coef.k < 1.0f) { ClrBit((uint8*)&FillAlarm.STS, 4); } else { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 } } // 滤波器初始化 float alpha = 1.0f - expf(-2 * M_PI * FILTER_CUTOFF_HZ / SAMPLE_RATE_HZ); IIR_Filter_Init(&weight_filter, alpha); //IIR_Filter_Init(&weight_filterAD, alpha); // 初始化滤波器:初始位置=4000,初始速度=0 // Q:过程噪声,R:观测噪声 //stkf_init(&filter, 80000.0, 4000, 25e6, 0.04, ADS_coef.ADC_VALUE_Last); stkf_init(&filter, 80000.0, 0, 4000, 25e6, ADS_coef.ADC_VALUE_Last); //zero_calibration(); // 零点标记 //Loading_calibration(20000); // 假设加载标定值为20000g LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 } uint8_t SFW_A; float LLw; float Lw_w; float sum = 0, sq_sum = 0, r = 0; uint8_t kfi; void ADS1232_Processing(uint8_t Calibration) { uint32_t ad; uint32_t IIRTemp; float weight_abs = 0.0f; advanced_sliding_filter(&SF); SF.window_number++; if (SF.window_number > 0xffff && (Filling.State == IDLE)) // 加上没有在加注状态判断 { SF.window_number = 0; ADS_PDWN_L; // PDWN_L delay_us(40); ADS_PDWN_H; // PDWN_H 去电复位 delay_us(40); read_Ads1232(Calibration); delay_us(10); read_Ads1232(Calibration); } ADS_coef.ADC_VALUE = ADtoDiffVolt(SF.mean); // 读取差分电压值 ad = ADS_coef.ADC_VALUE; IIRTemp = IIR_Filter_Update(&weight_filter, (float)ADS_coef.ADC_VALUE); if (uabs_diff(IIRTemp, ADS_coef.ADC_VALUE) < 200) ADS_coef.ADC_VALUE = IIRTemp; // 预测与更新 // if (ADS_coef.Valve_change > 0) //阀门有改变AD值不可信 // { // ADS_coef.Valve_change--; // ADS_coef.ADC_VALUE = filter.x[0] + filter.x[1] * 0.05; // } // else { stkf_predict(&filter); stkf_update(&filter, ADS_coef.ADC_VALUE); ADS_coef.ADC_VALUE = filter.x[0]; } ADS_coef.weight = DiffVoltTOg(ADS_coef.ADC_VALUE); Lw_w = fabsf(ADS_coef.weight_Last - ADS_coef.weight); // if (Lw_w < 10 && Filling.State == IDLE) // ADS_coef.weight = (ADS_coef.weight + ADS_coef.weight_Last) / 2; // //计算流动稳定值(预测) // if (Lw_w < (Filling.FillingSpeed + 100)) // { // if (liu_wen == 0) // liu_wen = ADS_coef.weight; // else // liu_wen = (liu_wen + ADS_coef.weight + (Filling.FillingSpeed / 6)) / 2; // if (uabs_diff(liu_wen, ADS_coef.weight) > 200) // { // if (liu_count > 3) //修正 // { // liu_wen = ADS_coef.weight; // } // liu_count++; // } // else // liu_count = 0; // } // if (Filling.State != IDLE) // { // //防止突变 连续3次突变 // if (Lw_w > ADS_coef.weight_Last / 20 && ADS_coef.weight > (liu_wen + Filling.FillingSpeed)) // { // if (big_count < 5) // { // ADS_coef.weight = ADS_coef.weight_Last; // big_count++; // } // } // else // big_count = 0; // } //稳定性加强 if ((Filling.State != FUELING) && Lw_w < 60) { SF_W.WINDOW_SIZE = ((SFW_A >= 14) ? (SFW_A = 14) : SFW_A++); if (Filling.State == SAVEDATA || Filling.State == SUSPEND) SF_W.EXCLUDE_NUM = 4; else SF_W.EXCLUDE_NUM = 2; SF_W.buffer[SF_W.index] = ADS_coef.weight; if (SFW_A > 10) { advanced_sliding_filter(&SF_W); ADS_coef.weight = SF_W.mean; } SF_W.index = (SF_W.index + 1) % 14; } else if (Filling.State == FUELING && Filling.FillingSpeed > 0 && Lw_w < 80) //上次重量差小于上上次重量差三倍 { SF_W.WINDOW_SIZE = ((SFW_A >= 3) ? (SFW_A = 3) : SFW_A++); SF_W.EXCLUDE_NUM = 0; SF_W.buffer[SF_W.index] = ADS_coef.weight; if (SFW_A >= 3) { //SF_W.buffer[SF_W.index] += (Filling.FillingSpeed/10*3); advanced_sliding_filter(&SF_W); if (fabsf(SF_W.mean - ADS_coef.weight) < 25) ADS_coef.weight = SF_W.mean; else { SFW_A = 0; SF_W.index = 0; } } SF_W.index = (SF_W.index + 1) % 3; } else { SFW_A = 0; SF_W.index = 0; } if (1 == ADS_coef.Blance_Abnormal) SetBit((uint8 *)&FillAlarm.STS, 6, 0); // 6-称传感器异常 else ClrBit((uint8*)&FillAlarm.STS, 6); // 判稳 if (fabsf(ADS_coef.weight_Last - ADS_coef.weight) < 5) //g { ADS_coef.wen_flag++; if (20 < ADS_coef.wen_flag) // 连续20次于上一次重量相差在5g以内 { BaData.DataStable = 1; FillFlag.DataState = 1; // 判断为数据稳定 // if (1 == FirstUp && ADS_coef.weight != 0 && ADS_coef.weight < 200 && ADS_coef.zero_coef > 0) // { // FirstUp = 0; // ADS_coef.NetWeight_coef = ADS_coef.ADC_VALUE - ADS_coef.zero_coef; // } } if (ADS_coef.wen_flag > 0x2fff) // 保持稳定状态 { ADS_coef.wen_flag = 0x2f; } if (ADS_coef.wen_flag > 0x40 && ADS_coef.weight < 200) // 零点跟踪 { trace_s++; ADS_coef.zero_trace += ADS_coef.ADC_VALUE; ADS_coef.zero_trace = ADS_coef.zero_trace / 2; if (trace_s > 0x70) { //ADS_coef.NetWeight_coef = ADS_coef.zero_trace - ADS_coef.zero_coef; trace_s = 0; } } } else { ADS_coef.wen_flag = 0; BaData.DataStable = 0; FillFlag.DataState = 0; // 判断为数据不稳 } WeightShow_10(ADS_coef.weight); sprintf((char *)com4.TX_Buffer, "show:%d weight:%f AD:%d ->%d Lw_LLw:%f speed:%d i_us:%ld\n", ADS_coef.weight_show, ADS_coef.weight, ad, ADS_coef.ADC_VALUE, fabsf(ADS_coef.weight_Last - LLw), (Filling.FillingSpeed), i_us); com4.TX_tailPtr = strlen(com4.TX_Buffer); STARTtx4(); i_us = 0; LLw = ADS_coef.weight_Last; ADS_coef.weight_Last = ADS_coef.weight; ADS_coef.ADC_VALUE_Last = ADS_coef.ADC_VALUE; ADS_coef.ADC_VALUE = 0; }
09-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值