Linux下从4G模组获取网络时间

从龙尚4G模组上获取网络时间并设置到板子

  • 获取4G模组网络时间并同步开发板
    • 龙尚4G模组获取时间
    • Linux下的测试程序
    • get_4g_time(char *com_port,char *time_buf)函数
    • 分析串口传来的字符串,将时间串拿出来
    • 时间串个数问题
    • 将ASCII时间串转为time_t时间
    • 用stime设置时间就可以了

获取4G模组网络时间并同步开发板

因开发板上没有外部RTC,每次需要连接服务器进行授时,但当服务器如果宕机了或者其他原因不能提供授时复位时,那么需要通过网络来同步授时时间到开发板来正确开启设备。

龙尚4G模组获取时间

不同4G模组的AT指令会稍微有所差别,根据供应商提供的AT指令说明手册即可简单找到针对时间的AT指令:

  1. 实时时钟: ,AT+CCLK,TA返回模块的当前时间;
  2. AT+CCLK 操作指令如表所示;
类型 指令 可能的返回结果 说明
设置指令 AT+CCLK= OK 若设置成功,则设置模块时间
设置指令 AT+CCLK= ERROR/+CME ERROR: 失败
查询指令 AT+CCLK? +CCKL:YY/MM/DD,hh:mm:ss<+zz>OK 若设置时区,则查询时显示时区,否则不显示时区。默认时区为00

Linux下的测试程序

测试代码:

#include 
#include "serial.h"
int main(int argc, char **argv)
{
	int i;
	char buf[6];
	get_4g_time(argv[1], buf);
	for(i = 0; i<6;i++)
	{
		printf("%x ",buf[i]);
	}
	printf("\n");
	return 0;
}

get_4g_time(char *com_port,char *time_buf)函数

打开串口并从4G模组串口中得到时间字符串:

int get_4g_time(char *com_port,char *time_buf)
{
	int tty_fd;
	int ret;
	int readBytes;
	int i=0,j=0,flag=0;
	char buf0[32];
	char tmp[6];
	char *p = NULL;
	tty_fd = InitCom(com_port);
	if(tty_fd < 0)
	{
		printf("open tty error:%s\n",com_port);
		return -1;	
	}
	SetConfig(tty_fd,115200,8,'N',1);
	char buf[BUFFER];
	memset(buf,0,BUFFER);
	sprintf(buf,"%s","AT+CCLK?\r");
	write(tty_fd,buf,strlen(buf));
	sleep(1);
	memset(buf,0,BUFFER);
	readBytes = read(tty_fd,buf,BUFFER);
	buf[readBytes] = '\0';
	printf("the readBytes is %d:%s\n",readBytes,buf);
	close(tty_fd);
	time_analysis(buf,time_buf);
	return 0;
}

分析串口传来的字符串,将时间串拿出来

分析串口字符串,将时间串拿出来并返回给定义的变量:

int time_analysis(char *source, char *time_buf)
{
	int i=0,j=0,flag=0;
	char buf[32];
	char tmp[6];
	char *p = source;
	int len = strlen(source);
    for(i=0;i<len;i++)
    {
        if(flag==0 && p[i]=='\"')
        {
            flag=1;
        }
        else if(flag==1 && p[i]=='\"')
        {
            buf[j]='\0';
        }
        else if(flag==1 && p[i]!='\"')
        {
        	if(p[i] >= '0' && p[i] <= '9')
            	buf[j++]=p[i];
        }
    }
	printf("buf is %s\n",buf);
	p = buf;
	for(i=0;i<6;i++)
	{
		memcpy(tmp,p,2);
		tmp[3] = '\0';
		if(i==3)
			time_buf[i] = atoi(tmp)+8;
		else
			time_buf[i] = atoi(tmp);
		p += 2;
	}
    return 0;
}

时间串个数问题

时间串根据自己的程序进行修改,我用的6字节的ASCII来存储时间,例如20年06月19日14点15分32秒,则字符串ASCII值为:14 06 13 0e 0f 20。

将ASCII时间串转为time_t时间

代码如下:

time_t ascii2timet(char *impact_time)
{
	struct tm tm = {0};
	char outstr[16];
	time_t tt;
	tm.tm_year = 2000 + impact_time[0] - 1900;
	tm.tm_mon = impact_time[1] - 1;
	tm.tm_mday = impact_time[2];
	tm.tm_hour = impact_time[3];
	tm.tm_min = impact_time[4];
	tm.tm_sec = impact_time[5];
	strftime(outstr,16,"%m%d%H%M%S",&tm);
	tt = mktime(&tm);
	return tt;
}

用stime设置时间就可以了

你可能感兴趣的:(4G模组获取时间,linux,物联网,编程语言,网络)