0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

电波校时钟的制作

454398 来源:网络整理 作者:网络整理 2019-11-21 09:01 次阅读

简介:

手头有一个项目,需要一个“精确”的频率计,作为DIY一族,准备动手制作一个。在制作频率计之前,需要一个 能精确测量晶振频率的东西。之前尝试过NTP对时,发现精度太差,不好使。所以准备改用电波对时。百度搜了一下,动手做电波表的朋友还真不少, 但讲得不够详细,解码部分还是“保密”的。只好尝试自立更生了。

BPC电波钟模块

电波对时需要一个接收头,接收授时中心发出的电波信号。我们国家的授时信号频率为68.5Khz,发射台在商丘。 接收头实际上是一个窄带信号接收器,其带宽只有几个赫兹,通常采用晶体滤波器来限制接收带宽。由于工作频率比较低,放大部分是比较 容易设计的,有一定无线电基础的都可以做出来。

这里我们直接从某宝上买来一个完整的电波钟模块。花了15大洋,省了很多事。

电波校时钟的制作

BPC模块上用到的引脚有4条。

VCC :电源,1.5~3.5V

GND :地

SIG :BPC授时信号输出

EN :模块使能(低电平使能,高电平关闭模块)

BPC解码和校时

电波钟模块输出的BPC信号如下图,1分钟包含3个帧,一个BPC帧的周期为20秒,除了第“0”秒外,其余19秒每秒一个 脉冲。方波秒脉冲有0.1S,0.2S,0.3S,0.4S四种脉冲宽度状态,分别表示四进制的0, 1, 2, 3,现有的时间编码都以二进制表示时间信息, 是为了采用微处理器解码方便。但四进制只是数值的一种表示方式,并不影响微处理器把它作为二进制处理,或者采取简单的变换就可将1位 四进制数变成2位二进制数。

P0设在每分钟0,20, 40秒,以缺少秒脉冲使帧与帧隔开,同时作为帧起始预告。

P1为帧标志,P1=0表示帧起于第1秒,P1=1表示帧起始于21秒,P1=2表示帧起始于41秒。帧标志是必需的,它用来确定整分的起始。 例如:当接收完一组包含着“10时38分”的时间编码时,如果帧标志标明该帧为第二帧,就可以把下一帧的P1位置标定为10时38分41秒, 再过20秒便是10时39分的起始。

P2为预留位。用于需要扩充信息。

时&分表示了时间

其他各位数据在本案中没有用到,不做详细说明

解码MCU采用了TI公司MSP430G2211IPW14,MSP系列的MCU以低功耗著称,非常适合于电池供电的应用。本例中, MCU大部分时间工作在约20uA的低功耗模式下。

BPC解码软件使用了MSP430G2211的TimeA,TimeA的计数器由32768Hz的晶振提供时钟,从0~0xFFFF循环计数。每2秒 循环一周。BPC信号接在MCU的中断请求上,在上下跳变沿均产生中断,中断服务程序中读取TimerA计数器。根据脉冲宽度解码BPC编码的信号。 由于BPC信号的最小脉宽为0.1秒,软件中还加入了滤波处理,可以滤除脉宽较窄的干扰信号。

if (MCU_INT_GET(BPC_SIGNAL_PORT, BPC_SIGNAL_PIN)) { static uint16 wPrevToggle = 0; //前一次跳变时刻 static uint16 wLastPulseWidth = 0; //前一次脉冲宽度 static uint8 bLastPulsePolarity = 0; //前一次脉冲极性(1:正脉冲,0:负脉冲) static uint8 ucBpcBitPos = 0xFF; //BPC解码位置,0xFF表示解码状态机复位 static uint8 ucBpc[2]; //BPC码数据,只取包含“时:分:秒”信息的前面2字节。 uint16 wCurToggle; //本次跳变时刻 uint16 wCurPulseWidth; //本次脉冲宽度 uint16 wBpcSecond; //BPC解码得到的时间秒数 uint8 bCurPulsePolarity; //本次脉冲极性(1:正脉冲,0:负脉冲) uint8 ucTmp; MCU_INT_XOR_EDGE(BPC_SIGNAL_PORT, BPC_SIGNAL_PIN); MCU_INT_CLEAR(BPC_SIGNAL_PORT, BPC_SIGNAL_PIN); //正跳变,表示的是负脉冲(结束) bCurPulsePolarity = MCU_INT_GET_EDGE(BPC_SIGNAL_PORT, BPC_SIGNAL_PIN) ? 0 : 1; wCurToggle = GetCurTimerA(); wCurPulseWidth = wCurToggle - wPrevToggle; if ((wCurPulseWidth 《 PULSE_FILTER_OUT) || (bCurPulsePolarity == bLastPulsePolarity)) { //本次跳变脉宽过短,将当作干扰毛刺被过滤掉,脉宽同前一次合并 //本次脉宽极性同前一次相同(跟在干扰毛刺后),脉宽也同前一次合并 wLastPulseWidth += wCurPulseWidth; } else { //前一次脉宽数据有效,可以处理了。 if (!bLastPulsePolarity && (wLastPulseWidth 》 PULSE_10ms * 100)) { //每帧数据头部有1秒时间的空档期,表示帧起始 ucBpcBitPos = 14; //只用到前14bit数据 ucBpc[0] = ucBpc[1] = 0; } else if (ucBpcBitPos != 0xFF) { if (!bLastPulsePolarity) { //负脉冲 if (wLastPulseWidth 《 PULSE_10ms * 55) //BPC编码正脉冲宽度最小600ms,《550ms为非法,解码状态机复位 ucBpcBitPos = 0xFF; } else { //正脉冲 ucTmp = 0xFF; if (wLastPulseWidth 《 PULSE_10ms * 45) { if (wLastPulseWidth 》 PULSE_10ms * 35) //400ms脉宽 ucTmp = 3; else if (wLastPulseWidth 》 PULSE_10ms * 25) //300ms脉宽 ucTmp = 2; else if (wLastPulseWidth 》 PULSE_10ms * 15) //200ms脉宽 ucTmp = 1; else if (wLastPulseWidth 》 PULSE_10ms * 5) //100ms脉宽 ucTmp = 0; } if (ucTmp == 0xFF) { //脉宽非法,解码状态机复位 ucBpcBitPos = 0xFF; } else { //保存合法数据 ucBpcBitPos -= 2; ucBpc[ucBpcBitPos 》》 3] |= ucTmp 《《 (ucBpcBitPos & 0x07); if (ucBpcBitPos == 0) { //一帧数据接收完成 ucBpcBitPos = 0xFF; //解码状态机复位,等待下次数据 wBpcSecond = ((ucBpc[1] 《《 2) | (ucBpc[0] 》》 6)) & 0x0F; //小时 wBpcSecond *= 3600; wBpcSecond += ((uint16)(ucBpc[0] & 0x3F)) * 60; //分钟 wBpcSecond += ((ucBpc[1] 》》 4) & 0x03) * 20 + 21; //秒数 //如果相临近的两次BPC校时都是准确的(没有误码),守时中断应该在BPC //信号的边界前后,因此,秒数只可能差0或1秒。据此判断校时成功 if ((wBpcSecond - s_wRealSecond) 《 2) s_wEvent |= BPC_FINISHED; s_wRealSecond = wBpcSecond; s_wTarSecond = wCurToggle + COUNT_1S; } //if (ucBpcBitPos == 0 } } } wPrevToggle = wCurToggle; wLastPulseWidth = wCurPulseWidth; bLastPulsePolarity = bCurPulsePolarity; } }

守时信号输出

TimerA的通道0工作在比较器模式,用作守时和UART波特率发生器。时间以12小时内的秒数表示,从00:00:00或12:00:00 开始计数,在每秒开始时将时间读数从UART口发出去。MSP430G2211没有专用的UART,需要软件实现。UART数据格式为8位、无校验、1200波特率。总共 16bit数据,需要用2个字节表示,加上每字节的起始位、停止位,总共20位。

#pragma vector=TIMER0_A0_VECTOR __interrupt void Uart_ISR(void) { static int8 iBits = 0; static uint16 wMask; TACCTL0 &= ~TAIFG; //清中断 //每秒起始位置把16bits实时时间通过UART发送出去 if ((iBits == 0) || (iBits == 10)) { MCU_IO_CLR(UART_TX_PORT, UART_TX_PIN); //起始位 } else if ((iBits == 9) || (iBits == 19)) MCU_IO_SET(UART_TX_PORT, UART_TX_PIN); //停止位 else { //发送数据位 if (s_wRealSecond & wMask) MCU_IO_SET(UART_TX_PORT, UART_TX_PIN); else MCU_IO_CLR(UART_TX_PORT, UART_TX_PIN); wMask 《《= 1; } iBits++; if (iBits == 20) { //实时时间发送完毕,准备在下一秒再次发送 s_wTarSecond += COUNT_1S; TACCR0 = s_wTarSecond; s_wRealSecond++; if (s_wRealSecond 》= ((uint16)12*3600)) s_wRealSecond = 0; iBits = 0; wMask = 1; s_wEvent |= SECOND_EVENT; } else TACCR0 += UART_BIT_WIDTH; __low_power_mode_off_on_exit(); }

守时时钟校准

本系统需要依靠标称频率为32768Hz晶振提供时间基准来守时,晶振负载电容对频率有微调作用。为了测定晶振实际工作 频率,可测量一段时间内的积累误差。例如在10:00:00时进行第一次BPC校时,6个小时后在16:00:00进行第二次BPC校时,用串口工具接收并打印出 第二次BPC校时前后从UART口输出的守时信号

校时之前

【2017-10-11 15:58:47:850】CB 0D

【2017-10-11 15:58:48:850】CC 0D

校时之后

【2017-10-11 15:59:47:827】07 0E

【2017-10-11 15:59:48:827】08 0E

从打印出来的数据可以看出,在校时前后两点(0x0E08-0x0DCC = 60秒),对应PC机系统时间为59:48:827-58:48:850 = 59.977秒,也就是说6小时内积累的误差为-0.023秒,可以忽略不计。否则可能需要调整负载电容来对频率进行微调,或者也可以调整代码中的 COUNT_1S的宏定义值来重新标定“1秒”。

机芯驱动

本设计初衷是要制作一个能够准确计时(无累积误差)的东西。因此完成守时信号输出就OK了,但既然动了手,就准备弄个 完整的电波钟玩玩。拆解了一个多时不用的石英钟,只将机芯步进马达的线圈引出,其他电路统统拆掉。这里我范了一个错误,本以为马达是1秒 走一步或二步,按此设计了驱动代码,结果马达跑得非常别扭,走走退退,不知怎回事,弄了半天才发现问题所在,实际上这个机芯步进马达是每秒16步 的,差得也太远了。因此,建议朋友在拆机前先测一下原机的驱动波形。

这种步进电机的驱动信号为正负交替的脉冲信号。脉冲宽度需要有个合理的范围,拆机时没有先用示波器测一下,只好自己 凑了。不过,就算测了也只能供参考,因为原机是1.5V供电的,现在改成3V,脉宽肯定需要调窄,理论上升到2倍电压后脉宽应是原来的1/4.我的这个马达 用12ms脉宽驱动,工作得很Happy.朋友自己制作时可以自行调整MOTOR_PULSE_DUTY。

为了实现正负极性的交替,使用了2个IO端口(石英钟机芯马达不分极性直接连在这两个端口上就行了),输出两路移相的方波信号。两路方波信号之间的相差即为脉冲宽度。当钟面显示 的时间同实际时间有偏差时,需要改变脉冲周期以调整电机速度,使两者趋于一致。机芯驱动使用了TimeA的通道1,在其中断服务中实现

#pragma vector=TIMER0_A1_VECTOR __interrupt void Motor_drv_ISR(void) { if (TACCTL1 & CCIFG) { // 步进电机驱动信号,一个周期分4个Stage,电机走2步。 // S1,S3提供动力输出。 // ------ // | S1 | // | | // --------------| |--------------| | // S0 S2 | | // | | // ------ // S3 static uint8 ucStage = 0; //步进电机每走一步分2个stage。 uint16 wS0S2; //S0,S2时间长度 TACCTL1 &= ~CCIFG; //清中断 if (ucStage == 2 * STEP_1S - 1) { //每秒末进入此处 ucStage = 0; s_wDisplaySecond++; if (s_wDisplaySecond 》= ((uint16)12 * 3600)) s_wDisplaySecond = 0; } else ucStage++; //先假定钟面时间总是偏“快”的,算一下“快”了多少 if (s_wDisplaySecond 》 s_wRealSecond) wS0S2 = s_wDisplaySecond - s_wRealSecond; else //超了一圈(12小时) wS0S2 = ((uint16)12 * 3600) - (s_wRealSecond - s_wDisplaySecond); //如果算下来“快”了9小时以内,认为其确实“快”了,否则认为实际是“慢”了3小时不到。 //之所以不以6小时分界,是因为步进马达可以无限放慢,有限地加快。 if (wS0S2 《 2) //偏快不多,正常运行 wS0S2 = MOTOR_PERIOD - MOTOR_PULSE_DUTY; //正常运行 else if (wS0S2 《 ((uint16)9 * 3600)) //偏快,降速运行 wS0S2 = MOTOR_PERIOD_SLOW - MOTOR_PULSE_DUTY; else //偏慢,加速运行 wS0S2 = MOTOR_PERIOD_FAST - MOTOR_PULSE_DUTY; //步进电机驱动信号4个stage一个循环,走2步 switch(ucStage & 0x03) { case 0: MCU_IO_CLR(MOTOR_DRVN_PORT, MOTOR_DRVN_PIN); TACCR1 += wS0S2; break; case 1: MCU_IO_SET(MOTOR_DRVP_PORT, MOTOR_DRVP_PIN); TACCR1 += MOTOR_PULSE_DUTY; break; case 2: MCU_IO_SET(MOTOR_DRVN_PORT, MOTOR_DRVN_PIN); TACCR1 += wS0S2; break; case 3: MCU_IO_CLR(MOTOR_DRVP_PORT, MOTOR_DRVP_PIN); TACCR1 += MOTOR_PULSE_DUTY; break; } } __low_power_mode_off_on_exit(); }

使用方法

由于系统无法读取钟面显示的时间,因此在系统上电启动时,必须先把钟面拨到00:00:00的默认位置。上电时,MCU默认为 钟面显示时间和系统实际时间为00:00:00.系统在00:00:02启动BPC对时,对时成功后,“实际时间”就准确了,这时,从UART输出的守时信号也是准确的了。 但钟面时间需要一段时间后才能逐步同实际时间一致。以后,系统会在每天的00:00:02和12:00:02各启动BPC对时一次,如果对时成功或20分钟内不能对时 则自动关闭BPC模块以节约电池。对时成功,照明等会点亮2秒。

在每天的17:00-21:00, 05:00-9:00两个时段内是BPC发射台是关闭的,在这两个时段内开机是无法对时的。

系统提供了一个按钮,短按按钮可以点灯5秒,以便夜间照明。长按2秒以上可以立即打开BPC对时,对时成功或5分钟内不成功 则自动关闭BPC模块。这些业务逻辑都在主程序中实现。

实物图

原理图

JI为下载接口。MSP430G2211晶振匹配电容内置,可配置,所以不需要外接电容

责任编辑:wv

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 电波钟
    +关注

    关注

    0

    文章

    4

    浏览量

    7124
收藏 人收藏

    评论

    相关推荐

    安徽京准 NTP网络校时器 NTP服务器 电厂应用方案

    【安徽京准】NTP网络校时器(NTP服务器)电厂应用方案
    的头像 发表于 08-08 09:27 135次阅读
    安徽京准 NTP网络<b class='flag-5'>校时</b>器 NTP服务器 电厂应用方案

    NTP服务器知识课堂 网络时间同步系统的校时方式

    LED电子时钟相信大家应该都很熟悉,在我们生活中随处可见,尤其是在学校、商场、办公楼、高铁站、机场、高速服务器、医院等场所。但是网络时钟系统的校时方式,就没有多少人知道了,下面就给大家介绍网络同步
    的头像 发表于 07-30 14:23 156次阅读
    NTP服务器知识课堂 网络时间同步系统的<b class='flag-5'>校时</b>方式

    网络时间同步系统的校时方式

    LED电子时钟相信大家应该都很熟悉,在我们生活中随处可见,尤其是在学校、商场、办公楼、高铁站、机场、高速服务器、医院等场所。但是网络时钟系统的校时方式,就没有多少人知道了,下面就给大家介绍网络同步
    的头像 发表于 07-25 17:00 223次阅读
    网络时间同步系统的<b class='flag-5'>校时</b>方式

    GPS校时器 NTP网络校时服务器 助力高速收费-安徽京准

    GPS校时器(NTP网络校时服务器)助力高速收费-安徽京准
    的头像 发表于 07-16 16:09 302次阅读
    GPS<b class='flag-5'>校时</b>器 NTP网络<b class='flag-5'>校时</b>服务器 助力高速收费-安徽京准

    同步时钟:北斗/GPS卫星、电信基站、NTP以太网校时方式的区别

    同步时钟是保证各设备时间统一的重要装置,广泛应用于电力、通信、金融、学校、医院、地铁等多个领域。目前,常用的同步时钟方式包括:北斗/GPS卫星、电信基站、NTP以太网等。   下面跟着小编来看
    的头像 发表于 06-27 16:56 336次阅读
    同步<b class='flag-5'>时钟</b>:北斗/GPS卫星、电信基站、NTP以太网<b class='flag-5'>校时</b>方式的区别

    【京准科技】GPS校时器(NTP校时器)守时方法研究

    【京准科技】GPS校时器(NTP校时器)守时方法研究
    的头像 发表于 06-04 15:52 434次阅读
    【京准科技】GPS<b class='flag-5'>校时</b>器(NTP<b class='flag-5'>校时</b>器)守时方法研究

    京准电子 GPS北斗卫星校时服务器在煤矿数据系统的应用

    京准电子 GPS北斗卫星校时服务器在煤矿数据系统的应用
    的头像 发表于 06-03 15:24 243次阅读
    京准电子 GPS北斗卫星<b class='flag-5'>校时</b>服务器在煤矿数据系统的应用

    如何使用emwin制作时钟

    请教下,使用emwin制作时钟 ??
    发表于 04-29 06:21

    网络时间同步服务器的校时方式,您了解多少?

    LED电子时钟相信大家应该都很熟悉,在我们生活中随处可见,尤其是在学校、商场、办公楼、高铁站、机场、高速服务器、医院等场所。但是网络时钟系统的校时方式,就没有多少人知道了,下面就给大家介绍网络时间
    的头像 发表于 04-02 14:25 1351次阅读
    网络时间同步服务器的<b class='flag-5'>校时</b>方式,您了解多少?

    赛思x中国民用航空飞行学院|智慧校园时钟系统解决方案,助力天府校区建设现代化智慧校园

    近日,中国民用航空飞行学院天府校区投入使用,约1600名学生已入驻该校区。赛思学校时钟系统解决方案,助力天府校区精准授时,打造现代化智慧校园。中国民用航空飞行学院天府校区「智慧校园建设项目」中国
    的头像 发表于 03-15 10:24 454次阅读
    赛思x中国民用航空飞行学院|智慧校园<b class='flag-5'>时钟</b>系统解决方案,助力天府校区建设现代化智慧校园

    电波暗室的屏蔽原理是什么?

    电波暗室利用外壳的金属壳体以及内部表面的铁氧体和尖劈吸波材料来实现对电磁波的屏蔽,阻止外部电磁波进入或内部电磁波干扰外部环境的原理。这些材料结合使用,共同作用以有效地减少电磁波的传播和干扰
    的头像 发表于 12-29 10:13 963次阅读
    <b class='flag-5'>电波</b>暗室的屏蔽原理是什么?

    一种实现多通道无压缩IP流PTP时钟精准校时分析的方法

    PTP(Precision Time Protocol,精确时间协议)是一种时间同步的协议,由IEEE 1588-2008定义,通过在主时钟和从时钟之间交换信息来工作,用于精确同步分布式网络通信中各个节点的实时时钟,将网络设备
    的头像 发表于 12-04 14:10 1475次阅读
    一种实现多通道无压缩IP流PTP<b class='flag-5'>时钟</b>精准<b class='flag-5'>校时</b>分析的方法

    基于C8051F340单片机的GPS校时器设计

    电子发烧友网站提供《基于C8051F340单片机的GPS校时器设计.pdf》资料免费下载
    发表于 10-26 09:00 0次下载
    基于C8051F340单片机的GPS<b class='flag-5'>校时</b>器设计

    51单片机自动校时万年历设计方案

    51单片机自动校时万年历设计
    发表于 09-26 08:20

    制作RGB HexMatrix物联网时钟

    HexMatrix是具有许多三角形像素的LED矩阵。六个像素组合成一个六边形。FastLED库的矩阵上可以显示许多不同的动画。我还设计了0到9的数字,并为矩阵中的每个数字使用了10个段,并制作了一个IOT时钟
    发表于 09-25 06:58