Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

113 wiersze
4.3 KiB

  1. """测试逻辑分析仪 CSV/BIN 波形解析。"""
  2. from __future__ import annotations
  3. import struct
  4. import tempfile
  5. import unittest
  6. from pathlib import Path
  7. from logic_waveform import (
  8. WaveformChannel,
  9. build_frequency_curve,
  10. load_bin_waveform,
  11. load_csv_waveform,
  12. parse_channel_selection,
  13. parse_marker_times_ms,
  14. )
  15. from parse_logic_csv import CsvParseError
  16. class LogicWaveformTest(unittest.TestCase):
  17. """验证两种导出格式的关键解析结果。"""
  18. def test_load_csv_waveform(self) -> None:
  19. """CSV 应识别采样信息、数字时间列和通道跳变。"""
  20. content = """; Sample rate: 20 MHz
  21. ; Sample count: 10
  22. SystemTime,Time(s),Channel 0,Channel 1
  23. '2026-08-14 10:00:00,0.0,0,1
  24. '2026-08-14 10:00:00,0.1,1,1
  25. '2026-08-14 10:00:00,0.2,1,0
  26. """
  27. with tempfile.TemporaryDirectory() as directory:
  28. path = Path(directory) / "wave.csv"
  29. path.write_text(content, encoding="utf-8")
  30. data = load_csv_waveform(path)
  31. self.assertEqual(data.sample_rate, 20_000_000)
  32. self.assertEqual(data.sample_count, 10)
  33. self.assertEqual(data.record_count, 3)
  34. self.assertEqual(data.start_time, 0.0)
  35. self.assertEqual(data.end_time, 0.2)
  36. self.assertEqual(data.channels[0].times, [0.0, 0.1])
  37. self.assertEqual(data.channels[0].levels, [0, 1])
  38. self.assertEqual(data.channels[1].times, [0.0, 0.2])
  39. self.assertEqual(data.channels[1].levels, [1, 0])
  40. def test_load_16_channel_bin_waveform(self) -> None:
  41. """16 通道 BIN 应按小端 16 位采样点读取。"""
  42. samples = (0x0000, 0x0010, 0x0010, 0x0000)
  43. with tempfile.TemporaryDirectory() as directory:
  44. path = Path(directory) / "wave.bin"
  45. path.write_bytes(struct.pack("<4H", *samples))
  46. data = load_bin_waveform(path, 10.0, 16, [4])
  47. channel = data.channels[0]
  48. self.assertEqual(data.sample_count, 4)
  49. self.assertAlmostEqual(data.duration, 0.3)
  50. self.assertEqual(channel.index, 4)
  51. self.assertEqual(channel.times, [0.0, 0.1, 0.3])
  52. self.assertEqual(channel.levels, [0, 1, 0])
  53. def test_parse_channel_selection(self) -> None:
  54. """通道输入应支持单个、列表和范围。"""
  55. self.assertIsNone(parse_channel_selection("自动", 16))
  56. self.assertEqual(parse_channel_selection("4", 16), [4])
  57. self.assertEqual(parse_channel_selection("0,2,4-6", 16), [0, 2, 4, 5, 6])
  58. def test_build_frequency_curve_with_automatic_falling_edge(self) -> None:
  59. """负逻辑脉冲应自动使用第一个真实下降沿计算频率。"""
  60. channel = WaveformChannel(
  61. index=4,
  62. name="Channel 4",
  63. times=[0.0, 0.1, 0.11, 0.2, 0.21, 0.3, 0.31],
  64. levels=[1, 0, 1, 0, 1, 0, 1],
  65. )
  66. curve = build_frequency_curve(channel, "auto")
  67. self.assertEqual(curve.edge_name, "下降沿")
  68. self.assertEqual(curve.times, [0.1, 0.2, 0.3])
  69. for frequency in curve.frequencies:
  70. self.assertAlmostEqual(frequency, 10.0)
  71. measured_time, frequency = curve.frequency_at(0.2)
  72. self.assertEqual(measured_time, 0.2)
  73. self.assertEqual(frequency, 10.0)
  74. def test_build_frequency_curve_with_rising_edge(self) -> None:
  75. """指定上升沿时应按相邻上升沿周期换算频率。"""
  76. channel = WaveformChannel(
  77. index=0,
  78. name="Channel 0",
  79. times=[0.0, 0.01, 0.015, 0.02, 0.0225, 0.025, 0.0275],
  80. levels=[0, 1, 0, 1, 0, 1, 0],
  81. )
  82. curve = build_frequency_curve(channel, "rising")
  83. self.assertEqual(curve.edge_name, "上升沿")
  84. self.assertAlmostEqual(curve.frequencies[0], 100.0)
  85. self.assertAlmostEqual(curve.frequencies[-1], 200.0)
  86. def test_parse_marker_times_ms(self) -> None:
  87. """关键时间应支持多个毫秒数值。"""
  88. self.assertEqual(parse_marker_times_ms("100, 200,500"), [0.1, 0.2, 0.5])
  89. def test_parse_marker_times_ms_rejects_more_than_ten_unique_values(self) -> None:
  90. """关键时间超过十个时应给出明确错误。"""
  91. with self.assertRaisesRegex(CsvParseError, "最多设置 10 个"):
  92. parse_marker_times_ms(",".join(str(value) for value in range(11)))
  93. if __name__ == "__main__":
  94. unittest.main()