“北斗时钟” 方案
一、基于 当前方案的 进一步完善建议
存在的延时:北斗模块 ----- 聚芯SoC t1
聚芯内部时延 t2
聚芯SoC ----- Zigbee模块CC2430 t3
Zigbee内部:从应用层发送到物理层RF的发送 t4
Zigbee之间的传播时延 t5
Zigbee内部的接收时延 t6
针对每个时延又都有具体细节的微时延。
1、针对UART传输时延
上图的红色线条,北斗模块 ----- 聚芯SoC t1
聚芯SoC ----- Zigbee模块CC2430 t3
这一部分时间比较难于控制,现在给出两种解决办法,到那时强烈建议使用PPS(这需要硬件支持,板之上将秒脉冲连接到聚芯Soc、CC2430相应的可用端口):
1)基于秒脉冲PPS
从北斗模块向聚芯SoC引 秒脉冲线(PPS),同时向CC2430引入一个脉冲线(PPS)。引入流水的概念。
T时刻,PPS上升沿到来,北斗模块向聚芯SoC输送数据($GPRMC),同时聚芯SoC开始Count1计数(定时器计数),Count1计数直到聚芯SoC开始处理这个数据包(获取到本地时间);
T+1时刻,在上升沿到来时,聚芯 向 CC2430发送数据,CC2430开始Count2计数(定时器计数)Count2计数 直到 CC2430开始处理这个数据(获取到本地时间)。
Count1便可以精确测出 北斗模块 到 聚芯 的时间t1
Count2便可以精确测出 聚芯 到 CC2430 的时间 t3
2)没有PPS情况下
没有PPS情况下,没有那么精准。关键在于得到通过串口第一传输到 接收方 时,接收方 的当前时间,或者当 传送结束 时 接收方 的本地时间。(但是后者无法确定,因为传输结束无 明确的标识符,也无相关的中断),因此采用第一种,得到通过串口第一传输到 接收方 时,接收方 的当前本地时间,但是在串口中断中 也没有标志第一个字符接收的中断,而是同等的接收中断(也就是说每来一个字符或一串字符来一次中断,字符之间是等同的,而不是有一个特别的第一个字符 的中断)。
引入32位timerHigh 和 32位timerCount进行计时,timerCount 每间隔一定的时间(例如50us)计数一次。在系统初始化是将timerCount赋值非常大值(200,000),
伪代码如下:
系统初始化:timerHigh=0,; timerCount=200,000
starTimer1(50us);
在timer1定时器中断服务程序中:
if(timerCount==快溢出值)timerHigh=1,timerCount=0;
else tiemrCoutn++;
当uart接收到字符数据时,判断
if(timerCount> 某个阈值) //说明是数据包的第一个字符或者第一串字符
{
timerCount=0;
starTimer1(50us) //重新计数
Get_Local_Time();得到当前本地时间
}
Else
{ //则不是第一个 或 第一串 字符
}
同时第一个或第一串字符由 上一个模块通过串口发过来的时间Tuart 的时间可以通过波特率 与 字节数 计数得到。
接收者接收的第一个字节时 当前本地时间为 Trecieve,当再次发送时得到另一个时间Tsend,Tsend- Trecieve+Tuart (便可以得到包括 上一级UART 传输在内 和 本地转发 的总时间)
在没有PPS情况下的 不精确 地方在于:软件处理可能不能被及时响应。
2、针对CC2430内部时延校正
在应用层处理时获取 当前MAC 时间T(app-process-time),同时在发送时通过SFD中断捕获MAC时间T(mac-send-time),这里注意的应用层获取时间需要禁止所有软中断,在SFD中断产生时MAC时间捕获到一个寄存器里,后来读取的T(mac-send-time)是捕获的时间。
二、方案总体设计修改
图1.、当前的系统框架
1、精简方式:北斗模块+CC2430
由于CC2430具有MCU,具有一定的运算功能,其实直接用 “北斗模块”+CC2430就可以完成整个工作(CC2430也有安全加密功能)。
2、北斗模块+聚芯+CC2420
如果一定需要“聚芯SoC”, 那么就是因为 聚芯SoC 的运算速度快,运行频率要高于CC2430。聚芯主要是用来作处理,那么就不需要一个再用来做处理的MCU(CC2430中),那么直接用CC2420(只用RF收发,没有MCU)就可以了。