我们通过电波钟模块接收国家授时中心发出的电波钟信号,通过STM32单片机将信号解码,就可以获得极为准确的时间信息。我的毕业设计中有一个模块是自动对时,在这里将我调出来的电波钟程序发出来,有感兴趣的或者设计需要电波钟的可以参考一下,节省开发时间。
一、电波钟介绍
旧式的钟表具有一个共同的缺点就是时间误差较大,未解决电子钟的时间同步问题,出现了低频时码对时技术。电波钟表是一种新兴的计时产品,是一种通过接受国家授时中心的无线信号以确定时间准确性的计时工具,其成本低,使用方便,广泛应用在一些要求时间高精度同步的设备中,电波钟的电池只要有电就会精确的走动,不需要时常校正时间,它会自动接收电波对时信号并自动校正时间,在电力电网、通信、电子商务等方面都在大规模使用。
二、使用的元器件
STM32F103开发板
电波钟模块,可以在淘宝上买,价格在15元左右。
一些排针和杜邦线,由于连接电波钟模块
电波钟模块实物就是这样子的,一个小电路板以及一个磁棒。


三、硬件设计
模块共有5个焊脚,在使用时只用到了V、G、T、P四个接口,具体的连接是:
V-接电源VCC,1.5~3.5V
G-接地GND
T-时间信号反向输出端
P-模块使能端,工作接底,静态接高
H-自动增益控制接高电平(模块已连好高电平,不用连接)
我将T端连到了PA0口,使用了STM32单片机的定时器2的通道1即TIM2_CH1,使用单片机的输入捕获,将信号进行解码。电波钟模块与STM32的连接原理图如下:

四、BPC编码格式
中国的 BPC 时间信号编码规则的特征是:
(1)每一帧信号的周期是 20 秒钟,所以每分钟可以发播 3 帧时间调制信号。
(2)脉冲周期是 1 秒钟,但是,脉冲宽度(即高电平持续时间)有四种,分别对应着四进制数的 0、1、2、3,脉宽400ms 对应 3,脉宽 300ms 对应 2,脉宽 200ms 对应 1,脉宽 100ms 对应 0。每帧时间信号包含 19个脉冲,缺少1个秒脉冲作为分隔,有规律的脉冲组合得以用来表示对应的时间信息。
(3)帧与帧的间隔,以缺少 1 秒脉冲方式表示。
P0:每帧的开始,每分钟 3 次,间隔 20 秒,因此 P0 则是在第 0 秒、第 20 秒和第 40 的位置。
P1:用做帧定位,P1 有三种状态,分别为 0、1、2,0 表示该帧从第 1 秒钟开始,1 表示该帧从第 21 秒钟开始,2 表示该帧从第 41 秒钟开始。
P2:保留帧,由于以后扩展,所以接收到的P2永远为0。
P3:组合使用位,前半位用于表示上午或下午,后半位用于第 0-8 位的偶校验,其中0,1表示上午,23表示下午。
P4:组合使用位,前半位保留,后半位用于第 10-17 位的偶校验。
编码格式如下图:

可以看到,一帧的第4、5个脉冲表示当前的时,6、7、8脉冲表示当前的分钟信息,依次类推即可获得当前的时间信息,接收一帧完成后,根据P1 可以知道这一帧一分钟内的那一帧,从而可以获得当前的秒信息。
五、软件设计
使用keil 5进行程序开发,首先编写解码、显示程序,编译通过后将程序下载到单片机上运行,找到干扰较小的地方,就可以接收到BPC信号,从而获得当前的时间信息。输入捕获以及单片机对BPC信号进行解码的主要程序如下,要查看完整的文件,可以在文章末尾下载我调好的工程文件,可以通过LCD显示屏查看时间,串口也会输出接收到的BPC信息。
输入捕获程序:
timer.c
主函数 main.c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"
#include "usart.h"
#include "lcd.h"
extern u8 TIM2CH1_CAPTURE_STA; //输入捕获状态
extern u16 TIM2CH1_CAPTURE_VAL; //输入捕获值
char xiaoshi=0,fenzon=0,xinqi=0,ri=0,yue=0,nian=0,wu=0,miao=0;
int P1;
int i=0;
u8 a[19];
int main(void)
{
double temp=0;
int dat;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
delay_init(); //延时函数初始化
uart_init(9600); //9600
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
TIM2_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数
POINT_COLOR=RED;
LCD_ShowString(50,130,200,16,16," - - ");
LCD_ShowString(60,80,200,24,24," : : ");
while(1)
{
delay_us(10);
if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
{
miao=miao+1;
if(miao==60) miao=0;
temp=TIM2CH1_CAPTURE_STA&0X3F;
temp*=65536; //溢出时间总和
temp+=TIM2CH1_CAPTURE_VAL; //得到总的高电平时间
temp=(double)temp/1000; //ms
if((temp>=850)&&(temp<950)) dat=0;
else if((temp>=750)&&(temp<850)) dat=1;
else if((temp>=650)&&(temp<750)) dat=2;
else if((temp>=550)&&(temp<650)) dat=3;
if(temp>1200)
{
printf("\r\n");
i=0;
miao++;
LCD_ShowNum(128,80,miao,2,24);
}
a[i]=dat;
i++;
if(i==19)
{
xiaoshi=((a[3])*4)+(a[4]);
fenzon=(((a[5])*16)+((a[6])*4)+(a[7]));
xinqi=((a[8])*4)+(a[9]);
ri=((a[11])*16)+((a[12])*4)+a[13]; // 换算方式
yue=((a[14])*4)+a[15];
nian=((a[16])*16)+((a[17])*4)+a[18];
wu=a[10]; //0和1表示上午 2和3表示下午
P1=a[1]; // 0表示1秒 1表示21秒 2表示41秒
if(P1==0)
{
miao=19;
}
if(P1==1)
{
miao=39;
}
if(P1==2)
{
miao=59;
}
if(wu>1)
{
xiaoshi=xiaoshi+12; //时间处理
}
}
TIM2CH1_CAPTURE_STA=0; //开启下一次捕获
printf("%d ",dat);
LCD_ShowNum(50,130,nian,4,16);
LCD_ShowNum(90,130,yue,2,16);
LCD_ShowNum(114,130,ri,2,16);
switch(xinqi)
{
case 0:
LCD_ShowString(160,130,200,16,16,"Sunday ");
break;
case 1:
LCD_ShowString(160,130,200,16,16,"Monday ");
break;
case 2:
LCD_ShowString(160,130,200,16,16,"Tuesday ");
break;
case 3:
LCD_ShowString(160,130,200,16,16,"Wednesday");
break;
case 4:
LCD_ShowString(160,130,200,16,16,"Thursday ");
break;
case 5:
LCD_ShowString(160,130,200,16,16,"Friday ");
break;
case 6:
LCD_ShowString(160,130,200,16,16,"Saturday ");
break;
}
LCD_ShowNum(60,80,xiaoshi,2,24);
LCD_ShowNum(94,80,fenzon,2,24);
LCD_ShowNum(128,80,miao,2,24);
POINT_COLOR=GBLUE;
LCD_ShowxNum(10,10,dat,10,24,0);
POINT_COLOR=RED;
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
六、运行效果展示

您好,有完整代码和压缩包吗
您好,有完整代码和压缩包吗