时钟是硬件设计人员的标准概念,但不太熟悉软件工程师。但是,在嵌入式编程(尤其是实时嵌入式编程)中,软件开发人员必须在其软件程序中处理时钟。本文讨论基于软件的时钟的基础知识。
什么是时钟
时钟是一种交替固定频率的信号。
图1:时钟信号。
时钟周期是信号连续上升沿之间的时间。频率是上升沿出现的速率(即1/周期)。时间或频率表征时钟。在软件中,要跟踪时钟,您只需存储其中一个值。在本文中,这些示例使用其周期来表征时钟,因为这使得它们更容易编码。为了说明,让我们使用浮点类型来表示它(例如,C double类型)。在实践中,可以使用任何可以表示时间的类型。通常使用定点表示。
使用时钟
一旦软件中有时钟频率,您可以通过乘以或除以周期来轻松地对时钟进行乘法或除法。有关时钟的信息可以传送到远程系统以远程重建,或控制与时钟同步传输的数据流。
输出时钟
要输出时钟,需要对输出端口进行高位和低位交替打击。以下C风格的伪代码显示了这个想法:
double t;
int val = 0;
t = get_current_time();
while(1){
t + = period/2;
output_at_time(t,val);
val = ~val;
}
此处 get_current_time 获取当前时间, output_at_time 在指定时间向端口输出值。但是,这些功能仅对软件系统中固有的某些分辨率是准确的。输出时钟的频率被量化为该分辨率,这意味着频率可以远离所需值。你可以通过跟踪这种量化引起的误差并随着时间的推移进行调整来改善这一点。以下代码显示了这一点:
double t;
int val = 0;
double hi = floor((期间/2)/分辨率)*分辨率;
double lo =(期间/2)-hi;
double err = 0;
t = get_time();
while(1){
t + = hi;
err + = lo;
if(err》 = resolution){
err - = resolution;
t + = 1;
output_at_time(t,val);
val = ~val;
}
此算法会跟踪错误,当错误变得足够大以便合并到输出中时,它会这样做。使用此方法,输出时钟将具有正确的频率,但量化仍将导致时钟上的可观察到的抖动。
恢复时钟
有时您需要从输入信号中恢复时钟,以便将其用作系统中其他处理的基础。
匹配频率
最简单的事情是匹配传入时钟的频率。在特定时间段内,计算时钟上升沿的数量,然后计算每个上升沿的周期:
period = sample_period/ticks_in;
传入时钟随时间变化,因此您必须定期重新采样。
使用反馈回路
有时只是匹配时钟的频率是不够的。随着时间的推移,小的不匹配和调整会增加,导致您的内部时钟概念和实际时钟长时间漂移。恢复时钟的滴答数可以与原始时钟的滴答数不同。为了解决这个问题,您需要不断调整时钟之间的累积误差,这是一个可以使用PID控制循环完成的任务。¹
假设您想要将输出时钟与输入时钟匹配。其思想是定期调整输出时钟周期。在每个调整点,查看自上次调整传入时钟(ticks_in)以来的滴答数以及自上次调整传出时钟(ticks_out)以来的滴答数。它们之间的区别在于时钟的比例误差。
从比例误差中,您还可以计算积分(或累计)误差和差分误差。然后基于这些值调整周期以将时钟周期移向正确的值。随着时间的推移,算法停留在固定点上,并且比例误差趋向于零。以下代码可用于调整每次更新的时间段:
P = ticks_out -ticks_in;
I = I + P;
D = P -prevP;
period = period + Kp * P + Ki * I + Kd * D;
常数Kp,Ki和Kd的设置会影响算法的稳定速度以及它可以处理的输入时钟的扰动程度。有一套方法可以正确地为你的应用程序计算这些常量,这里没有讨论,但一个很好的起点是关于PID控制循环的维基百科页面。
下图显示了此类算法随时间推移的典型误差。
图2:PID误差进程。为什么?
对于硬件工程师来说,上一节的结果并不突出。时钟已经以相当复杂的方式路由。那么为什么需要将时钟带入软件领域呢?一个原因是,将时钟作为软件中的逻辑实体,您可以对其进行分析并对其进行操作。例如,您可以将要在其他地方使用的时钟进行小数乘法,或者可以将其频率报告给某个更高级别的应用程序。但是,一个很大的应用是,您可以将时钟传输到系统的另一部分,并通过仅数字传输进行恢复,而无需显式传输时钟。例如,时钟可以通过USB总线或以太网传输。如果必须明确连接系统中的每个时钟信号,这在连接性和灵活性方面带来了很多好处,这将受到严重限制。
要远程恢复时钟,您需要传输反馈信息(例如,滴答计数)。这种计算在一段时间内仍然需要一个共同的时基,因此系统的所有部分必须具有相同的全球时间感。如何做到这一点超出了本文的范围,但对于基于总线的系统(如USB或Firewire),总线可能带有全局时钟。对于更松散耦合的系统,如以太网或其他分组交换网络,需要全局时钟恢复协议。
全部0条评论
快来发表一下你的评论吧 !