任务要求是这样的,64×64的光电探测器阵列,我要读取出该阵列的电流,并将它们转换为对数形式,再让后一个时刻与前一时刻的对数电流值相减(打算用采样保持和减法器),这个差值再与阈值比较,输出比较结果(超过正负阈值与否),此外还需要得到超出阈值的光电探测器的行列坐标。
就是这么复杂的一个系统,打算逐列扫,然后行并行读取,我现在不知道该如何在尽可能低的延时下并行读取64行数据,肯定不可能设计64条读取通路,那该采用什么方法呢?太折磨了!恳请佬们说说想法,谢谢!
阵列电流读取系统设计
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
4条回答 默认 最新
檀越@新空间 2026-03-05 15:23关注下午好🌅🌅🌅
本答案参考通义千问这是一个非常具有挑战性的嵌入式系统设计任务,涉及到高速电流读取、对数转换、差分处理、阈值比较以及坐标提取。你提到的“逐列扫描,行并行读取”是合理的思路,但要实现低延时和高效率,需要从硬件和软件两个层面进行优化。
一、系统总体架构设计
1. 系统功能分解
- 64×64光电探测器阵列:每个像素输出电流信号。
- 逐列扫描:每列依次激活(控制开关),将该列的64个像素的电流信号送入读取通道。
- 行并行读取:在每一列被激活后,同时读取64行的电流信号。
- 对数转换:将电流信号转换为对数形式(如log(I))。
- 差分处理:计算当前时刻与前一时刻的对数电流差值。
- 阈值比较:判断差值是否超过正负阈值。
- 坐标提取:记录超出阈值的像素行列坐标。
二、关键问题分析与解决方案
2. 如何在低延时下并行读取64行数据?
核心问题:
- 无法为每行设计独立的读取通路(成本高、复杂度高)。
- 需要在每列激活时,同时读取64行的数据。
解决方案:
✅ 方案一:使用多路复用器 + ADC + 采样保持电路
-
原理:
- 每列激活后,通过**多路复用器(MUX)**将64行的电流信号依次输入到一个ADC中。
- 使用**采样保持电路(Sample and Hold, S/H)**在每一行读取时保持电流值不变,避免ADC转换期间信号变化导致误差。
-
优点:
- 降低硬件复杂度,仅需一个ADC。
- 可以实现低延时的行并行读取。
-
缺点:
- 转换时间较长,若ADC速度不够,可能影响整体性能。
-
代码示例(伪代码):
// 假设有一个8位ADC,支持16个通道 void read_column(int col_index) { for (int row = 0; row < 64; row++) { select_mux_channel(row); // 选择第row行 hold_current(); // 采样保持 adc_value[row] = read_adc(); // 读取ADC值 } }✅ 方案二:采用行并行电流采集芯片(如AD7991、ADS1256等)
-
原理:
- 使用具备多个模拟输入通道的ADC芯片(如ADS1256有8个通道),配合外部MUX扩展至64通道。
- 在每一列激活时,通过MUX切换64行的电流信号,分别送入ADC的各个通道。
- 由于ADC是同步采样的,可以实现行并行读取。
-
优点:
- 高精度、高速度。
- 支持多通道并行采集。
-
缺点:
- 需要额外的MUX和ADC芯片,成本略高。
-
代码示例(伪代码):
// 使用ADS1256,8通道,通过MUX扩展到64通道 void read_column(int col_index) { for (int row = 0; row < 64; row++) { select_mux_row(row); // 选择第row行 adc_values[row] = read_ads1256_channel(row % 8); // 读取对应通道 } }✅ 方案三:采用数字信号处理器(DSP)或FPGA进行并行处理
-
原理:
- 利用FPGA或DSP的并行处理能力,设计流水线结构。
- 在每一列激活后,将64行的电流信号并行输入到不同的处理单元中,进行对数转换、差分计算和阈值比较。
-
优点:
- 极高的实时性。
- 可扩展性强。
-
缺点:
- 开发难度较高,需要熟悉FPGA开发工具(如Vivado、Quartus)。
三、对数转换与差分处理
3. 对数转换方法
-
硬件实现:
- 使用对数放大器(如LMC6001、MAX4206等)直接将电流信号转换为对数值。
-
软件实现:
- 通过ADC采集电流值,再在MCU或FPGA中进行对数运算(如
log(current))。
- 通过ADC采集电流值,再在MCU或FPGA中进行对数运算(如
-
推荐方式:
- 如果电流范围较大,建议使用硬件对数放大器,提高精度和响应速度。
4. 差分处理(Current Difference)
-
原理:
- 保存上一时刻的对数电流值(
prev_log_current)。 - 当前时刻的对数电流值为
curr_log_current。 - 计算差值:
diff = curr_log_current - prev_log_current。
- 保存上一时刻的对数电流值(
-
代码示例(伪代码):
float diff = curr_log_current[row] - prev_log_current[row];
四、阈值比较与坐标提取
5. 阈值比较逻辑
-
设定正负阈值(如
threshold = 0.1)。 -
若
abs(diff) > threshold,则认为该像素发生显著变化。 -
代码示例(伪代码):
for (int row = 0; row < 64; row++) { if (abs(diff[row]) > threshold) { // 记录该像素的坐标 record_coordinate(col_index, row); } }
五、系统优化建议
6. 降低延时的方法
| 优化点 | 方法 | |--------|------| | ADC转换时间 | 选用高速ADC(如1MSPS以上) | | Mux切换时间 | 使用低延迟Mux(如CD4051、CD74HC4067) | | 数据传输 | 使用SPI或I²C接口进行快速通信 | | 并行处理 | 使用FPGA或DSP进行并行计算 | | 内存缓存 | 使用双缓冲技术存储前一帧数据 |
六、总结与推荐方案
最终推荐方案(最可行且高效)
-
硬件部分:
- 使用多路复用器 + 高速ADC + 采样保持电路,实现逐列扫描、行并行读取。
- 选择对数放大器(如MAX4206)进行电流到对数信号的转换。
-
软件部分:
- 在MCU或FPGA中实现差分计算、阈值比较和坐标记录。
- 使用双缓冲技术保存前一帧数据,用于差分计算。
-
开发工具:
- 推荐使用 STM32 或 FPGA(Xilinx Artix-7) 进行开发。
七、代码示例(完整流程)
// 伪代码:主循环 while (true) { for (int col = 0; col < 64; col++) { activate_column(col); // 激活当前列 for (int row = 0; row < 64; row++) { select_mux_row(row); // 选择当前行 hold_current(); // 采样保持 float current = read_adc(); // 读取ADC值 float log_current = log(current); // 对数转换 float diff = log_current - prev_log_current[row]; // 差分 if (abs(diff) > threshold) { record_coordinate(col, row); // 记录坐标 } } update_prev_log_current(); // 更新前一帧数据 } }
如果你有具体的硬件平台(如STM32、FPGA型号)或ADC型号,我可以进一步提供更详细的代码和配置方案。希望这些思路能帮助你解决这个复杂的系统设计问题!
解决 无用评论 打赏 举报