| 
钻石会员 主题
回帖0
积分11757
阅读权限50
注册时间2013-9-14
最后登录1970-1-1
在线时间 小时
 
 | 
 
| 本帖最后由 gongzhu 于 2014-8-22 22:32 编辑 
 做个数码管显示的万年历程序,综合了两个程序:
 程序1,读取DS3231时间数据并显示到数码管,没有问题;
 程序2,读取串口gps时间数据并显示到数码管,也没有问题。
 
 现将程序1、2合并,同时读取DS3231和串口GPS数据并发送至数码管显示,开始运行正常,运行一段(不固定)时间后死机。
 知道是中断处理上的问题,便给main()和串口接收加上了中断开关ES信号,这下不会死机了,可是gps的时间显示每隔4、5秒会停顿一秒,下一秒后又会正常运行几秒,如此循环(不知是否能用“跳秒”描述),而DS3231的数据则正常更新显示。
 因第一次碰到,不懂如何处理。
 
 主要程序如下:
 
 void GetDS3231();  //读取DS3231数据,并处理农历、星期
 void Send2Led();   //驱动Max7219更新数码管数据,含DS3231和GPS的时间数据
 void FormatString(char *p,uchar len);//格式化GPRMC字符串,把时间、日期传递给全局变量
 
 main()//主函数:100ms循环调用GetDS3231() ,发现数据有更新则刷新Max7219更新数码管数据
 {
 uchar T=0;//判断秒有无更新,防止过快刷新数码管驱动芯片max7219
 init(); //系统初始化
 InitBps();//串口初始化
 
 while(1)//进入无限循环
 {
 if(w == 0)         //运行模式
 {
 ES = 0; //中断关
 GetDS3231();        //读取DS3231时间数据
 ES = 1;//中断开
 if(T != Dstime[0])
 {
 Send2Led();//更新数码管数据
 T = Dstime[0];
 }
 //ES = 1;//中断开放在此处运行效果一样
 DelayMS(100); //一定得延时,否则串口不能正常接收数据
 }
 else
 {}
 //检测按键设置时间略
 }
 }
 
 GetRs232_Data() interrupt 4   //串口中断读取GPS数据,截取GPRMC数据串并处理出时间日期数据
 {
 uchar tmp, i;
 ES = 0;//中断关
 if(RI)
 {
 tmp = SBUF;
 switch(tmp)
 {
 case '$':
 mode = 1;                //接收命令模式
 byte_count = 0;          //接收位数清空
 memset(RsBuf, 0, 80);
 RsBuf[byte_count++] = tmp;
 break;
 case '\r':
 if(mode == 2)
 buf_full = 1;
 else
 buf_full = 0;
 mode = 0;
 RsBuf[byte_count] = '\0';
 break;
 default:
 if(mode == 1)
 {
 //命令种类判断
 RsBuf[byte_count] = tmp;                //接收字符放入类型缓存
 if(byte_count == 5)                     //如果类型数据接收完毕,判断类型
 {
 if(RsBuf[1] == 'G' && RsBuf[2] == 'P' && RsBuf[3] == 'R')
 {
 if(RsBuf[4] == 'M' && RsBuf[5] == 'C')
 {
 mode = 2;   /** 获取标志头 $GPRMC        缓存可以接收后续字符 **/
 }
 else
 {
 mode = 0;
 byte_count = 0;
 }
 }
 else
 {
 mode = 0;
 byte_count = 0;
 }
 }
 
 byte_count++;
 }
 else if(mode == 2)
 {
 RsBuf[byte_count] = tmp;
 byte_count++;
 }
 
 if(byte_count > 73)         /** 接收数据过长,超过73Byte还没标志尾抛弃 **/
 {
 mode = 0;
 byte_count = 0;
 memset(RsBuf, 0, 80);
 }
 break;
 }
 if(buf_full && byte_count > 36 && Checksum(RsBuf, byte_count))         // 标志头尾齐全、至少有时间日期数据、异或校验无误,才能解析数据
 {
 FormatString(RsBuf, byte_count);//格式化GPRMC字符串,把时间、日期传递给全局变量
 buf_full = 0;
 }
 }
 RI = 0;
 ES = 1;//中断开
 }
 
 
 补充,GPS通信协议:9600,N,8,1 ;每秒发送一次,总数据525字节左右,如下:
 $GPRMC,060323.00,A,3333.87334,N,11859.00314,E,0.087,353.41,180814,,,A*68
 $GPVTG,353.41,T,,M,0.087,N,0.162,K,A*37
 $GPGGA,060323.00,3333.87334,N,11859.00314,E,1,4,16.63,-18.5,M,4.9,M,,*7B
 $GPGSA,A,3,28,01,11,17,,,,,,,,,18.83,16.63,8.83*0C
 $GPGSV,3,1,12,28,73,325,36,01,57,039,39,04,69,241,,11,36,051,37*7D
 $GPGSV,3,2,12,20,44,130,,17,39,300,39,30,32,216,,32,31,075,*78
 $GPGSV,3,3,12,08,20,194,,06,12,230,,07,12,190,,19,06,081,*73
 $GPGLL,3333.87334,N,11859.00314,E,060323.00,A,A*64
 $GPZDA,060323.00,18,08,2014,00,00*64
 
 
 
 
 | 
 |