编写信号发生器(Signal Generator)的测试脚本需要结合硬件控制、测试逻辑和结果分析。以下是详细的步骤和代码示例(以Python为例),涵盖从基础控制到自动化测试的实现。
bashpip install pyvisa numpy matplotlib pandas
使用PyVISA 通过SCPI命令 控制信号发生器。
python
import
pyvisa
class
SignalGenerator:
def
__init__(self, resource):
self.rm = pyvisa.ResourceManager()
self.device =
self.rm.open_resource(resource)
self.device.timeout =
5000
# 超时时间(ms)
self.device.read_termination =
'n'
# 读取终止符
self.device.write_termination =
'n'
# 写入终止符
def
close(self):
self.device.close()
python
class
SignalGenerator:
# ...(前述初始化代码)
def
set_frequency(self, freq_hz):
"""设置频率(Hz)"""
self.device.write(f"FREQ
{freq_hz}Hz")
def
set_power(self, power_dbm):
"""设置功率(dBm)"""
self.device.write(f"POW
{power_dbm}dBm")
def
enable_output(self, state=True
):
"""开启/关闭输出"""
self.device.write(f"OUTP
{'ON'
if
state
else
'OFF'}")
def
query(self, cmd):
"""发送查询命令并返回结果"""
return
self.device.query(cmd).strip()
# 示例:设置调制(AM调制)
def
set_am_modulation(self, depth_percent):
self.device.write("MOD OFF")# 先关闭调制
self.device.write("MOD:AM:STAT ON")# 开启AM调制
self.device.write(f"MOD:AM:DEP
{depth_percent}%")# 设置调制深度
使用JSON文件管理测试参数,便于动态加载:
json// test_config.json{"frequency_list": [1e6, 10e6, 100e6], // 测试频率点(Hz)"power_levels": [-20, 0, 10], // 测试功率(dBm)"modulation": {"type": "AM","depth": 30},"dwell_time_sec": 2 // 每个参数点的停留时间}
python
import
json
import
time
import
pandas
as
pd
from
datetime
import
datetime
class
AutomatedTest:
def
__init__(self, config_file):
with
open(config_file)
as
f:
self.config = json.load(f)
self.sg = SignalGenerator("TCPIP0::192.168.1.100::inst0::INSTR")# 替换为实际地址
self.results = []
def
run_test(self):
for
freq
in
self.config["frequency_list"]:
for
power
in
self.config["power_levels"]:
# 设置信号发生器参数
self.sg.set_frequency(freq)
self.sg.set_power(power)
# 可选:设置调制
if
"modulation"
in
self.config:
self._setup_modulation()
# 开启输出并等待稳定
self.sg.enable_output(True)
time.sleep(self.config["dwell_time_sec"])
# 采集结果(示例:读取实际输出值)
actual_freq =
float(self.sg.query("FREQ?"))
actual_power =
float(self.sg.query("POW?"))
# 记录结果
self.results.append({
"Timestamp": datetime.now(),
"Set_Frequency_Hz": freq,
"Actual_Frequency_Hz": actual_freq,
"Set_Power_dBm": power,
"Actual_Power_dBm": actual_power,
"Status":
"PASS"
if
abs(actual_freq - freq) <
1e3
else
"FAIL"
})
# 关闭输出(可选)
self.sg.enable_output(False)
def
_setup_modulation(self):
mod =
self.config["modulation"]
if
mod["type"] ==
"AM":
self.sg.set_am_modulation(mod["depth"])
def
save_results(self, filename):
df = pd.DataFrame(self.results)
df.to_csv(filename, index=False)
print(f"Results saved to
{filename}")
def
close(self):
self.sg.close()
# 执行测试
if
__name__ ==
"__main__":
test = AutomatedTest("test_config.json")
try:
test.run_test()
test.save_results("test_results.csv")
finally:
test.close()
python
class
MultiDeviceTest:
def
__init__(self):
self.sg = SignalGenerator("TCPIP0::192.168.1.100::inst0::INSTR")
self.scope = ScopeController("TCPIP0::192.168.1.101::inst0::INSTR")# 示波器控制类
def
measure_output(self):
self.sg.enable_output(True)
time.sleep(1)
measured_power =
self.scope.measure_power()# 伪代码:通过示波器测量实际功率
return
measured_power
pythondef adaptive_test():initial_power = -20while initial_power <= 10:sg.set_power(initial_power)measured = measure_dut_output() # 伪代码:测量被测设备输出if measured
python
import
matplotlib.pyplot
as
plt
def
generate_report(csv_file):
df = pd.read_csv(csv_file)
# 绘制频率误差图
plt.figure(figsize=(10,
5))
plt.plot(df["Set_Frequency_Hz"], df["Actual_Frequency_Hz"] - df["Set_Frequency_Hz"],
'o-')
plt.xlabel("Set Frequency (Hz)")
plt.ylabel("Frequency Error (Hz)")
plt.title("Frequency Accuracy Test")
plt.grid()
plt.savefig("frequency_accuracy.png")
plt.close()
错误处理
pythondef safe_query(device, cmd, retries=3):for _ in range(retries):try:return device.query(cmd)except pyvisa.Error as e:time.sleep(1)raise Exception(f"Command {cmd} failed after {retries} retries")
日志记录
pythonimport logginglogging.basicConfig(filename='test.log', level=logging.DEBUG, format='%(asctime)s - %(message)s')
性能优化
SOUR:LIST:FREQ
命令)。
asyncio
)控制多台设备。
python
# main.py
from
automated_test
import
AutomatedTest
import
argparse
if
__name__ ==
"__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--config", default="test_config.json")
parser.add_argument("--output", default="test_results.csv")
args = parser.parse_args()
test = AutomatedTest(args.config)
try:
test.run_test()
test.save_results(args.output)
generate_report(args.output)# 生成图表
finally:
test.close()
通过以上方法,可以高效实现信号发生器的自动化测试,适用于生产校验、研发验证等场景。