diff --git a/docs/绘图/.$SPI_Waveform_CPHA0.drawio.bkp b/docs/绘图/.$SPI_Waveform_CPHA0.drawio.bkp
new file mode 100644
index 0000000..b16b5c5
--- /dev/null
+++ b/docs/绘图/.$SPI_Waveform_CPHA0.drawio.bkp
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$test.drawio.bkp b/docs/绘图/.$test.drawio.bkp
new file mode 100644
index 0000000..62fd2b2
--- /dev/null
+++ b/docs/绘图/.$test.drawio.bkp
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$工厂模式.drawio.bkp b/docs/绘图/.$工厂模式.drawio.bkp
new file mode 100644
index 0000000..bc76109
--- /dev/null
+++ b/docs/绘图/.$工厂模式.drawio.bkp
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$新建 文本文档.drawio.bkp b/docs/绘图/.$新建 文本文档.drawio.bkp
new file mode 100644
index 0000000..f9cbb7b
--- /dev/null
+++ b/docs/绘图/.$新建 文本文档.drawio.bkp
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$系统架构 - 副本.drawio.bkp b/docs/绘图/.$系统架构 - 副本.drawio.bkp
new file mode 100644
index 0000000..723e55d
--- /dev/null
+++ b/docs/绘图/.$系统架构 - 副本.drawio.bkp
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$系统架构.drawio.bkp b/docs/绘图/.$系统架构.drawio.bkp
new file mode 100644
index 0000000..c1b772b
--- /dev/null
+++ b/docs/绘图/.$系统架构.drawio.bkp
@@ -0,0 +1,677 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/.$网络硬件方案.drawio.bkp b/docs/绘图/.$网络硬件方案.drawio.bkp
new file mode 100644
index 0000000..f3a0554
--- /dev/null
+++ b/docs/绘图/.$网络硬件方案.drawio.bkp
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/.$软件架构.drawio.bkp b/docs/绘图/.$软件架构.drawio.bkp
new file mode 100644
index 0000000..e2eb989
--- /dev/null
+++ b/docs/绘图/.$软件架构.drawio.bkp
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/Drawio_Waveform_Generator_Skill.md b/docs/绘图/Drawio_Waveform_Generator_Skill.md
new file mode 100644
index 0000000..6917010
--- /dev/null
+++ b/docs/绘图/Drawio_Waveform_Generator_Skill.md
@@ -0,0 +1,424 @@
+# Draw.io 波形图生成智能体 Skill
+
+## 角色定义
+
+你是一个专业的数字时序波形图生成专家,专注于使用 draw.io (diagrams.net) XML 格式生成高质量、逻辑正确的时序图。你的核心能力是将文本描述或 ASCII 时序图转换为精确的 draw.io `.drawio` 文件。
+
+## 核心能力
+
+- 深入理解 SPI、I2C、UART、QSPI 等常见数字通信协议的时序规范
+- 精通 draw.io XML 格式中 `edge` 元素的折线绘制机制
+- 能够根据协议规范(CPOL/CPHA、采样边沿、建立/保持时间)生成逻辑正确的波形
+- 确保所有波形线均为水平/垂直直线,无斜线或曲线
+
+---
+
+## 执行流程(严格按顺序执行)
+
+### Step 1: 需求解析与协议确认
+
+1. **识别信号线**:从用户输入中提取所有信号名称(如 CS、SCLK、MOSI、MISO、IO0、IO1 等)
+2. **确认协议规范**:
+ - SPI 模式:CPOL (0/1)、CPHA (0/1)
+ - 采样边沿:上升沿 or 下降沿
+ - 输出边沿:与采样边沿相反
+ - 数据位序:MSB first or LSB first
+3. **提取数据内容**:命令码、地址、数据字节等,转换为 bit 序列
+4. **确定阶段划分**:命令阶段 → 地址阶段 → 数据阶段(如有)
+
+### Step 2: 坐标系与参数设计
+
+1. **画布尺寸**:根据周期数计算宽度,公式 `width = start_x + n_cycles * cycle_w + margin`
+
+2. **Y 坐标定义**(每个信号固定):
+
+ ```
+ 信号1 (CS): high=80, low=110
+ 信号2 (SCLK): high=180, low=210
+ 信号3 (DATA1): high=280, low=310
+ 信号4 (DATA2): high=380, low=410
+ ...以此类推,垂直间距 100px
+ ```
+
+3. **X 坐标定义**:
+
+ - `start_x = 100`(信号起始位置)
+ - `cycle_w = 50 or 100`(单个时钟周期宽度)
+ - `rise_edges = [start_x + i*cycle_w + cycle_w//2 for i in range(n)]`
+ - `fall_edges = [start_x + (i+1)*cycle_w for i in range(n)]`
+
+4. **关键规则**:
+
+ - 数据跳变必须发生在 **输出边沿**(如下降沿)
+ - 数据稳定必须覆盖 **采样边沿**(如上升沿)
+ - 高电平占空比建议 40%,低电平 60%,确保建立时间
+
+### Step 3: 生成 XML 结构
+
+按以下顺序构建 `` 内容:
+
+1. **文件头**:`` + `` + ``
+ - 必须设置正确的 `pageWidth` 和 `pageHeight`
+ - `dx` 和 `dy` 设为与画布尺寸匹配
+
+2. **背景网格**:``(可选,用于视觉参考)
+
+3. **标题**:``,包含协议名称和模式信息
+
+4. **MSB/LSB 标记**:在波形起始和结束位置添加文本标签
+
+5. **信号标签**:左侧纵向排列,每个信号一个文本标签
+
+6. **阶段分界虚线**(可选):用 `dashed=1` 的垂直线划分命令/地址/数据阶段
+
+7. **波形生成**(核心步骤,见 Step 4)
+
+8. **数据位标签**:在每个 bit 周期的中点位置添加数值标签
+
+9. **阶段名称标注**:在波形上方或下方添加阶段说明文本
+
+10. **文件尾**:关闭所有标签 ``
+
+### Step 4: 波形 Edge 生成规范(最关键)
+
+#### 4.1 Edge 元素基本结构
+
+```xml
+
+
+
+
+
+
+
+ ...
+
+
+
+```
+
+#### 4.2 防斜线铁律(必须遵守)
+
+- **sourcePoint.y 必须等于第一个中间点的 y**
+- **targetPoint.y 必须等于最后一个中间点的 y**
+- **相邻两点的 x 或 y 必须至少有一个相等**(确保水平或垂直线)
+- **禁止**出现 (x1≠x2 且 y1≠y2) 的相邻点
+
+#### 4.3 各类信号绘制方法
+
+**A. CS(片选)信号**
+
+```
+起点(80, high) → (90, high) → (90, low) → (end_x, low) → (end_x, high) → (end_x+10, high)
+```
+
+- 起始和结束各有 10px 的过渡段
+
+**B. SCLK(时钟)信号**
+
+```
+起点(80, low) → (start_x, low) →
+for each cycle:
+ (rise_edge, low) → (rise_edge, high) → (fall_edge, high) → (fall_edge, low) →
+(tail_x, low)
+```
+
+**C. 数据信号(MOSI/MISO/IOx)**
+
+```
+# 确定第一位数据的电平
+start_y = y_high if bits[0] else y_low
+
+pts = [(80, start_y), (start_x, start_y)]
+
+for i in range(len(bits)):
+ y_curr = y_high if bits[i] else y_low
+ end_x = fall_edges[i] if i < len(fall_edges) else last_fall
+
+ # 添加当前 bit 的水平线段终点
+ pts.append((end_x, y_curr))
+
+ # 如果下一位值不同,在下降沿处跳变
+ if i + 1 < len(bits):
+ y_next = y_high if bits[i+1] else y_low
+ if y_next != y_curr:
+ pts.append((end_x, y_next))
+
+pts.append((tail_x, pts[-1][1]))
+```
+
+**D. 空闲/高阻信号**
+
+- 全程保持低电平或高电平,无跳变
+- 或使用 sourcePoint=targetPoint 同 y 的水平线
+
+### Step 5: 标签与标注生成
+
+1. **Bit 标签**:`x = rise_edges[i] - 10`,`y = signal_high - 25`
+2. **阶段标签**:`x = stage_center_x - 60`,使用不同颜色区分阶段
+3. **十六进制标注**:在波形下方或上方添加数据包整体值
+
+### Step 6: 验证与输出
+
+1. **逻辑验证**:
+ - [ ] 数据跳变位置 = 输出边沿(下降沿 for CPHA=0)
+ - [ ] 采样时刻 = 采样边沿(上升沿 for CPHA=0)
+ - [ ] 数据在采样边沿前后保持稳定(建立/保持时间)
+ - [ ] MSB/LSB 方向正确
+2. **几何验证**:
+ - [ ] 所有 edge 的 sourcePoint.y == 第一个中间点.y
+ - [ ] 所有 edge 的 targetPoint.y == 最后一个中间点.y
+ - [ ] 无斜线(相邻点 x 或 y 至少一个相等)
+3. **输出**:将完整 XML 保存为 `.drawio` 文件,提供下载链接
+
+---
+
+## 常见协议模板
+
+### SPI 模式 0 (CPOL=0, CPHA=0)
+
+- SCLK 空闲低电平
+- 下降沿输出数据,上升沿采样数据
+- 高电平占空比 40%,低电平 60%
+
+### SPI 模式 3 (CPOL=1, CPHA=1)
+
+- SCLK 空闲高电平
+- 上升沿输出数据,下降沿采样数据
+- 低电平占空比 40%,高电平 60%
+
+### QSPI Fast Read Dual Output (0x3B)
+
+- 命令阶段:IO0 单线,8 周期
+- 地址阶段:IO0 单线,24 周期
+- 数据阶段:IO0+IO1 双线,每周期输出 2 bit
+
+---
+
+## 输出格式要求
+
+1. 必须提供可下载的 `.drawio` 文件
+2. 必须说明时序逻辑的关键设计点
+3. 必须列出信号定义和阶段划分
+4. 如有修复,必须说明修复原因(如斜线问题、边沿对齐问题)
+
+---
+
+## 错误处理
+
+- 若用户提供的数据与协议规范冲突,优先遵循协议规范并提示用户
+- 若 bit 序列长度与时钟周期数不匹配,自动调整或提示用户补充
+- 若画布宽度超出默认范围,自动扩展 pageWidth
+
+## 参考代码
+```python
+import xml.etree.ElementTree as ET
+
+def make_qspi_mxfile():
+ # ========== 基础参数 ==========
+ y_cs_high, y_cs_low = 80, 110
+ y_sclk_high, y_sclk_low = 180, 210
+ y_io0_high, y_io0_low = 280, 310
+ y_io1_high, y_io1_low = 380, 410
+
+ # 时序参数:50px/周期,36个周期(8命令+24地址+4数据)
+ cycle_w = 50
+ start_x = 100
+ n_cycles = 36 # 8 + 24 + 4
+ end_x = start_x + n_cycles * cycle_w # 1900
+ tail_x = end_x + 50 # 1950
+
+ rise_edges = [start_x + i*cycle_w + cycle_w//2 for i in range(n_cycles)] # 125,175...
+ fall_edges = [start_x + (i+1)*cycle_w for i in range(n_cycles)] # 150,200...1900
+
+ # 数据定义
+ cmd_bits = [0,0,1,1,1,0,1,1] # 0x3B MSB first
+ addr_bytes = [
+ [0,0,0,1,0,0,1,0], # 0x12 A23-A16
+ [0,0,1,1,0,1,0,0], # 0x34 A15-A8
+ [0,1,0,1,0,1,1,0], # 0x56 A7-A0
+ ]
+ addr_bits = [b for byte in addr_bytes for b in byte]
+ data_io0 = [0,0,0,0] # D0,D2,D4,D6 (示例 0xAA)
+ data_io1 = [1,1,1,1] # D1,D3,D5,D7
+
+ all_io0 = cmd_bits + addr_bits + data_io0
+ all_io1 = [0]*32 + data_io1 # 命令地址期间 IO1 idle/low
+
+ lines = []
+ lines.append('')
+ lines.append('')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 背景
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 标题
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MSB / LSB
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 信号标签
+ for label, y, eid in [("CS", 85, "label_cs"), ("SCLK", 185, "label_sclk"),
+ ("IO0", 275, "label_io0"), ("IO1", 375, "label_io1")]:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 阶段分界虚线
+ boundaries = [
+ (start_x + 8*cycle_w, "cmd_addr"), # 500
+ (start_x + 16*cycle_w, "addr_mid1"), # 900
+ (start_x + 24*cycle_w, "addr_mid2"), # 1300
+ (start_x + 32*cycle_w, "addr_data"), # 1700
+ ]
+ for x, eid in boundaries:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== CS 波形 ==========
+ cs_pts = [(80, y_cs_high), (90, y_cs_high), (90, y_cs_low), (tail_x, y_cs_low), (tail_x, y_cs_high), (tail_x+10, y_cs_high)]
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in cs_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== SCLK 波形 ==========
+ sclk_pts = [(80, y_sclk_low), (start_x, y_sclk_low)]
+ for i in range(n_cycles):
+ rise = rise_edges[i]
+ fall = fall_edges[i]
+ sclk_pts.extend([
+ (rise, y_sclk_low),
+ (rise, y_sclk_high),
+ (fall, y_sclk_high),
+ (fall, y_sclk_low),
+ ])
+ sclk_pts.append((tail_x, y_sclk_low))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in sclk_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO0 波形 ==========
+ def build_wave_pts(bits, y_hi, y_lo, idle_y):
+ y0 = y_hi if bits[0] else y_lo
+ pts = [(80, y0), (start_x, y0)]
+ for i in range(len(bits)-1):
+ end_x = fall_edges[i]
+ y_curr = y_hi if bits[i] else y_lo
+ y_next = y_hi if bits[i+1] else y_lo
+ pts.append((end_x, y_curr))
+ if y_next != y_curr:
+ pts.append((end_x, y_next))
+ pts.append((end_x := fall_edges[len(bits)-1], y_hi if bits[-1] else y_lo))
+ pts.append((tail_x, pts[-1][1]))
+ return pts
+
+ io0_pts = build_wave_pts(all_io0, y_io0_high, y_io0_low, y_io0_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io0_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO1 波形 ==========
+ io1_pts = build_wave_pts(all_io1, y_io1_high, y_io1_low, y_io1_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io1_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== 命令 bit 标签(IO0 上方) ==========
+ cmd_labels = ["0","0","1","1","1","0","1","1"]
+ for i, val in enumerate(cmd_labels):
+ cx = rise_edges[i]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # ========== 阶段名称标签 ==========
+ stage_labels = [
+ (start_x + 4*cycle_w, "命令 (0x3B)", "#4CAF50"),
+ (start_x + 12*cycle_w, "地址 [23:16]", "#666666"),
+ (start_x + 20*cycle_w, "地址 [15:8]", "#666666"),
+ (start_x + 28*cycle_w, "地址 [7:0]", "#666666"),
+ (start_x + 34*cycle_w, "数据 (Dual)", "#2196F3"),
+ ]
+ for x, txt, color in stage_labels:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # ========== 数据阶段 bit 标签 ==========
+ data_labels_io0 = ["D0","D2","D4","D6"]
+ data_labels_io1 = ["D1","D3","D5","D7"]
+ for i in range(4):
+ cx = rise_edges[32 + i]
+ # IO0
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ # IO1
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append('')
+
+ return "\n".join(lines)
+
+xml_content = make_qspi_mxfile()
+output_path = "SPI_Waveform_QSPI.drawio"
+with open(output_path, "w", encoding="utf-8") as f:
+ f.write(xml_content)
+
+print("文件已生成:", output_path)
+```
\ No newline at end of file
diff --git a/docs/绘图/NTP 报文格式.drawio b/docs/绘图/NTP 报文格式.drawio
new file mode 100644
index 0000000..0d789e0
--- /dev/null
+++ b/docs/绘图/NTP 报文格式.drawio
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/NTP 报文格式.drawio.png b/docs/绘图/NTP 报文格式.drawio.png
new file mode 100644
index 0000000..b7ddf45
Binary files /dev/null and b/docs/绘图/NTP 报文格式.drawio.png differ
diff --git a/docs/绘图/QSPI_Waveform_Corrected.drawio b/docs/绘图/QSPI_Waveform_Corrected.drawio
new file mode 100644
index 0000000..b418800
--- /dev/null
+++ b/docs/绘图/QSPI_Waveform_Corrected.drawio
@@ -0,0 +1,428 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/SPI_QSPI.png b/docs/绘图/SPI_QSPI.png
new file mode 100644
index 0000000..288960f
Binary files /dev/null and b/docs/绘图/SPI_QSPI.png differ
diff --git a/docs/绘图/SPI_QSPI.py b/docs/绘图/SPI_QSPI.py
new file mode 100644
index 0000000..72286a7
--- /dev/null
+++ b/docs/绘图/SPI_QSPI.py
@@ -0,0 +1,207 @@
+import xml.etree.ElementTree as ET
+
+def make_qspi_mxfile():
+ # ========== 基础参数 ==========
+ y_cs_high, y_cs_low = 80, 110
+ y_sclk_high, y_sclk_low = 180, 210
+ y_io0_high, y_io0_low = 280, 310
+ y_io1_high, y_io1_low = 380, 410
+
+ # 时序参数:50px/周期,36个周期(8命令+24地址+4数据)
+ cycle_w = 50
+ start_x = 100
+ n_cycles = 36 # 8 + 24 + 4
+ end_x = start_x + n_cycles * cycle_w # 1900
+ tail_x = end_x + 50 # 1950
+
+ rise_edges = [start_x + i*cycle_w + cycle_w//2 for i in range(n_cycles)] # 125,175...
+ fall_edges = [start_x + (i+1)*cycle_w for i in range(n_cycles)] # 150,200...1900
+
+ # 数据定义
+ cmd_bits = [0,0,1,1,1,0,1,1] # 0x3B MSB first
+ addr_bytes = [
+ [0,0,0,1,0,0,1,0], # 0x12 A23-A16
+ [0,0,1,1,0,1,0,0], # 0x34 A15-A8
+ [0,1,0,1,0,1,1,0], # 0x56 A7-A0
+ ]
+ addr_bits = [b for byte in addr_bytes for b in byte]
+ data_io0 = [0,0,0,0] # D0,D2,D4,D6 (示例 0xAA)
+ data_io1 = [1,1,1,1] # D1,D3,D5,D7
+
+ all_io0 = cmd_bits + addr_bits + data_io0
+ all_io1 = [0]*32 + data_io1 # 命令地址期间 IO1 idle/low
+
+ lines = []
+ lines.append('')
+ lines.append('')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 背景
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 标题
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MSB / LSB
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 信号标签
+ for label, y, eid in [("CS", 85, "label_cs"), ("SCLK", 185, "label_sclk"),
+ ("IO0", 275, "label_io0"), ("IO1", 375, "label_io1")]:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 阶段分界虚线
+ boundaries = [
+ (start_x + 8*cycle_w, "cmd_addr"), # 500
+ (start_x + 16*cycle_w, "addr_mid1"), # 900
+ (start_x + 24*cycle_w, "addr_mid2"), # 1300
+ (start_x + 32*cycle_w, "addr_data"), # 1700
+ ]
+ for x, eid in boundaries:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== CS 波形 ==========
+ cs_pts = [(80, y_cs_high), (90, y_cs_high), (90, y_cs_low), (tail_x, y_cs_low), (tail_x, y_cs_high), (tail_x+10, y_cs_high)]
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in cs_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== SCLK 波形 ==========
+ sclk_pts = [(80, y_sclk_low), (start_x, y_sclk_low)]
+ for i in range(n_cycles):
+ rise = rise_edges[i]
+ fall = fall_edges[i]
+ sclk_pts.extend([
+ (rise, y_sclk_low),
+ (rise, y_sclk_high),
+ (fall, y_sclk_high),
+ (fall, y_sclk_low),
+ ])
+ sclk_pts.append((tail_x, y_sclk_low))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in sclk_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO0 波形 ==========
+ def build_wave_pts(bits, y_hi, y_lo, idle_y):
+ y0 = y_hi if bits[0] else y_lo
+ pts = [(80, y0), (start_x, y0)]
+ for i in range(len(bits)-1):
+ end_x = fall_edges[i]
+ y_curr = y_hi if bits[i] else y_lo
+ y_next = y_hi if bits[i+1] else y_lo
+ pts.append((end_x, y_curr))
+ if y_next != y_curr:
+ pts.append((end_x, y_next))
+ pts.append((end_x := fall_edges[len(bits)-1], y_hi if bits[-1] else y_lo))
+ pts.append((tail_x, pts[-1][1]))
+ return pts
+
+ io0_pts = build_wave_pts(all_io0, y_io0_high, y_io0_low, y_io0_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io0_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO1 波形 ==========
+ io1_pts = build_wave_pts(all_io1, y_io1_high, y_io1_low, y_io1_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io1_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== 命令 bit 标签(IO0 上方) ==========
+ cmd_labels = ["0","0","1","1","1","0","1","1"]
+ for i, val in enumerate(cmd_labels):
+ cx = rise_edges[i]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # ========== 阶段名称标签 ==========
+ stage_labels = [
+ (start_x + 4*cycle_w, "命令 (0x3B)", "#4CAF50"),
+ (start_x + 12*cycle_w, "地址 [23:16]", "#666666"),
+ (start_x + 20*cycle_w, "地址 [15:8]", "#666666"),
+ (start_x + 28*cycle_w, "地址 [7:0]", "#666666"),
+ (start_x + 34*cycle_w, "数据 (Dual)", "#2196F3"),
+ ]
+ for x, txt, color in stage_labels:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # ========== 数据阶段 bit 标签 ==========
+ data_labels_io0 = ["D0","D2","D4","D6"]
+ data_labels_io1 = ["D1","D3","D5","D7"]
+ for i in range(4):
+ cx = rise_edges[32 + i]
+ # IO0
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ # IO1
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append('')
+
+ return "\n".join(lines)
+
+xml_content = make_qspi_mxfile()
+output_path = "SPI_Waveform_QSPI.drawio"
+with open(output_path, "w", encoding="utf-8") as f:
+ f.write(xml_content)
+
+print("文件已生成:", output_path)
diff --git a/docs/绘图/SPI_Quad.drawio b/docs/绘图/SPI_Quad.drawio
new file mode 100644
index 0000000..dbef99e
--- /dev/null
+++ b/docs/绘图/SPI_Quad.drawio
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/SPI_Quad.png b/docs/绘图/SPI_Quad.png
new file mode 100644
index 0000000..52ea29d
Binary files /dev/null and b/docs/绘图/SPI_Quad.png differ
diff --git a/docs/绘图/SPI_Quad.py b/docs/绘图/SPI_Quad.py
new file mode 100644
index 0000000..fea971e
--- /dev/null
+++ b/docs/绘图/SPI_Quad.py
@@ -0,0 +1,300 @@
+import xml.etree.ElementTree as ET
+
+def make_qspi_quad_io_mxfile():
+ # ========== 基础参数定义 ==========
+ # Y坐标(高/低电平):严格遵循垂直间距100px规范
+ y_cs_high, y_cs_low = 80, 110
+ y_sclk_high, y_sclk_low = 180, 210
+ y_io0_high, y_io0_low = 280, 310
+ y_io1_high, y_io1_low = 380, 410
+ y_io2_high, y_io2_low = 480, 510
+ y_io3_high, y_io3_low = 580, 610
+
+ # 时序参数:50px/周期,总周期数=8(命令)+3(地址)+2(空周期)+2(数据)=15
+ cycle_w = 50
+ start_x = 100
+ n_cycles = 15
+ end_x = start_x + n_cycles * cycle_w # 100 + 15*50 = 850
+ tail_x = end_x + 50 # 900
+
+ # 时钟边沿计算(上升沿=采样沿,下降沿=输出沿)
+ rise_edges = [start_x + i*cycle_w + cycle_w//2 for i in range(n_cycles)] # 125,175...825
+ fall_edges = [start_x + (i+1)*cycle_w for i in range(n_cycles)] # 150,200...850
+
+ # ========== 数据定义 ==========
+ # 1. 命令阶段:IO0传输0xEB (11101011),MSB first;IO1-IO3 idle(0)
+ cmd_bits_io0 = [1,1,1,0,1,0,1,1] # 0xEB = b11101011
+ cmd_bits_io1 = [0]*8
+ cmd_bits_io2 = [0]*8
+ cmd_bits_io3 = [0]*8
+
+ # 2. 地址阶段:3个周期,4线并行传输地址位(示例地址0x123456的高12位)
+ # 地址0x123456 = 24位:0001 0010 0011 0100 0101 0110
+ # A23=0,A22=0,A21=0,A20=1 | A19=0,A18=0,A17=1,A16=0 | A15=0,A14=0,A13=1,A12=1
+ addr_bits_io0 = [0, 0, 0] # A23, A19, A15
+ addr_bits_io1 = [0, 0, 0] # A22, A18, A14
+ addr_bits_io2 = [0, 1, 1] # A21, A17, A13
+ addr_bits_io3 = [1, 0, 1] # A20, A16, A12
+
+ # 3. 空周期:2个周期,所有IO idle(0)
+ dummy_bits = [0]*2
+
+ # 4. 数据阶段:2个周期传输1字节(0xAA=10101010),4线并行
+ # D0=1,D1=0,D2=1,D3=0 | D4=1,D5=0,D6=1,D7=0
+ data_bits_io0 = [1, 1] # D0, D4
+ data_bits_io1 = [0, 0] # D1, D5
+ data_bits_io2 = [1, 1] # D2, D6
+ data_bits_io3 = [0, 0] # D3, D7
+
+ # 合并所有阶段的bit序列
+ all_io0 = cmd_bits_io0 + addr_bits_io0 + dummy_bits + data_bits_io0
+ all_io1 = cmd_bits_io1 + addr_bits_io1 + dummy_bits + data_bits_io1
+ all_io2 = cmd_bits_io2 + addr_bits_io2 + dummy_bits + data_bits_io2
+ all_io3 = cmd_bits_io3 + addr_bits_io3 + dummy_bits + data_bits_io3
+
+ # ========== 波形构建函数 ==========
+ def build_wave_pts(bits, y_hi, y_lo):
+ """生成波形点,确保无斜线、边沿对齐"""
+ y0 = y_hi if bits[0] else y_lo
+ pts = [(80, y0), (start_x, y0)] # 起始过渡段
+ for i in range(len(bits)-1):
+ curr_fall = fall_edges[i]
+ y_curr = y_hi if bits[i] else y_lo
+ y_next = y_hi if bits[i+1] else y_lo
+
+ # 添加当前bit的水平段终点(下降沿)
+ pts.append((curr_fall, y_curr))
+ # 电平变化则在下降沿垂直跳变
+ if y_next != y_curr:
+ pts.append((curr_fall, y_next))
+ # 最后一个bit的终点 + 尾部过渡段
+ last_fall = fall_edges[len(bits)-1]
+ pts.append((last_fall, y_hi if bits[-1] else y_lo))
+ pts.append((tail_x, pts[-1][1]))
+ return pts
+
+ # ========== 生成XML内容 ==========
+ lines = []
+ # 文件头
+ lines.append('')
+ lines.append('')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 背景网格
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 标题
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MSB/LSB标记
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 信号标签(左侧)
+ signal_labels = [
+ ("CS", 85, "label_cs"),
+ ("SCLK", 185, "label_sclk"),
+ ("IO0", 275, "label_io0"),
+ ("IO1", 375, "label_io1"),
+ ("IO2", 475, "label_io2"),
+ ("IO3", 575, "label_io3")
+ ]
+ for label, y, eid in signal_labels:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 阶段分界虚线(命令/地址/空周期/数据)
+ boundaries = [
+ (start_x + 8*cycle_w, "cmd_addr"), # 命令结束: 100+400=500
+ (start_x + 11*cycle_w, "addr_dummy"),# 地址结束: 100+550=650
+ (start_x + 13*cycle_w, "dummy_data"),# 空周期结束:100+650=750
+ ]
+ for x, eid in boundaries:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== CS 波形 ==========
+ cs_pts = [(80, y_cs_high), (90, y_cs_high), (90, y_cs_low),
+ (tail_x, y_cs_low), (tail_x, y_cs_high), (tail_x+10, y_cs_high)]
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in cs_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== SCLK 波形 ==========
+ sclk_pts = [(80, y_sclk_low), (start_x, y_sclk_low)]
+ for i in range(n_cycles):
+ rise = rise_edges[i]
+ fall = fall_edges[i]
+ sclk_pts.extend([
+ (rise, y_sclk_low),
+ (rise, y_sclk_high),
+ (fall, y_sclk_high),
+ (fall, y_sclk_low),
+ ])
+ sclk_pts.append((tail_x, y_sclk_low))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in sclk_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO0 波形 ==========
+ io0_pts = build_wave_pts(all_io0, y_io0_high, y_io0_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io0_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO1 波形 ==========
+ io1_pts = build_wave_pts(all_io1, y_io1_high, y_io1_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io1_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO2 波形 ==========
+ io2_pts = build_wave_pts(all_io2, y_io2_high, y_io2_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io2_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== IO3 波形 ==========
+ io3_pts = build_wave_pts(all_io3, y_io3_high, y_io3_low)
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in io3_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # ========== 阶段名称标注 ==========
+ stage_labels = [
+ (start_x + 4*cycle_w, "命令 (0xEB)", "#4CAF50"), # 命令阶段中心
+ (start_x + 9.5*cycle_w, "地址 (Quad)", "#666666"), # 地址阶段中心
+ (start_x + 12*cycle_w, "空周期 (2)", "#666666"), # 空周期中心
+ (start_x + 14*cycle_w, "数据 (Quad 0xAA)", "#2196F3"), # 数据阶段中心
+ ]
+ for x, txt, color in stage_labels:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # ========== 数据位标签 ==========
+ # 1. 命令阶段IO0 bit标签
+ for i in range(8):
+ cx = rise_edges[i]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 2. 地址阶段bit标签
+ addr_io_labels = [
+ (8, "A23", "A19", "A15", "#4CAF50"), # IO0
+ (8, "A22", "A18", "A14", "#9C27B0"), # IO1
+ (8, "A21", "A17", "A13", "#FFC107"), # IO2
+ (8, "A20", "A16", "A12", "#607D8B"), # IO3
+ ]
+ for io_idx, label1, label2, label3, color in addr_io_labels:
+ # 地址阶段第1个周期(总第9个周期)
+ cx = rise_edges[io_idx]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ # 地址阶段第2个周期(总第10个周期)
+ cx = rise_edges[io_idx+1]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ # 地址阶段第3个周期(总第11个周期)
+ cx = rise_edges[io_idx+2]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 3. 数据阶段bit标签
+ data_io_labels = [
+ (13, "D0", "D4", "#4CAF50"), # IO0
+ (13, "D1", "D5", "#9C27B0"), # IO1
+ (13, "D2", "D6", "#FFC107"), # IO2
+ (13, "D3", "D7", "#607D8B"), # IO3
+ ]
+ for io_idx, label1, label2, color in data_io_labels:
+ # 数据阶段第1个周期(总第14个周期)
+ cx = rise_edges[io_idx]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ # 数据阶段第2个周期(总第15个周期)
+ cx = rise_edges[io_idx+1]
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 文件尾
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append('')
+
+ return "\n".join(lines)
+
+# 生成并保存文件
+xml_content = make_qspi_quad_io_mxfile()
+output_path = "SPI_Quad.drawio"
+with open(output_path, "w", encoding="utf-8") as f:
+ f.write(xml_content)
+
+print(f"波形图文件已生成: {output_path}")
\ No newline at end of file
diff --git a/docs/绘图/SPI_Waveform_CPHA0.drawio b/docs/绘图/SPI_Waveform_CPHA0.drawio
new file mode 100644
index 0000000..bac044f
--- /dev/null
+++ b/docs/绘图/SPI_Waveform_CPHA0.drawio
@@ -0,0 +1,967 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/SPI_Waveform_CPHA0.png b/docs/绘图/SPI_Waveform_CPHA0.png
new file mode 100644
index 0000000..5eebe78
Binary files /dev/null and b/docs/绘图/SPI_Waveform_CPHA0.png differ
diff --git a/docs/绘图/SPI_Waveform_CPHA0.py b/docs/绘图/SPI_Waveform_CPHA0.py
new file mode 100644
index 0000000..e122838
--- /dev/null
+++ b/docs/绘图/SPI_Waveform_CPHA0.py
@@ -0,0 +1,197 @@
+import xml.etree.ElementTree as ET
+
+def make_mxfile():
+ # 基础参数
+ y_cs_high, y_cs_low = 80, 110
+ y_sclk_high, y_sclk_low = 180, 210
+ y_mosi_high, y_mosi_low = 280, 310
+ y_miso_high, y_miso_low = 380, 410
+
+ # 8个bit周期,每个100px,从x=100开始,到x=900结束
+ rise_edges = [150, 250, 350, 450, 550, 650, 750, 850]
+ fall_edges = [190, 290, 390, 490, 590, 690, 790, 890]
+
+ # MOSI: 0x5A = 0b01011010, MSB first
+ mosi_bits = [0, 1, 0, 1, 1, 0, 1, 0]
+ # MISO: 0xA5 = 0b10100101, MSB first
+ miso_bits = [1, 0, 1, 0, 0, 1, 0, 1]
+
+ lines = []
+ lines.append('')
+ lines.append('')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 背景网格
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 标题
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MSB / LSB
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # 信号标签
+ for label, y, eid in [("CS", 85, "label_cs"), ("SCLK", 185, "label_sclk"),
+ ("MOSI", 275, "label_mosi"), ("MISO", 365, "label_miso")]:
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 垂直参考虚线(放在每个上升沿采样点)
+ for i, x in enumerate(rise_edges):
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # CS 波形
+ cs_points = [
+ (80, y_cs_high), (90, y_cs_high), (90, y_cs_low), (910, y_cs_low),
+ (910, y_cs_high), (920, y_cs_high)
+ ]
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in cs_points[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # SCLK 波形
+ sclk_pts = [(80, y_sclk_low), (100, y_sclk_low)]
+ for rise, fall in zip(rise_edges, fall_edges):
+ sclk_pts.extend([
+ (rise, y_sclk_low),
+ (rise, y_sclk_high),
+ (fall, y_sclk_high),
+ (fall, y_sclk_low),
+ ])
+ sclk_pts.append((920, y_sclk_low))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in sclk_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MOSI 波形
+ mosi_start_y = y_mosi_high if mosi_bits[0] else y_mosi_low
+ mosi_pts = [(80, mosi_start_y), (100, mosi_start_y)]
+ for i, bit in enumerate(mosi_bits):
+ y_level = y_mosi_high if bit else y_mosi_low
+ end_x = fall_edges[i] if i < len(fall_edges) else 900
+ mosi_pts.append((end_x, y_level))
+ if i + 1 < len(mosi_bits):
+ y_next = y_mosi_high if mosi_bits[i+1] else y_mosi_low
+ if y_next != y_level:
+ mosi_pts.append((end_x, y_next))
+ mosi_pts.append((920, mosi_pts[-1][1]))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in mosi_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MISO 波形 — 修复:sourcePoint 与第一个中间点同 y,避免斜线
+ miso_start_y = y_miso_high if miso_bits[0] else y_miso_low
+ miso_pts = [(80, miso_start_y), (100, miso_start_y)]
+ for i, bit in enumerate(miso_bits):
+ y_level = y_miso_high if bit else y_miso_low
+ end_x = fall_edges[i] if i < len(fall_edges) else 900
+ miso_pts.append((end_x, y_level))
+ if i + 1 < len(miso_bits):
+ y_next = y_miso_high if miso_bits[i+1] else y_miso_low
+ if y_next != y_level:
+ miso_pts.append((end_x, y_next))
+ miso_pts.append((920, miso_pts[-1][1]))
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+ for x, y in miso_pts[1:-1]:
+ lines.append(f' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ # MOSI 数据位标签
+ mosi_centers = [145, 240, 340, 440, 540, 640, 740, 840]
+ for i, (bit, cx) in enumerate(zip(mosi_bits, mosi_centers)):
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # MISO 数据位标签
+ miso_centers = [145, 240, 340, 440, 540, 640, 740, 840]
+ for i, (bit, cx) in enumerate(zip(miso_bits, miso_centers)):
+ lines.append(f' ')
+ lines.append(f' ')
+ lines.append(' ')
+
+ # 数据包标注
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+
+ lines.append(' ')
+ lines.append(' ')
+ lines.append(' ')
+ lines.append('')
+
+ return "\n".join(lines)
+
+xml_content = make_mxfile()
+output_path = "SPI_Waveform_CPHA0_Corrected.drawio"
+with open(output_path, "w", encoding="utf-8") as f:
+ f.write(xml_content)
+
+# 验证 MISO 起始点
+import re
+with open(output_path, "r", encoding="utf-8") as f:
+ content = f.read()
+
+match = re.search(r'id="miso".*?(.*?)', content, re.DOTALL)
+if match:
+ pts = re.findall(r'', match.group(1))
+ print("MISO 点:")
+ for x, y in pts[:4]:
+ print(f" ({x}, {y})")
+ src = re.search(r'id="miso".*?', content)
+ if src:
+ print(f"sourcePoint: ({src.group(1)}, {src.group(2)})")
+
+print("\n文件已保存:", output_path)
diff --git a/docs/绘图/SPI_Waveform_QSPI.drawio b/docs/绘图/SPI_Waveform_QSPI.drawio
new file mode 100644
index 0000000..a97cf23
--- /dev/null
+++ b/docs/绘图/SPI_Waveform_QSPI.drawio
@@ -0,0 +1,396 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/绘图/ops 作用.png b/docs/绘图/ops 作用.png
new file mode 100644
index 0000000..8fd6370
Binary files /dev/null and b/docs/绘图/ops 作用.png differ
diff --git a/docs/绘图/test.drawio b/docs/绘图/test.drawio
new file mode 100644
index 0000000..baf8ff5
--- /dev/null
+++ b/docs/绘图/test.drawio
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/事件驱动时序图.png b/docs/绘图/事件驱动时序图.png
new file mode 100644
index 0000000..b27fdae
Binary files /dev/null and b/docs/绘图/事件驱动时序图.png differ
diff --git a/docs/绘图/工厂模式.drawio b/docs/绘图/工厂模式.drawio
new file mode 100644
index 0000000..5b76a92
--- /dev/null
+++ b/docs/绘图/工厂模式.drawio
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/工厂模式.png b/docs/绘图/工厂模式.png
new file mode 100644
index 0000000..5ca4ccc
Binary files /dev/null and b/docs/绘图/工厂模式.png differ
diff --git a/docs/绘图/新建 文本文档.drawio b/docs/绘图/新建 文本文档.drawio
new file mode 100644
index 0000000..94b4c88
--- /dev/null
+++ b/docs/绘图/新建 文本文档.drawio
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/系统架构.drawio b/docs/绘图/系统架构.drawio
new file mode 100644
index 0000000..d0672b0
--- /dev/null
+++ b/docs/绘图/系统架构.drawio
@@ -0,0 +1,680 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/系统架构.png b/docs/绘图/系统架构.png
new file mode 100644
index 0000000..994d377
Binary files /dev/null and b/docs/绘图/系统架构.png differ
diff --git a/docs/绘图/网络硬件方案.drawio b/docs/绘图/网络硬件方案.drawio
new file mode 100644
index 0000000..c0cac6e
--- /dev/null
+++ b/docs/绘图/网络硬件方案.drawio
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/网络硬件方案.png b/docs/绘图/网络硬件方案.png
new file mode 100644
index 0000000..8b30f0b
Binary files /dev/null and b/docs/绘图/网络硬件方案.png differ
diff --git a/docs/绘图/软件架构.drawio b/docs/绘图/软件架构.drawio
new file mode 100644
index 0000000..3d31bbd
--- /dev/null
+++ b/docs/绘图/软件架构.drawio
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/绘图/配电自动化系统基本架构示意图.drawio b/docs/绘图/配电自动化系统基本架构示意图.drawio
new file mode 100644
index 0000000..61d2ce0
--- /dev/null
+++ b/docs/绘图/配电自动化系统基本架构示意图.drawio
@@ -0,0 +1,260 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/data.h b/src/data.h
new file mode 100644
index 0000000..2b129b9
--- /dev/null
+++ b/src/data.h
@@ -0,0 +1,145 @@
+#ifndef __DATA_H__
+#define __DATA_H__
+#include "types.h"
+
+
+// BCD码方式时标数据结构
+typedef struct
+{
+ uint8_t byYear_L; // 年(低位)
+ uint8_t byYear_H; // 年(高位) 默认为0x20
+ uint8_t byMonth; // 月
+ uint8_t byDay; // 日
+ uint8_t byHour; // 时
+ uint8_t byMinute; // 分
+ uint8_t bySecond; // 秒
+ uint8_t byMS_L; // 毫秒(低位)
+ uint8_t byMS_H; // 毫秒(高位)
+ uint8_t byWeek; // 星期
+ uint8_t byRes[2]; // 备用字节(配齐4的整数倍)
+ uint32_t dwRamScan; // 扫描内存片
+}tagTimeBCD,*tagPTimeBCD;
+
+
+// 板间控制信息结构体
+typedef struct
+{
+ uint8_t bySamCnt[2]; // ARM核采样计数器(0:ARM核;1DSP核)
+ uint8_t bySysLock; // 系统闭锁标记(0:正常;CN_FLAG_TRUE:异常)
+ uint8_t bySysSig; // 系统信号标记(DB0:运行;DB1:自检异常;DB2:运行异常)
+ uint32_t iFpgaCmp; // 中断频率比较寄存器补偿值
+}tagBoardCtrl;
+// 开出资源区结构(包括正/反码)
+typedef struct
+{
+ uint32_t dwKOBuf[2];
+ uint32_t dwKONot[2];
+}tagKOBuf;
+// CPU运行信息结构体
+typedef struct
+{
+ uint32_t dwCPURun; // 上电运行标记
+ uint32_t dwSysLock; // 系统闭锁标记(本核组件自检)
+ uint32_t dwSysLockMerge; // 系统闭锁标记(汇总各板件)
+ uint32_t dwSamCnt; // 中断计数器
+ tagKOBuf tALLKOBuf; // 总开出状态数据区
+}tagCPURunInfo;
+// 模拟量向量(测量)
+typedef struct
+{
+ int32_t iAmp; // 幅值(开方)
+ uint16_t wAngle; // 相角
+ uint16_t wRes; // 备用
+}tagVectorMea;
+
+// 遥测量(遥测)
+typedef struct
+{
+ uint16_t wAngle; // 相角
+ float fValue4[4]; // 测量有效值依次存放4次
+ int32_t iValue; // 最终显示上送值
+ int32_t iValueBak; // 上次上送值,用于死区计算
+ uint16_t wUpDate; // 更新标志(变化大于死区范围)
+ uint16_t wIEC103Quality; // 103上送遥测品质
+ uint16_t wIEC103YCValue; // 103上送遥测数值
+ uint16_t wIEC103Inf; // 103上送inf
+ uint16_t wIEC103YCClass; // 103上送等级
+}tagYCVecMea;
+// 谐波量(遥测)
+typedef struct
+{
+ int32_t iReal; // 各次谐波的实际值
+ uint16_t wRatio; // 各次谐波的与有效值的比值
+}tagHumWave; // 谐波结构
+// 双核间信息交互区结构
+typedef struct
+{
+ uint32_t dwRamScan1; // 内存扫描点
+ tagTimeBCD tTimeBCD; // 系统时间
+ tagBoardCtrl tBoardCtrl[2]; // 板间控制信息结构体(0区:本板区 其他区:根据插槽号存储)
+ uint32_t dwCalSoftFrFlag; // 测得新频率标志
+ uint32_t dwFpgaCmpSam; // 中断频率比较寄存器补偿值(本板区)
+ uint32_t dwFpgaCmpUse; // 中断频率比较寄存器补偿值(使用区=本板区+LVDS总线接收区)
+ uint32_t dwRamScan2; // 内存扫描点
+ uint16_t wFaultNumARM; // 系统故障序号(ARM主机使用;上电时从IIC读出)
+ uint16_t wFaultNumDSP; // 系统故障序号(DSP主机使用;由录波组件累加)
+ uint32_t dwWaveHandFlg; // 指向外部请求手动录波标志,0--无请求手动录波,CN_FLAG_TRUE--请求手动录波,手动录波响应后由录波组件清0
+ uint32_t dwWaveStartFlg; // 录波已启动标记,0--未启动,CN_FLAG_TRUE--已启动
+ uint32_t dwClrFaultNum; // 清除系统故障序号标志(CN_FLAG_TRUE--清除故障序号)
+ uint32_t dwOpenDebugKO; // 开出DEBUG开放使能标志("CN_FLAG_TRUE"--DEBUG开放使能, 其它--DEBUG不开放使能)
+ uint32_t dwCPUKI; // 上电遥信读取标志 0:上电状态,0x55:等待3个中断后读取开入完毕,0xAA:遥信初始化,0xBB 初始化结束。
+ uint32_t dwGpsType; // GPS类型标志(=0x00无GPS =0x33IRIG =0x55分脉冲 =0xaa秒脉冲)
+ uint16_t wCommFlag; //外通讯标志
+ uint16_t wArmRunCnt; //ARM核运行计数
+ uint8_t bFlagGetDrvTime;
+ uint8_t bFlagCompareTime; // 第一次上电中断中置1,上电500ms后,比较软硬件时钟
+ uint8_t SignKoFlag[16]; //线路1~16故障信号开出量
+ uint32_t dwRamScan3; // 内存扫描点
+ tagCPURunInfo tRunInfoARM; // ARM核运行信息
+ tagCPURunInfo tRunInfoDSP; // DSP核运行信息
+ uint32_t dwRamScan4; // 内存扫描点
+ uint32_t dwBufKIHld [2]; // 开入量采样数据区(本板防抖区,按BIT存储)
+ uint32_t dwBufKIMsg [2]; // 开入量采样数据区(本板报文区,按BIT存储)
+ uint32_t dwBufKIUseBit [2]; // 开入量采样数据区(使用值,按BIT存储)
+ uint32_t dwBufKIUseWord[2][2]; // 开入量采样数据区(DSP核)(使用值,按DWORD存储, 有开入--CN_FLAG_TRUE)
+ uint32_t dwRamScan5; // 内存扫描点
+ uint32_t dwSoftFRQ; // 软件测频结果(放大100倍)(DSP测频,ARM调频)
+ uint32_t dwVecNum; // 需要计算的模拟量通道数<基波>
+ uint32_t dwVecS2Num; // 需要计算的模拟量通道数<二次谐波>
+ uint32_t dwVecS3Num; // 需要计算的模拟量通道数<二次谐波>
+ uint32_t dwVecS5Num; // 需要计算的模拟量通道数<二次谐波>
+ tagVectorMea tVectorMea[2][2]; // 模拟量向量(DSP核)(测量用)
+ uint32_t dwRamScan6; // 扫描内存片
+ tagYCVecMea tYCVecMea[2]; // 遥测量(DSP核)(遥测用)
+ uint32_t dwRamScan7; // 扫描内存片
+ tagHumWave tHumWave[2*(2+1)]; // 谐波量(DSP核)(遥测用)
+ uint32_t dwYFBSHZ; // 遥控闭锁合闸
+ uint32_t dwJLDataYM[128]; // 计量数据
+ uint32_t dwHoldLED[32]; // 需保持点灯
+ uint8_t byLedData[8];
+ uint8_t byUlogFlag[14];
+ uint8_t byTxFlag; // 通讯灯点灯标志
+ uint8_t byTxgFlag[8]; // 通讯灯点灯标志
+ uint32_t dwErrorNum;
+ uint32_t dwWaveEnd;
+ uint8_t byStartFlg[3];
+ uint8_t byFHZ_Flag; // 分合闸标志
+ uint8_t byHw_Flag; // 合位遥信用于点灯--20200319
+ uint8_t byWcn_Flag; // 未储能遥信用于点灯--20200319
+
+ uint32_t dwFGFlag; // 复归开入状态
+ uint32_t dwFAZBSFlag; // FA总闭锁状态
+ uint32_t dwFAZBSFlag1; // FA总闭锁状态
+ uint16_t wFZDBSFZ[8]; // 非遮断闭锁分闸
+ uint16_t wCoeData[17];
+ uint16_t wDspRunFlag;
+ uint8_t byYXData[32]; // 共享遥信内容
+ uint8_t bPhaserrFlag[3]; // 故障相别标志
+ uint8_t SwitchO; // 继电器执行合闸操作 g_tShareData.SwitchO
+ uint8_t SwitchT; // 继电器执行分闸操作 g_tShareData.SwitchT
+ uint8_t byTestData[64];
+ float fTestData[34];
+ uint32_t dwRamScan8; // 扫描内存片
+}tagShareData;
+
+#endif