一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1396|回复: 8
收起左侧

[51单片机] 调GPS碰到的一个中断优先级的问题

[复制链接]
发表于 2015-10-14 21:47 | 显示全部楼层 |阅读模式
本帖最后由 gongzhu 于 2015-10-15 12:03 编辑

仍然在改进自己的大尺寸万年历,本来都已经调完成了。但感觉原来的按钮程序太土(Delayms(10)~~while(!K1)),就想改成状态机加定时器练练手,不曾想在连GPS出现了意想不到的问题。
GPS秒钟经常会走5、6秒后停顿1s,跳过这秒后正常走几秒再停顿1s。而DS3231走时则很正常,用GPS连接电脑直接读取数据则很正常,万年历刷回老按钮程序则走时又正常。
好了,确定是因为增加了timer0 定时器导致了问题。主程序的运行原理是这样的:通过定时器传递50ms周期读取DS3231的时间,如果时间有变化则刷新数码管,“顺便”刷新GPS的秒钟。
查程序初始化:
  1. void InitBps()
  2. {
  3.     SCON = 0x50;                    //8-bit variable UART
  4.     TMOD = 0x20;                    //Set Timer1 as 8-bit auto reload mode
  5.     TH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vaule
  6.     TR1 = 1;                        //Timer1 start run
  7.     ES = 1;                         //Enable UART interrupt
  8.     EA = 1;                         //Open master interrupt switch

  9.     ES = 1;                         //串口中断允许
  10.    PS = 1;                                //串口中断优先

  11.     TMOD |= 0X01;                                    //set timer0 as mode1 (16-bit)
  12.     TL0 = T1MS;                     //initial timer0 low byte
  13.     TH0 = T1MS >> 8;                //initial timer0 high byte
  14.     TR0 = 1;                                                //timer0 start running
  15.     ET0 = 1;                        //enable timer0 interrupt

  16.     EA = 1;                             //EA = 1; //总中断
  17.     DelayMS(100);
  18. }
复制代码
可是明明已经设置了串口优先啊,试着注销掉看一下   //PS = 1;
哎嗨,这下好了,观察了几个小时,gps秒钟都能与DS3231同步走秒了。


虽然解决了,但仍有不解,希望大神不吝指教!
贴出定时器代码,源自严泽远时钟程序的:
  1. void Timer0_interrupt() interrupt 1
  2. {
  3.     TL0 = T1MS;                     //reload timer0 low byte
  4.     TH0 = T1MS >> 8;                //reload timer0 high byte
  5.     if (Tcount-- == 0)               //1ms * 10
  6.     {
  7.         Tcount = 10;               //reset counter
  8.         KeyValue = GetKey();       //键值
  9.         KeyProc();
  10.     }

  11.     if(++F_50ms_Loop        >= 50)
  12.     {
  13.         F_50ms                =        1;
  14.         F_50ms_Loop                =        0;
  15.     }
  16.     if(++F_500ms_Loop        >= 500)
  17.     {
  18.         F_500ms        =        1;
  19.         F_500ms_Loop        =        0;
  20.     }
  21. }
复制代码
为验证GPS的时间问题,特意把前年做的GPS调试程序重新修改下,改正了一个bug,增加了一个与本地时间校对的记录。
211800nt2t2d2223q3364q.png

新程序界面:
2015-10-14_212618.png


勾选“测试”,保存的记录就有本地时间了:
2015-10-15_120211.png


朋友曾反应gps读取数据都正常,就是电脑校时出错。
在自己的win10上测试也发现了此问题,调时程序发现是日期的格式不一样,需把系统日期调成“2015-10-14”样(分隔符为“-”)就行了。
当然win7及以上系统需以管理员权限运行。
V2.0 GPS调时程序: gps.rar (330.18 KB, 下载次数: 37, 售价: 3 人民币)
 楼主| 发表于 2015-10-15 09:13 | 显示全部楼层
没人理睬啊,很高深吗?
我求助别的论坛了
发表于 2015-10-15 11:16 | 显示全部楼层
楼主暴露了你的位置,可以用导弹定位了
发表于 2015-10-15 11:41 来自手机 | 显示全部楼层
只是串口中断优先GPS数据是否串口中断里处理的????
 楼主| 发表于 2015-10-15 11:54 | 显示全部楼层
dy6354 发表于 2015-10-15 11:16
楼主暴露了你的位置,可以用导弹定位了

百密一疏!
 楼主| 发表于 2015-10-15 12:22 | 显示全部楼层
本帖最后由 gongzhu 于 2015-10-15 12:49 编辑
benli 发表于 2015-10-15 11:41
只是串口中断优先GPS数据是否串口中断里处理的????

主程序处理GPS的日期时间数据(UTC转北京时间),GPS串口中断只是简单读取:
  1. void GetRs232_Data() interrupt 4                                 /** GPS信息采集 **/
  2. {
  3.     u8 tmp;
  4.         //ES = 0;        
  5.     if(RI)
  6.     {
  7.         tmp = SBUF;
  8.         switch(tmp)
  9.         {
  10.         case '



  11. 多谢给了个方向!
  12. :
  13.             mode = 1;            //接收命令模式
  14.             byte_count = 0;      //接收位数清空
  15.             break;
  16.         case ',':
  17.             seg_count++;        //逗号计数加1
  18.             byte_count = 0;
  19.             break;
  20.         case '*':
  21.             mode = 0;
  22.             break;
  23.         default:
  24.             if(mode == 1)  //命令种类判断
  25.             {
  26.                 cmd[byte_count] = tmp;          //接收字符放入类型缓存
  27.                 if(byte_count >= 4)
  28.                 {
  29.                     //如果类型数据接收完毕,判断类型
  30.                     if(cmd[0] == 'G')
  31.                     {
  32.                         if(cmd[1] == 'P')
  33.                         {
  34.                             if(cmd[2] == 'R')
  35.                             {
  36.                                 if(cmd[3] == 'M')
  37.                                 {
  38.                                     if(cmd[4] == 'C')
  39.                                     {
  40.                                         mode = 2;
  41.                                         seg_count = 0;
  42.                                         byte_count = 0;
  43.                                     }
  44.                                     else         //以下5个else千万不能省略!
  45.                                     {
  46.                                         mode = 0;
  47.                                         seg_count = 0;
  48.                                         byte_count = 0;
  49.                                     }
  50.                                 }
  51.                                 else
  52.                                 {
  53.                                     mode = 0;
  54.                                     seg_count = 0;
  55.                                     byte_count = 0;
  56.                                 }
  57.                             }
  58.                             else
  59.                             {
  60.                                 mode = 0;
  61.                                 seg_count = 0;
  62.                                 byte_count = 0;
  63.                             }
  64.                         }
  65.                         else
  66.                         {
  67.                             mode = 0;
  68.                             seg_count = 0;
  69.                             byte_count = 0;
  70.                         }

  71.                     }
  72.                     else
  73.                     {
  74.                         mode = 0;
  75.                         seg_count = 0;
  76.                         byte_count = 0;
  77.                     }
  78.                 }
  79.             }
  80.             else if(mode == 2)
  81.             {
  82.                 //接收数据处理
  83.                 switch(seg_count)
  84.                 {
  85.                 case 1:
  86.                     if(byte_count < 6) //时间处理
  87.                     {
  88.                         if(tmp > 47 && tmp < 58)
  89.                             time[byte_count] = tmp;
  90.                     }
  91.                     break;
  92.                 case 2:                                //是否有效
  93.                     if(byte_count < 1)
  94.                     {
  95.                         va = tmp == 'A';
  96.                     }
  97.                     break;
  98.                 case 9:                                //日期处理
  99.                     if(byte_count < 6)
  100.                     {
  101.                         if(tmp > 47 && tmp < 58)
  102.                             date[byte_count] = tmp;

  103.                         if(byte_count == 5)         //日期时间接收完毕即可处理
  104.                         {
  105.                             FormatDT();
  106.                         }
  107.                     }
  108.                     break;
  109.                 case 10:                         //电脑发送强制校时信号          $GPRMC,024813.640,,,,,,,,150706,X
  110.                     if(byte_count < 1)
  111.                     {
  112.                         QJ = tmp == 'X' ;                //QJ 和 X 碰到一起了,别想歪了
  113.                     }
  114.                     break;
  115.                 default:
  116.                     break;
  117.                 }
  118.             }
  119.             byte_count++;        //接收数位加1
  120.             break;
  121.         }
  122.     }
  123.     RI = 0;
  124.         //ES = 1;        
  125. }
复制代码
多谢给了个方向!
发表于 2015-10-15 12:29 来自手机 | 显示全部楼层
虽然我不懂,但是楼主的追求精神值得佩服
 楼主| 发表于 2015-10-15 12:46 | 显示全部楼层
本帖最后由 gongzhu 于 2015-10-15 12:50 编辑

通知版主,论坛发帖 添加代码文字 部分有bug:
原代码:
2015-10-15_124424.png


复制进来后变成:
2015-10-15_124441.png


后台可能对$字符没处理好。
发表于 2015-10-15 16:54 来自手机 | 显示全部楼层
除非非常简单的程序,要不程序中尽量不要用while死循环等待,检测按键释放可以用一个标志位来完成

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-11 12:34 , Processed in 0.073406 second(s), 45 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表