简介:线阵CCD驱动电路在非接触式工件尺寸测量中应用广泛,但传统设计常受限于实现复杂、单片机驱动速度慢、计数分频法灵活性差,且难以随环境光强调整光积分时间,容易出现输出饱和失真或景物与背景难以区分的问题。这份面向CCD硬件设计与数码相机相关开发者的技术文档,给出一种不改变系统主频即可动态控制光积分时间的驱动方案,采用EPM7032C44可编程逻辑器件通过调节光转移脉冲周期实现,并已应用于带钢纵切机组自动对中系统。文中完整梳理CCD的MOS结构与TCD1206UD光敏元阵列、转移脉冲与复位脉冲等驱动波形时序,以及空驱动延长积分时间的具体做法,可作为驱动电路设计与调试的参考。资源包为1个doc文件,约120KB,已有271人学习下载,适合需要快速理解动态驱动思路的工程师查阅。
1. 从一次饱和失真说起:线阵CCD驱动电路为什么要动态控制光积分时间
某次纵切机组对中工位反复出现输出波形削顶,现场先擦镜头、换光源,问题依旧。根因不在光学件,而是线阵CCD驱动电路把光积分时间写死了:背景光一强,CCD输出就饱和;背景光一弱,物体和背景又糊在一起。这份设计资料给了一条不改变系统主频的思路——用CPLD动态控制光积分时间,按背景光强调整空驱动数量,让CCD始终落在输出信号的线性区。数码相机里的CCD硬件设计讲究曝光控制,搬到工业线阵扫描场景,核心同样是“积分窗口”而不是单纯换镜头。适合做CCD硬件设计、CPLD时序开发和工业视觉采集的开发者。
2. 方案定位与技术选型:CPLD、单片机、计数分频三种CCD驱动路线的取舍
2.1 三种传统驱动方案的实际短板
线阵CCD的驱动信号不是“给个时钟就能出图”。转移脉冲SH决定电荷从光敏元搬进模拟移位寄存器,φ1、φ2负责把电荷一級一級推到输出端,复位脉冲φR决定OS端每次输出后的复位节拍。驱动电路一旦把SH周期固定,光积分时间就固定,环境光变强时输出幅度跟着涨,涨到电源轨附近就是饱和失真;环境光变弱时信号幅度掉下去,背景和物体在A/D量化后挤在同一小段码值里,后续算法再厉害也分不开。
常见做法里,直接数字电路驱动法用门电路和计数器搭时序,逻辑一多,飞线、改板、调试都麻烦;单片机驱动法靠软件翻转IO,频率低,遇到高速线阵CCD时一个中断抖动就把时序带偏;计数分频法改积分时间要动主频或计数器初值,主频一动,模拟通道的滤波器参数、A/D采样节拍都得跟着重算,改计数初值又可能把驱动波形占空比带歪。这三种路线本质都是静态驱动,光积分时间不随背景光强走。
| 方案 | 实现方式 | 实际短板 | 适用场景 |
|---|---|---|---|
| 直接数字电路 | 门电路+计数器搭时序 | 改一版要重新布线,调试困难 | 时序固定、产量极大的简单产品 |
| 单片机驱动 | 软件翻转IO或定时器输出 | 频率低,中断抖动影响时序 | 低速、低成本、非连续采集 |
| 计数分频法 | 改主频或计数器初值 | 主频影响模拟通道,初值影响波形 | 光强稳定的封闭环境 |
| CPLD动态控制 | 硬件计数器+微处理器预置 | 需要时序仿真和引脚规划 | 光强变化、要求连续扫描的工业场景 |
这张表里最值得关注的是最后一行:CPLD把时序发生放在硬件里,主频不动,只改“空驱动数量”来拉长或缩短SH周期。数码相机里的CCD硬件设计把曝光时间当成可调参数,工业线阵把这套思路放到连续扫描场景,难点变成时序不能抖、主频不能动、参数要能被微处理器在线改。选CPLD不是为了追新,而是因为它刚好卡在“硬件时序稳定”和“参数可在线配置”之间。
2.2 动态光积分时间方案的架构拆解
这套方案的闭环不复杂:线阵CCD采集到的信号先过抗干扰电路,再进A/D转换,转换结果存储后送给微处理器;微处理器对一段数据做峰值、均值或饱和点统计,判断当前背景光偏强还是偏弱,算出一个光积分延时预置值,写到CPLD的Data总线;CPLD用统一主频T0产生SH、φ1、φ2、φR,其中SH周期由基本计数器和光积分延时预置计数器共同决定。背景光强时,预置值让空驱动数量变少,积分时间短;背景光弱时,空驱动数量变多,积分时间长。
这里的关键约束是“不改变系统主频”。主频T0同时喂给φ1、φ2、φR和SH计数器,模拟通道的采样节拍、滤波器的截止频率、A/D的转换窗口都按T0设计。改主频等于把模拟侧重新调一遍,现场没有那么多时间。改空驱动数量只动SH周期,φ1、φ2的节拍不变,A/D照旧采样,软件只需要改一个12位预置值。
架构上可以把它拆成四块:CCD像元与模拟移位寄存器、驱动缓冲与电平转换、CPLD时序核心、微处理器闭环。CPLD的IO驱动能力有限,常见做法是加一级缓冲器再进CCD,避免长线负载把上升沿拖慢;微处理器和CPLD之间用数据总线或SPI这类接口传预置值,写入时机放在SH下降沿之后,避开正在计数的窗口。这个细节在后面避坑章会展开,现场很多“图像随机撕裂”就是写参数写在了错误节拍上。
2.3 器件与工具链:EPM7032C44、Verilog与主频约束
资料里用的CPLD是EPM7032C44,资源不算大,逻辑不能铺得太散。用它做线阵CCD驱动,核心就是几个计数器、几个比较器和一个SH输出,刚好够用。开发流程一般是:建工程、选器件、写Verilog、做时序仿真、分配引脚、综合、下载、用示波器量四路波形。没有硬件时也可以先跑仿真,把基本计数器的2236、延时计数器的4095、SH脉宽的500这几个边界扫一遍,比直接上板子盲调省时间。
引脚规划可以按下面这种思路列:
| 信号 | 方向 | 接法 | 注意点 |
|---|---|---|---|
| T0 | 输入 | 系统主时钟 | 尽量走全局时钟脚,避免普通IO引入抖动 |
| Data[11:0] | 输入 | 微处理器数据总线或寄存器输出 | 写入时加锁存,别在计数中途变 |
| phiSH | 输出 | 缓冲器→CCD转移栅 | 先量周期,再量脉宽 |
| phi1/phi2 | 输出 | 缓冲器→CCD模拟移位寄存器 | 两路反相,边沿要齐 |
| phiR | 输出 | 缓冲器→CCD复位端 | 极性和脉宽按器件手册确认 |
复现时先别急着接CCD。把CPLD下载进去,示波器探头挂在phiSH上,改Data看SH周期有没有跟着变;再挂phi1、phi2看两路是不是严格反相;最后挂phiR看复位脉冲有没有落在OS输出的节拍上。这个顺序看着笨,但能把“时序问题”和“光学问题”分开。现场最容易翻车的是把镜头问题、光源问题和驱动问题混在一起查,最后查了一圈发现是SH周期被预置值方向写反了。
提示:CPLD的IO不要直接长线驱CCD,先加缓冲器,再把地回流和时钟走线分开。边沿一软,后面调图像都是玄学。
3. 器件结构与驱动时序:TCD1206UD的2236个像元如何被四路脉冲读出
3.1 像元阵列、转移栅与模拟移位寄存器的分工
TCD1206UD是线阵CCD,资料里给的结构是2236个pn结光电二极管构成光敏元阵列。前64个和后12个被遮蔽,用作暗电流检测,符号记作Dn;中间2160个是曝光像敏单元,每个单元14μm长、14μm高,中心距14μm。光敏元两侧是存储电荷的MOS电容列,也就是存储栅;存储栅两侧是转移栅电极SH;再往外是CCD模拟移位寄存器,输出部分由信号输出单元和补偿输出单元构成。
这套结构决定了驱动信号的分工:SH负责把光敏元里积分出来的电荷搬到模拟移位寄存器,φ1、φ2负责在移位寄存器里搬电荷,φR负责输出 circuit 的复位。光积分时间不是由φ1、φ2决定的,而是由两个SH脉冲之间的间隔决定的。SH来得越密,光积分时间越短;SH间隔拉长,光积分时间变长,输出幅度跟着变高。资料里说“CCD输出信号与光强和光积分时间成正比”,落到电路上就是调SH周期。
输出顺序也要记清楚:OS端先出13个虚设单元信号,再出51个暗电流信号,然后连续输出S1到S2160有效像素信号;S2160之后又出9个暗信号,再出2个奇偶检测信号,之后是空驱动。空驱动数量可以人为延长,正好用来拉长光积分时间。这个“空驱动”不是废数据,它是这套动态控制方案的调节余量。
3.2 四路驱动脉冲的时序关系与最小周期计算
φ1、φ2由主频T0二分频得到,两路反相;φR由T0经逻辑电路产生;SH由计数器产生。资料里给了一个关键约束:一个SH周期中至少要有1118个φ1脉冲,否则上次数据没读完就开始下一次读数,输出会失真。这里容易把“SH周期”和“SH脉宽”混成一件事。按“φ1由T0二分频”推,φ1的周期是2T0,1118个φ1脉冲需要2236T0,所以SH周期至少2236T0。资料里写“TSH>1118T0”是按φ1脉冲数在数,不是按T0在数,读的时候要把它换算清楚。
用公式写就是:
T_phi1 = 2 * T0 T_SH_min = 1118 * T_phi1 = 2236 * T0 T_int = T_SH = 2236 * T0 + N_empty * T0其中T_int是光积分时间,N_empty是空驱动数量。最小光积分时间是2236T0,最大按资料口径是2236T0+4096T0。实际差一拍取决于计数器装载和清零的时序,仿真时要把边界扫出来。
| 参数 | 含义 | 资料取值 | 调试时看什么 |
|---|---|---|---|
| N | 基本计数长度 | 2236 | 小于这个值,有效像元读不完 |
| Data | 光积分延时预置值 | 1~4095 | 方向要和光强策略对齐 |
| SH脉宽 | 转移脉冲高电平时间 | 代码里约500T0 | 太窄转移不干净,太宽浪费周期 |
| φ1/φ2 | 移位寄存器时钟 | T0二分频、反相 | 两路边沿对齐,不能有交叠毛刺 |
| φR | 复位脉冲 | 与T0同步 | 极性和脉宽按CCD手册 |
注意:SH周期和SH脉宽不是一回事。周期决定光积分时间,脉宽决定电荷转移窗口。示波器上先把周期量对,再量脉宽,别拿脉宽去算积分时间。
3.3 空驱动数量与光积分时间的换算方法
按资料里的计数器逻辑,基本计数器计到2236后产生计数满信号,启动光积分延时预置计数器;预置计数器计满后清除基本计数器,并产生SH。预置初值确定空驱动数目,范围1~4095。按代码里“Data_reg递增到4095”的方向,Data越大,等待时间越短,SH周期越短;Data越小,等待时间越长,SH周期越长。这个方向和“背景光强时积分时间短”能对上:光强时给大预置值,光弱时给小预置值。
现场标定时可以列一张小表,把Data和实测SH周期对应起来:
| Data | 空驱动趋势 | SH周期趋势 | 适用光强 |
|---|---|---|---|
| 4095 | 最少 | 接近2236T0 | 强背景光,防饱和 |
| 2048 | 中等 | 约2236T0+2048T0 | 中等光强 |
| 1 | 最多 | 接近2236T0+4096T0 | 弱背景光,提信号幅度 |
这张表不是让你背数值,而是让你在微处理器里做闭环时有方向。光强时如果Data写反,饱和不但压不下去,还会更严重。调试时先把Data从最小走到最大,看SH周期是变长还是变短,确认方向后再进闭环。方向确认这一步花不了十分钟,但能省掉后面一堆“算法怎么调都不对”的怀疑。
3.4 输出信号序列与暗电流参考
OS端输出的序列里,前13个虚设单元、51个暗电流信号、9个暗信号和2个奇偶检测信号都不是有效像素,但它们有用途。暗电流信号随温度变化,拿它做参考可以补偿暗电平漂移;奇偶检测信号可以用来判断两列并行传输有没有错位。动态控制光积分时间时,光强变化会同时影响有效像素和暗电流,微处理器如果只看有效像素的峰值,容易把暗电平变化误判成光强变化。常见做法是取一段暗像元的均值做基线,再用有效像素的峰值或均值减基线,拿这个差值去调Data。
这个细节在强光场景下特别有用。背景光一强,有效像素先饱和,暗像元变化没那么快,减基线后能更早发现饱和趋势。弱光场景下,有效像素幅度低,暗电流占比变大,不减基线容易把暗电流当成信号。资料里没有展开算法,但硬件上已经把暗像元留出来了,二次开发时别浪费。
4. 核心逻辑拆解:Verilog里两个计数器如何生成SH脉冲与动态积分窗口
4.1 端口与寄存器定义
资料里的Verilog代码用了非ASCII的φ符号,直接贴进综合工具容易出问题。下面按原逻辑整理成ASCII信号名,方便阅读和综合。端口保留T0、Data、phiSH、phi1、phi2、phiR,内部用base_count管2236个基本节拍,sh_count管SH脉宽,data_reg存预置值,clr做周期清除。
module ccd_driver ( input wire T0, // 系统主频,所有时序的统一节拍 input wire [11:0] Data, // 微处理器下发的光积分延时预置值 output reg phiSH, // 转移脉冲 output reg phi1, // 模拟移位寄存器时钟1 output reg phi2, // 模拟移位寄存器时钟2,与phi1反相 output reg phiR // 复位脉冲 ); parameter N = 2236; // TCD1206UD一个SH周期的基础节拍数 reg [11:0] base_count; // 基本计数器 reg [11:0] data_reg; // 预置值锁存 reg [8:0] sh_count; // SH脉宽计数器 reg start_signal; // 启动延时计数 reg signal_del; // 装载预置值的延迟标志 reg clr; // 周期清除标志这段端口的重点在Data位宽。12位对应0~4095,刚好覆盖资料里说的预置范围。base_count也用12位,因为2236超过8位。sh_count用9位,因为SH脉宽计数到500就够。T0是唯一时钟,phi1、phi2、phiR、phiSH都从它派生,这样主频不动,时序关系不会因为改积分时间而散掉。
4.2 基本计数器与光积分延时预置计数器
基本计数器负责数到2236,数满后置start_signal,让延时计数器开始工作。延时计数器从data_reg开始递增,直到4095或clr到来。下面这段是整理后的核心计数逻辑:
always @(posedge T0) begin if (base_count == N) begin signal_del <= 1'b1; start_signal <= 1'b1; base_count <= base_count + 1'b1; end else if (base_count > N + 2) begin base_count <= N + 3; // 防止计数器越界后乱跳 end else begin signal_del <= 1'b0; base_count <= base_count + 1'b1; end if (clr) begin // clr优先级最高,直接清周期 base_count <= 12'd0; start_signal <= 1'b0; end endbase_count从0数到2236,对应一个SH周期里最基础的2236个T0。signal_del在计满那一拍置1,用来在下一拍把Data装进data_reg;start_signal同时置1,让延时计数器开始递增。base_count > N + 2那个分支是防越界,实际综合时可以把这段简化成饱和计数。clr放在最后,保证周期清除时不会被前面的自增覆盖。
延时计数器部分如下:
always @(posedge T0) begin if (signal_del) begin data_reg <= Data; // 在基本计数满后装载预置值 end if (start_signal) begin if (data_reg == 12'd4095) begin clr <= 1'b1; // 预置值走到头,准备产生SH end else begin data_reg <= data_reg + 1'b1; end end if (clr) begin if (sh_count == 9'd500) begin // SH高电平维持500个T0 sh_count <= 9'd0; clr <= 1'b0; end else begin sh_count <= sh_count + 1'b1; end end end这里的参数方向要盯住:data_reg装载Data后往4095走,Data越大,走到4095越快,空驱动越少,SH周期越短。Data越小,走到4095越慢,空驱动越多,SH周期越长。这个方向和“强光短积分、弱光长积分”能对上,微处理器在强光时给大值,弱光时给小值。如果二次开发时改成递减到0,方向就反过来,标定表也要跟着翻,别把两套逻辑混在一起。
4.3 转移脉冲与复位脉冲的生成细节
SH由clr产生。clr为高时phiSH为高,clr维持500个T0后清零,SH也就有了约500T0的脉宽。φ1、φ2由T0二分频,φR跟随T0。整理后的写法如下:
always @(posedge T0) begin phi1 <= ~phi1; phi2 <= phi1; // 非阻塞赋值,phi2取到的是翻转前的phi1 end always @(*) begin phiR = T0; // 复位脉冲与主频同步,实际极性按CCD手册确认 end always @(clr) begin phiSH = clr; // clr高则SH高,clr持续500T0则SH脉宽约500T0 endphi1每个T0翻转一次,周期是2T0;phi2取翻转前的phi1,所以和新的phi1反相。这个写法比phi2 = ~phi1更贴近硬件:两个寄存器在同一时钟沿更新,phi2拿到旧值,输出端自然反相。phiR这里用组合逻辑跟随T0,资料里说复位脉冲由主频经逻辑电路产生,实际板子上要按CCD手册确认极性和脉宽,别直接照抄。phiSH用clr做敏感信号,属于把内部标志当组合输出,综合一般能过,但时序分析不友好,后面第4.4会讲同步化改法。
4.4 代码里几个容易忽略的时序边界
第一个边界是SH周期和SH脉宽的交界。clr在data_reg到4095时置1,下一拍sh_count开始数500,SH在这500拍里保持高。周期清掉后base_count从0重新数,下一个SH要等2236拍再加延时。仿真时要把Data=1和Data=4095两个极端都跑一遍,看SH周期是不是落在2236T0到2236T0+4096T0附近,别只看中间值。
第二个边界是Data的写入时机。微处理器如果在base_count正数到一半时改Data,signal_del还没到,data_reg不会立刻更新,这还好;如果改在signal_del那一拍附近,可能装到旧值或新值,不同综合结果可能不一样。常见做法是加两级寄存器,把Data先锁存到data_shadow,等SH下降沿后再更新data_reg。这样写参数不会打断当前周期。
第三个边界是把clr当异步时钟。always @(clr)能综合,但clr是寄存器输出,拿它当敏感信号等于自己造了一个内部时钟,时序约束不好写,后面加逻辑也容易出毛刺。更稳的写法是状态机:在T0沿上判断base_count和data_reg,到了就置phiSH,数够500拍再清phiSH。下面这段是同步化思路:
localparam S_IDLE = 1'b0; localparam S_SH = 1'b1; reg state; always @(posedge T0) begin case (state) S_IDLE: begin if (base_count == N + data_reg) begin phiSH <= 1'b1; sh_count <= 9'd0; state <= S_SH; end else begin base_count <= base_count + 1'b1; end end S_SH: begin if (sh_count == 9'd500) begin phiSH <= 1'b0; base_count <= 12'd0; state <= S_IDLE; end else begin sh_count <= sh_count + 1'b1; end end endcase end这段把SH的置位和清零都放在T0沿上,clr不再当时钟,综合和时序分析都干净。代价是周期计算从“两个计数器串联”变成“一个状态机里比较”,逻辑量稍大,但EPM7032C44这种资源下仍然放得下。二次开发时如果加寄存器配置、饱和检测,建议直接从这个同步版本往下改,别在异步clr上叠逻辑。
5. 避坑与排查:动态CCD驱动电路联调时最容易翻车的5个点
5.1 输出全白或全黑:先量SH周期,不要先换镜头
现象:CCD输出要么一片高电平,要么一片低电平,A/D采回来全是0或满量程,图像上看不出物体轮廓。现场第一反应通常是镜头脏了、光源坏了,换完一圈问题还在。
原因:SH周期被预置值写死或写反,光积分时间落在极端。强光下积分时间太长,有效像元饱和,输出削顶;弱光下积分时间太短,信号幅度低于A/D的有效位数,看起来像全黑。还有一种情况是SH根本没出来,CCD没有转移脉冲,OS端只输出固定电平。
解决:示波器先挂phiSH,确认有没有脉冲、周期是多少、脉宽是多少。再改Data从最小走到最大,看SH周期有没有跟着变。如果周期不变,查Data总线有没有写进去、CPLD引脚有没有分配错;如果周期变了但方向反了,把预置值映射翻过来。镜头和光源放到时序确认之后再查,顺序别倒。
5.2 SH脉宽和SH周期混淆:图像固定条纹或错位
现象:图像上出现固定位置的条纹、重复错位,或者有效像元区中间有一段数据明显不对。改光源亮度,条纹位置不变;改Data,条纹会动但消不掉。
原因:把SH脉宽当成SH周期来调。SH脉宽太窄,转移栅开启时间不够,电荷没搬干净,上一行残影混到下一行;SH周期小于2236T0,上次数据没读完就开始下一次读数,移位寄存器里数据错位。资料里“TSH>1118T0”是按φ1脉冲数在说,直接当成T0数就会把周期算短一半。
解决:先按φ1周期换算。φ1是T0二分频,一个φ1周期2T0,1118个φ1脉冲对应2236T0。示波器同时挂phi1和phiSH,数一个SH周期里有多少个phi1脉冲,少于1118就把周期拉长。SH脉宽单独看,500T0是资料代码里的值,实际按CCD手册和转移栅特性微调,别拿脉宽去顶周期。
5.3 预置值方向写反:强光下饱和反而更严重
现象:现场光变强,微处理器按闭环逻辑调Data,结果输出饱和更厉害;光变弱,信号反而更小。看代码觉得闭环方向没错,看波形发现SH周期和预期相反。
原因:预置值计数方向没统一。资料代码里data_reg往4095递增,Data越大等待越短;二次开发改成递减到0后,Data越大等待越长。微处理器里的“强光增大Data”策略没跟着翻,方向就反了。还有一种情况是Data总线高低位接反,写4095实际进去是3840,标定表全乱。
解决:先做一张Data-SH周期实测表,从1到4095取几个点,确认单调方向。微处理器闭环里加一个方向标志,换计数器方向时只改一个宏。总线高低位用固定测试图案校验,比如写0xAAA和0x555,读回CPLD内部寄存器看是不是一致。方向确认之前不要开自动闭环,手动调几档把趋势看明白。
5.4 CPLD直接驱CCD:边沿变软、振铃、输出噪声大
现象:phi1、phi2上升沿变缓,示波器上看到振铃,CCD输出噪声大,暗像元基线不稳。换一片CPLD好一点,但问题还在。
原因:CPLD的IO驱动能力有限,CCD的驱动端有电容负载,长线又带来电感和反射。直接驱等于让IO去推一个不匹配的负载,边沿一软,移位寄存器的两个时钟交叠区变大,电荷转移不干净。地回流没处理好,数字开关噪声会窜到OS输出。
解决:加一级缓冲器,缓冲器靠近CCD放,走线短;输出串小电阻阻尼振铃;CPLD和CCD的地分开走,单点汇合;时钟线远离模拟输出线。示波器用短地弹簧测,别用长地线夹,否则看到的振铃有一半是探头带来的。边沿和噪声处理完,再去调Data,否则调参数像在猜。
5.5 微处理器写Data时毛刺:图像随机撕裂
现象:静态场景下图像偶尔撕裂,撕的位置随机;手碰数据总线或改软件写入频率,撕裂概率变化。复位后可能好一阵,跑久了又出现。
原因:Data在计数器计数中途变化,data_reg装到半新半旧的值;或者写使能和地址译码有毛刺,CPLD把一次写看成多次写。SH周期突然跳一拍,下一帧读出的像元就对不上。
解决:Data先进锁存器,再在SH下降沿后更新到data_reg;写使能用同步设计,地址译码加一拍寄存;微处理器侧写之前读状态寄存器的busy位,避开SH高电平窗口。调试时用逻辑分析仪抓写使能、Data和phiSH,看写入是不是落在SH高电平期间。把写入窗口错开,撕裂基本就没了。
6. 二次开发:把预置值做成可标定寄存器,并给时序留一个观测口
6.1 把预置值做成可配置寄存器
直接在顶层用Data总线比较危险,建议在CPLD里加一组寄存器:控制寄存器放enable、soft_reset、direction;预置值低8位和高4位分两个地址;状态寄存器回读当前SH周期计数和饱和标志。微处理器写预置值时先写影子寄存器,等SH下降沿后生效,当前周期不被打断。这样标定表可以存在微处理器里,换镜头、换光源只改表,不用重新综合CPLD。
| 地址 | 寄存器 | 位定义 | 用途 |
|---|---|---|---|
| 0x00 | CTRL | bit0 enable,bit1 soft_reset,bit2 dir | 使能和方向切换 |
| 0x01 | DATA_L | Data[7:0] | 预置值低8位 |
| 0x02 | DATA_H | Data[11:8] | 预置值高4位 |
| 0x03 | STATUS | bit0 busy,bit1 sat | 写入窗口和饱和提示 |
6.2 给时序留一个观测口
CPLD空闲IO别浪费,引两个观测点出来:一个输出SH周期计数的分频信号,一个输出“base_count计满”的脉冲。逻辑分析仪抓这两个点,再加phiSH和Data,就能看出预置值什么时候生效、周期有没有跳变。没有逻辑分析仪时,用示波器看观测点和phiSH的相位关系,也比只看图像猜强。这个口子平时不影响功能,出问题时能少熬一晚上。
6.3 验证顺序
先不接CCD,测四路波形和Data的单调关系;再接CCD,遮光、正常光
本文还有配套的精品资源,点击获取