找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1212|回复: 1
收起左侧

带GPS授时的,交通信号灯控制行人道闸的开启,关闭和报警 单片机源程序

[复制链接]
ID:699018 发表于 2020-2-27 13:31 | 显示全部楼层 |阅读模式
  1. /****************控制卡程序如果接手动接三根线和地****************/
  2. //#include<reg52.h>
  3. #include <STC12C5A60S2.H>
  4. #include<stdlib.h>
  5. #include <intrins.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #define S2RI 0x01        //串口2接收中断请求标志位
  9. #define S2TI 0x02        //串口2发送中断请求标志位
  10. #define FOSC 11059200L      //System frequency
  11. #define BAUD 9600           //UART baudrate         
  12. #define uchar unsigned char
  13. #define uint unsigned int
  14. #define RELOAD_COUNT  0xfd   //256-(11059200/9600/32/12+0.5)波特率设置,括号内的数取整数(晶振频率除波特率除32除12加取整数)
  15. void Delay_ms(unsigned int n);
  16. void send_UART_one(unsigned char i);

  17. /****************定义IO口变量****************/
  18. sbit GREEN = P0^0;
  19. sbit RED = P0^1;                                                               
  20. sbit TING = P0^2;
  21. sbit KAI = P0^3;
  22. sbit GUAN = P0^4;
  23. sbit LED1 = P0^5;
  24. sbit LED2 = P0^6;
  25. sbit CHUN = P2^5;
  26. sbit XIA = P2^4;
  27. sbit QIU = P2^3;
  28. sbit DONG = P2^2;                                                           
  29. sbit QITA = P2^1;                                                         
  30. sbit KAIGUAN = P2^0;                                                         
  31. sbit YK_LUO = P1^0;                                                      
  32. sbit YK_SHENG = P1^1;
  33. sbit YK_TING= P1^5;
  34. sbit EN_TX_RX= P1^4;
  35. sbit WDT_WDI= P3^2;
  36. void IO_Init()
  37. {
  38. LED1 = 0;
  39. KAI = 1;
  40. GUAN=0;
  41. //TING=0;
  42. }

  43. /********************************/
  44. //sbit sf=P3^3;//485控制
  45. uchar a,week,yhy,sj,yuefen,shi,fen,miao,ri,nian;                         //添加
  46. uint yue,xiaoshi;
  47. uchar flag=1;

  48. void Show_Float(float fla);
  49. void xingqi();

  50. char xdata rev_buf[80];        //接收缓存
  51. uchar xdata rev_start = 0;     //接收开始标志
  52. uchar xdata rev_stop  = 0;     //接收停止标志
  53. uchar xdata gps_flag = 0;      //GPS处理标志
  54. uchar xdata change_page = 0;   //换页显示标志
  55. uchar xdata num = 0;           //

  56. void send_UART_two(unsigned char i);//串口二发送

  57. typedef struct{
  58.         int year;          //年
  59.         int month;         //月
  60.         int  day;   //日
  61.         int hour;        //时
  62.         int minute;        //分
  63.         int second;        //秒
  64. }DATE_TIME;

  65. typedef xdata struct{
  66.         double  latitude;  //经度
  67.         double  longitude; //纬度
  68.         int     latitude_Degree;        //度
  69.         int                latitude_Cent;                //分
  70.         int           latitude_Second;    //秒
  71.         int     longitude_Degree;        //度
  72.         int                longitude_Cent;                //分
  73.         int           longitude_Second;   //秒
  74.         float         speed;      //速度
  75.         float         direction;  //航向
  76.         float         height_ground;    //水平面高度
  77.         float         height_sea;       //海拔高度
  78.         int     satellite;
  79.         uchar         NS;
  80.         uchar         EW;
  81.         DATE_TIME D;
  82. }GPS_INFO;
  83. int GPS_RMC_Parse(char *line,GPS_INFO *GPS);
  84. #define DelayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  85. static uchar GetComma(uchar num,char* str);
  86. static double Get_Double_Number(char *s);
  87. static float Get_Float_Number(char *s);
  88. static void UTC2BTC(DATE_TIME *GPS);

  89. //====================================================================//
  90. // 语法格式:int GPS_RMC_Parse(char *line, GPS_INFO *GPS)  
  91. // 实现功能:把gps模块的GPRMC信息解析为可识别的数据
  92. // 参    数:存放原始信息字符数组、存储可识别数据的结构体
  93. // 返 回 值:
  94. //                         1: 解析GPRMC完毕
  95. //           0: 没有进行解析,或数据无效
  96. //====================================================================//
  97. int GPS_RMC_Parse(char *line,GPS_INFO *GPS)
  98. {
  99.         uchar ch, status, tmp;
  100.         float lati_cent_tmp, lati_second_tmp;
  101.         float long_cent_tmp, long_second_tmp;
  102.         float speed_tmp;
  103.         char *buf = line;
  104.         ch = buf[5];
  105.         status = buf[GetComma(2, buf)];

  106.         if (ch == 'C')  //如果第五个字符是C,($GPRMC)
  107.         {
  108.                 if (status == 'A')  //如果数据有效,则分析
  109.                 {
  110.                         GPS -> NS       = buf[GetComma(4, buf)];
  111.                         GPS -> EW       = buf[GetComma(6, buf)];
  112.                         GPS->latitude   = Get_Double_Number(&buf[GetComma(3, buf)]);
  113.                         GPS->longitude  = Get_Double_Number(&buf[GetComma( 5, buf)]);
  114.                 GPS->latitude_Degree  = (int)GPS->latitude / 100;       //分离纬度
  115.                         lati_cent_tmp         = (GPS->latitude - GPS->latitude_Degree * 100);
  116.                         GPS->latitude_Cent    = (int)lati_cent_tmp;
  117.                         lati_second_tmp       = (lati_cent_tmp - GPS->latitude_Cent) * 60;
  118.                         GPS->latitude_Second  = (int)lati_second_tmp;
  119.                         GPS->longitude_Degree = (int)GPS->longitude / 100;        //分离经度
  120.                         long_cent_tmp         = (GPS->longitude - GPS->longitude_Degree * 100);
  121.                         GPS->longitude_Cent   = (int)long_cent_tmp;   
  122.                         long_second_tmp       = (long_cent_tmp - GPS->longitude_Cent) * 60;
  123.                         GPS->longitude_Second = (int)long_second_tmp;
  124.                         speed_tmp      = Get_Float_Number(&buf[GetComma(7, buf)]);    //速度(单位:海里/时)
  125.                         GPS->speed     = speed_tmp * 1.85;                           //1海里=1.85公里
  126.                         GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度                        
  127.                         GPS->D.hour    = (buf[7] - '0') * 10 + (buf[8] - '0');                //时间                        
  128.                         GPS->D.minute  = (buf[9] - '0') * 10 + (buf[10] - '0');                        
  129.                         GPS->D.second  = (buf[11] - '0') * 10 + (buf[12] - '0');                        
  130.                         tmp = GetComma(9, buf);
  131.                         GPS->D.day     = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期                        
  132.                         GPS->D.month   = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0');                        
  133.                         GPS->D.year    = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0');//+2000;
  134.                         UTC2BTC(&GPS->D);                        
  135.                         return 1;
  136.                 }               
  137.         }        
  138.         return 0;
  139. }
  140. //====================================================================//
  141. // 语法格式: static float Str_To_Float(char *buf)
  142. // 实现功能: 把一个字符串转化成浮点数
  143. // 参    数:字符串
  144. // 返 回 值:转化后单精度值
  145. //====================================================================//
  146. static float Str_To_Float(char *buf)
  147. {
  148.         float rev = 0;
  149.         float dat;
  150.         int integer = 1;
  151.         char *str = buf;
  152.         int i;
  153.         while(*str != '\0')
  154.         {
  155.                 switch(*str)
  156.                 {
  157.                         case '0':
  158.                                 dat = 0;
  159.                                 break;
  160.                         case '1':
  161.                                 dat = 1;
  162.                                 break;
  163.                         case '2':
  164.                                 dat = 2;
  165.                                 break;               
  166.                         case '3':
  167.                                 dat = 3;
  168.                                 break;
  169.                         case '4':
  170.                                 dat = 4;
  171.                                 break;
  172.                         case '5':
  173.                                 dat = 5;
  174.                                 break;
  175.                         case '6':
  176.                                 dat = 6;
  177.                                 break;
  178.                         case '7':
  179.                                 dat = 7;
  180.                                 break;
  181.                         case '8':
  182.                                 dat = 8;
  183.                                 break;
  184.                         case '9':
  185.                                 dat = 9;
  186.                                 break;
  187.                         case '.':
  188.                                 dat = '.';
  189.                                 break;
  190.                 }
  191.                 if(dat == '.')
  192.                 {
  193.                         integer = 0;
  194.                         i = 1;
  195.                         str ++;
  196.                         continue;
  197.                 }
  198.                 if( integer == 1 )
  199.                 {
  200.                         rev = rev * 10 + dat;
  201.                 }
  202.                 else
  203.                 {
  204.                         rev = rev + dat / (10 * i);
  205.                         i = i * 10 ;
  206.                 }
  207.                 str ++;
  208.         }
  209.         return rev;
  210. }
  211.                                                                                                 
  212. //====================================================================//
  213. // 语法格式: static float Get_Float_Number(char *s)
  214. // 实现功能: 把给定字符串第一个逗号之前的字符转化成单精度型
  215. // 参    数:字符串
  216. // 返 回 值:转化后单精度值
  217. //====================================================================//
  218. static float Get_Float_Number(char *s)
  219. {
  220.         char buf[10];
  221.         uchar i;
  222.         float rev;
  223.         i=GetComma(1, s);
  224.         i = i - 1;
  225.         strncpy(buf, s, i);
  226.         buf[i] = 0;
  227.         rev=Str_To_Float(buf);
  228.         return rev;        
  229. }

  230. //====================================================================//
  231. // 语法格式: static double Str_To_Double(char *buf)
  232. // 实现功能: 把一个字符串转化成浮点数
  233. // 参    数:字符串
  234. // 返 回 值:转化后双精度值
  235. //====================================================================//
  236. static double Str_To_Double(char *buf)
  237. {
  238.         double rev = 0;
  239.         double dat;
  240.         int integer = 1;
  241.         char *str = buf;
  242.         int i;
  243.         while(*str != '\0')
  244.         {
  245.                 switch(*str)
  246.                 {
  247.                         case '0':
  248.                                 dat = 0;
  249.                                 break;
  250.                         case '1':
  251.                                 dat = 1;
  252.                                 break;
  253.                         case '2':
  254.                                 dat = 2;
  255.                                 break;               
  256.                         case '3':
  257.                                 dat = 3;
  258.                                 break;
  259.                         case '4':
  260.                                 dat = 4;
  261.                                 break;
  262.                         case '5':
  263.                                 dat = 5;
  264.                                 break;
  265.                         case '6':
  266.                                 dat = 6;
  267.                                 break;
  268.                         case '7':
  269.                                 dat = 7;
  270.                                 break;
  271.                         case '8':
  272.                                 dat = 8;
  273.                                 break;
  274.                         case '9':
  275.                                 dat = 9;
  276.                                 break;
  277.                         case '.':
  278.                                 dat = '.';
  279.                                 break;
  280.                 }
  281.                 if(dat == '.')
  282.                 {
  283.                         integer = 0;
  284.                         i = 1;
  285.                         str ++;
  286.                         continue;
  287.                 }
  288.                 if( integer == 1 )
  289.                 {
  290.                         rev = rev * 10 + dat;
  291.                 }
  292.                 else
  293.                 {
  294.                         rev = rev + dat / (10 * i);
  295.                         i = i * 10 ;
  296.                 }
  297.                 str ++;
  298.         }
  299.         return rev;
  300. }
  301.                                                                                                 
  302. //====================================================================//
  303. // 语法格式: static double Get_Double_Number(char *s)
  304. // 实现功能:把给定字符串第一个逗号之前的字符转化成双精度型
  305. // 参    数:字符串
  306. // 返 回 值:转化后双精度值
  307. //====================================================================//
  308. static double Get_Double_Number(char *s)
  309. {
  310.         char buf[10];
  311.         uchar i;
  312.         double rev;
  313.         i=GetComma(1, s);
  314.         i = i - 1;
  315.         strncpy(buf, s, i);
  316.         buf[i] = 0;
  317.         rev=Str_To_Double(buf);
  318.         return rev;        
  319. }

  320. //====================================================================//
  321. // 语法格式:static uchar GetComma(uchar num,char *str)
  322. // 实现功能:计算字符串中各个逗号的位置
  323. // 参    数:查找的逗号是第几个的个数,需要查找的字符串
  324. // 返 回 值:0
  325. //====================================================================//
  326. static uchar GetComma(uchar num,char *str)
  327. {
  328.         uchar i,j = 0;
  329.         int len=strlen(str);
  330.         for(i = 0;i < len;i ++)
  331.         {
  332.                 if(str[i] == ',')
  333.                         j++;
  334.                 if(j == num)
  335.                         return i + 1;        
  336.         }
  337.         return 0;        
  338. }

  339. //====================================================================//
  340. // 语法格式:void UTC2BTC(DATE_TIME *GPS)
  341. // 实现功能:转化时间为北京时区的时间
  342. // 参    数:存放时间的结构体
  343. // 返 回 值:无
  344. //====================================================================//
  345. static void UTC2BTC(DATE_TIME *GPS)
  346. {
  347.         GPS->second ++;  
  348.         fen=((GPS->minute/10)<<4)+(GPS->minute%10);  //添加
  349.         miao=((GPS->second/10)<<4)+(GPS->second%10);   //添加
  350.         if(GPS->second > 59)
  351.         {
  352.                 GPS->second = 0;
  353.                 GPS->minute ++;
  354.                 if(GPS->minute > 59)
  355.                 {
  356.                         GPS->minute = 0;
  357.                         GPS->hour ++;
  358.                 }
  359.         }        

  360.     GPS->hour = GPS->hour + 8;
  361.         xiaoshi=GPS->hour;
  362.         shi=((GPS->hour/10)<<4)+(GPS->hour%10);   //添加
  363.         ri=((GPS->day/10)<<4)+(GPS->day%10);          //添加
  364.         if(GPS->hour > 23)
  365.         {
  366.                 GPS->hour -= 24;
  367.                 GPS->day += 1;
  368.                 if(GPS->month == 2 ||GPS->month == 4 ||GPS->month == 6 ||GPS->month == 9 ||GPS->month == 11 )
  369.                 {
  370.                         if(GPS->day > 30)
  371.                         {
  372.                                    GPS->day = 1;
  373.                                 GPS->month++;
  374.                         }
  375.                 }
  376.                 else
  377.                 {
  378.                         if(GPS->day > 31)
  379.                         {        
  380.                                    GPS->day = 1;
  381.                                 GPS->month ++;
  382.                         }
  383.                 }
  384.                 if(GPS->year % 4 == 0 )
  385.                 {
  386.                            if(GPS->day > 29 && GPS->month == 2)
  387.                         {               
  388.                                    GPS->day = 1;
  389.                                 GPS->month ++;
  390.                         }
  391.                 }
  392.                 else
  393.                 {
  394.                            if(GPS->day > 28 &&GPS->month == 2)
  395.                         {
  396.                                    GPS->day = 1;
  397.                                 GPS->month ++;
  398.                         }
  399.                 }
  400.                 if(GPS->month > 12)
  401.                 {
  402.                         GPS->month -= 12;
  403.                         GPS->year ++;
  404.                 }               
  405.         }
  406.         yue=GPS->month;
  407.         yuefen=((GPS->month/10)<<4)+(GPS->month%10);          //添加
  408.         nian=((GPS->year/10)<<4)+(GPS->year%10);                  //添加
  409. //        sj=0x14;//世纪
  410.         if(GPS->month==0x01)
  411.                 {
  412.                         yue=0x0d;
  413.                    GPS->year--;
  414.                 }
  415.         if(GPS->month==0x02)
  416.                 {
  417.                         yue=0x0e;
  418.                         GPS->year--;
  419.                 }
  420. //        week=(70+GPS->year+(GPS->year/4)+((26*(yue+1))/10)+GPS->day+(sj/4)-1-(2*sj))%7;
  421.     xingqi();
  422.         week=(GPS->year+(GPS->year/4)+yhy+GPS->day+6)%7;
  423.         if(GPS->month==0x01)
  424.                 {
  425.                    GPS->year++;
  426.                 }
  427.         if(GPS->month==0x02)
  428.                 {
  429.                         GPS->year++;
  430.                 }
  431.         if(week==0x00)
  432.                 {
  433.                         week=0x07;
  434.                 }        
  435.         send_UART_one(0xeb);
  436.         send_UART_one(miao);                   //修改后
  437.         send_UART_one(fen);                           //修改后
  438.         send_UART_one(shi);                                //修改后
  439.         send_UART_one(ri);                                //修改后
  440.     send_UART_one(yuefen);                        //修改后
  441.         send_UART_one(week);
  442.         send_UART_one(nian);                        //修改后
  443.         send_UART_one(0xec);

  444. }
  445. //EB 49 43 09 07 11 03 18 EC

  446. GPS_INFO   GPS;  //GPS信息结构体

  447. void xingqi()
  448.         {
  449.                 yhy=(26*(yue+1))/10;
  450.         }

  451. /*void send_UART_two(unsigned char i)
  452.         {
  453.                 unsigned char temp = 0;
  454.                 IE2=0x00;        //关串口2中断,es2=0
  455.             S2CON=S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
  456.             S2BUF=i;
  457.             do
  458.                 {
  459.                         temp=S2CON;
  460.                         temp=temp & 0x02;
  461.                 }while(temp==0);
  462.             S2CON=S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
  463.                 IE2=0x01;        //允许串口2中断,ES2=1
  464.         }  */

  465. void send_UART_one(unsigned char i)                                                 //外加+++
  466. {
  467.         unsigned char temp = 0;
  468.                 ES=0x00;        //关串口1中断,es=0
  469.             TI=0; //B'11111101,清零串口1发送完成中断请求标志
  470.             SBUF=i;
  471.                 while(TI==0);
  472.             TI=0; //B'11111101,清零串口1发送完成中断请求标志
  473.                 ES=0x01;        //允许串口1中断,ES=1
  474. }




  475. /****************************************
  476. 串口初始化        
  477. /****************************************/
  478. void Uart_Init(void)
  479. {
  480.                 TMOD=0x21;
  481.         
  482.                 TH0=0x3c;
  483.                 TL0=0xb0;
  484.                 ET0=1;//定时/计数器T0中断允许位
  485.                 TR0=1;//启动定时/计数器工

  486.                 EX1=0;//开外部中断1                判断程序运行需关闭外部中断
  487.                 IT1=1;//跳变沿方式
  488.            
  489.                 SCON=0x50;   //0101,0000 8位可变波特率,无奇偶校验位
  490.                 S2CON=0x50;   //0101,0000 8位可变波特率,无奇偶校验位,允许接收
  491.                 BRT=RELOAD_COUNT; //设置独立波特率发生器的重载初值
  492.                 AUXR=0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS
  493.                 ES=1;    //允许串口中断
  494.                 IE2=0x01;        //允许串口2中断,ES2=1
  495.         
  496.                 EA=1;//CPU中断总允许
  497.                 //sf=1;
  498. }
  499. /*************道闸关闭函数******************/
  500. void hong_led()
  501. {
  502.   if((RED==1)&&(GREEN==0)&&(flag==1))
  503.   {
  504.          
  505.                 KAI=0;        
  506.    GUAN=1;
  507.          TING=1;
  508.      Delay_ms(1000);
  509.                         WDT_WDI=~WDT_WDI;
  510.       GUAN=0;
  511.                         KAI=0;
  512.                   flag=0;
  513.       //TING=1;                                                                                                                                                                                      
  514.    }     
复制代码

回复

使用道具 举报

ID:1 发表于 2020-2-28 01:18 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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