标题:
带GPS授时的,交通信号灯控制行人道闸的开启,关闭和报警 单片机源程序
[打印本页]
作者:
jgsliguangzhao
时间:
2020-2-27 13:31
标题:
带GPS授时的,交通信号灯控制行人道闸的开启,关闭和报警 单片机源程序
/****************控制卡程序如果接手动接三根线和地****************/
//#include<reg52.h>
#include <STC12C5A60S2.H>
#include<stdlib.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#define S2RI 0x01 //串口2接收中断请求标志位
#define S2TI 0x02 //串口2发送中断请求标志位
#define FOSC 11059200L //System frequency
#define BAUD 9600 //UART baudrate
#define uchar unsigned char
#define uint unsigned int
#define RELOAD_COUNT 0xfd //256-(11059200/9600/32/12+0.5)波特率设置,括号内的数取整数(晶振频率除波特率除32除12加取整数)
void Delay_ms(unsigned int n);
void send_UART_one(unsigned char i);
/****************定义IO口变量****************/
sbit GREEN = P0^0;
sbit RED = P0^1;
sbit TING = P0^2;
sbit KAI = P0^3;
sbit GUAN = P0^4;
sbit LED1 = P0^5;
sbit LED2 = P0^6;
sbit CHUN = P2^5;
sbit XIA = P2^4;
sbit QIU = P2^3;
sbit DONG = P2^2;
sbit QITA = P2^1;
sbit KAIGUAN = P2^0;
sbit YK_LUO = P1^0;
sbit YK_SHENG = P1^1;
sbit YK_TING= P1^5;
sbit EN_TX_RX= P1^4;
sbit WDT_WDI= P3^2;
void IO_Init()
{
LED1 = 0;
KAI = 1;
GUAN=0;
//TING=0;
}
/********************************/
//sbit sf=P3^3;//485控制
uchar a,week,yhy,sj,yuefen,shi,fen,miao,ri,nian; //添加
uint yue,xiaoshi;
uchar flag=1;
void Show_Float(float fla);
void xingqi();
char xdata rev_buf[80]; //接收缓存
uchar xdata rev_start = 0; //接收开始标志
uchar xdata rev_stop = 0; //接收停止标志
uchar xdata gps_flag = 0; //GPS处理标志
uchar xdata change_page = 0; //换页显示标志
uchar xdata num = 0; //
void send_UART_two(unsigned char i);//串口二发送
typedef struct{
int year; //年
int month; //月
int day; //日
int hour; //时
int minute; //分
int second; //秒
}DATE_TIME;
typedef xdata struct{
double latitude; //经度
double longitude; //纬度
int latitude_Degree; //度
int latitude_Cent; //分
int latitude_Second; //秒
int longitude_Degree; //度
int longitude_Cent; //分
int longitude_Second; //秒
float speed; //速度
float direction; //航向
float height_ground; //水平面高度
float height_sea; //海拔高度
int satellite;
uchar NS;
uchar EW;
DATE_TIME D;
}GPS_INFO;
int GPS_RMC_Parse(char *line,GPS_INFO *GPS);
#define DelayNOP(); {_nop_();_nop_();_nop_();_nop_();};
static uchar GetComma(uchar num,char* str);
static double Get_Double_Number(char *s);
static float Get_Float_Number(char *s);
static void UTC2BTC(DATE_TIME *GPS);
//====================================================================//
// 语法格式:int GPS_RMC_Parse(char *line, GPS_INFO *GPS)
// 实现功能:把gps模块的GPRMC信息解析为可识别的数据
// 参 数:存放原始信息字符数组、存储可识别数据的结构体
// 返 回 值:
// 1: 解析GPRMC完毕
// 0: 没有进行解析,或数据无效
//====================================================================//
int GPS_RMC_Parse(char *line,GPS_INFO *GPS)
{
uchar ch, status, tmp;
float lati_cent_tmp, lati_second_tmp;
float long_cent_tmp, long_second_tmp;
float speed_tmp;
char *buf = line;
ch = buf[5];
status = buf[GetComma(2, buf)];
if (ch == 'C') //如果第五个字符是C,($GPRMC)
{
if (status == 'A') //如果数据有效,则分析
{
GPS -> NS = buf[GetComma(4, buf)];
GPS -> EW = buf[GetComma(6, buf)];
GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]);
GPS->longitude = Get_Double_Number(&buf[GetComma( 5, buf)]);
GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度
lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100);
GPS->latitude_Cent = (int)lati_cent_tmp;
lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60;
GPS->latitude_Second = (int)lati_second_tmp;
GPS->longitude_Degree = (int)GPS->longitude / 100; //分离经度
long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100);
GPS->longitude_Cent = (int)long_cent_tmp;
long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60;
GPS->longitude_Second = (int)long_second_tmp;
speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/时)
GPS->speed = speed_tmp * 1.85; //1海里=1.85公里
GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度
GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); //时间
GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0');
tmp = GetComma(9, buf);
GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期
GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0');
GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0');//+2000;
UTC2BTC(&GPS->D);
return 1;
}
}
return 0;
}
//====================================================================//
// 语法格式: static float Str_To_Float(char *buf)
// 实现功能: 把一个字符串转化成浮点数
// 参 数:字符串
// 返 回 值:转化后单精度值
//====================================================================//
static float Str_To_Float(char *buf)
{
float rev = 0;
float dat;
int integer = 1;
char *str = buf;
int i;
while(*str != '\0')
{
switch(*str)
{
case '0':
dat = 0;
break;
case '1':
dat = 1;
break;
case '2':
dat = 2;
break;
case '3':
dat = 3;
break;
case '4':
dat = 4;
break;
case '5':
dat = 5;
break;
case '6':
dat = 6;
break;
case '7':
dat = 7;
break;
case '8':
dat = 8;
break;
case '9':
dat = 9;
break;
case '.':
dat = '.';
break;
}
if(dat == '.')
{
integer = 0;
i = 1;
str ++;
continue;
}
if( integer == 1 )
{
rev = rev * 10 + dat;
}
else
{
rev = rev + dat / (10 * i);
i = i * 10 ;
}
str ++;
}
return rev;
}
//====================================================================//
// 语法格式: static float Get_Float_Number(char *s)
// 实现功能: 把给定字符串第一个逗号之前的字符转化成单精度型
// 参 数:字符串
// 返 回 值:转化后单精度值
//====================================================================//
static float Get_Float_Number(char *s)
{
char buf[10];
uchar i;
float rev;
i=GetComma(1, s);
i = i - 1;
strncpy(buf, s, i);
buf[i] = 0;
rev=Str_To_Float(buf);
return rev;
}
//====================================================================//
// 语法格式: static double Str_To_Double(char *buf)
// 实现功能: 把一个字符串转化成浮点数
// 参 数:字符串
// 返 回 值:转化后双精度值
//====================================================================//
static double Str_To_Double(char *buf)
{
double rev = 0;
double dat;
int integer = 1;
char *str = buf;
int i;
while(*str != '\0')
{
switch(*str)
{
case '0':
dat = 0;
break;
case '1':
dat = 1;
break;
case '2':
dat = 2;
break;
case '3':
dat = 3;
break;
case '4':
dat = 4;
break;
case '5':
dat = 5;
break;
case '6':
dat = 6;
break;
case '7':
dat = 7;
break;
case '8':
dat = 8;
break;
case '9':
dat = 9;
break;
case '.':
dat = '.';
break;
}
if(dat == '.')
{
integer = 0;
i = 1;
str ++;
continue;
}
if( integer == 1 )
{
rev = rev * 10 + dat;
}
else
{
rev = rev + dat / (10 * i);
i = i * 10 ;
}
str ++;
}
return rev;
}
//====================================================================//
// 语法格式: static double Get_Double_Number(char *s)
// 实现功能:把给定字符串第一个逗号之前的字符转化成双精度型
// 参 数:字符串
// 返 回 值:转化后双精度值
//====================================================================//
static double Get_Double_Number(char *s)
{
char buf[10];
uchar i;
double rev;
i=GetComma(1, s);
i = i - 1;
strncpy(buf, s, i);
buf[i] = 0;
rev=Str_To_Double(buf);
return rev;
}
//====================================================================//
// 语法格式:static uchar GetComma(uchar num,char *str)
// 实现功能:计算字符串中各个逗号的位置
// 参 数:查找的逗号是第几个的个数,需要查找的字符串
// 返 回 值:0
//====================================================================//
static uchar GetComma(uchar num,char *str)
{
uchar i,j = 0;
int len=strlen(str);
for(i = 0;i < len;i ++)
{
if(str[i] == ',')
j++;
if(j == num)
return i + 1;
}
return 0;
}
//====================================================================//
// 语法格式:void UTC2BTC(DATE_TIME *GPS)
// 实现功能:转化时间为北京时区的时间
// 参 数:存放时间的结构体
// 返 回 值:无
//====================================================================//
static void UTC2BTC(DATE_TIME *GPS)
{
GPS->second ++;
fen=((GPS->minute/10)<<4)+(GPS->minute%10); //添加
miao=((GPS->second/10)<<4)+(GPS->second%10); //添加
if(GPS->second > 59)
{
GPS->second = 0;
GPS->minute ++;
if(GPS->minute > 59)
{
GPS->minute = 0;
GPS->hour ++;
}
}
GPS->hour = GPS->hour + 8;
xiaoshi=GPS->hour;
shi=((GPS->hour/10)<<4)+(GPS->hour%10); //添加
ri=((GPS->day/10)<<4)+(GPS->day%10); //添加
if(GPS->hour > 23)
{
GPS->hour -= 24;
GPS->day += 1;
if(GPS->month == 2 ||GPS->month == 4 ||GPS->month == 6 ||GPS->month == 9 ||GPS->month == 11 )
{
if(GPS->day > 30)
{
GPS->day = 1;
GPS->month++;
}
}
else
{
if(GPS->day > 31)
{
GPS->day = 1;
GPS->month ++;
}
}
if(GPS->year % 4 == 0 )
{
if(GPS->day > 29 && GPS->month == 2)
{
GPS->day = 1;
GPS->month ++;
}
}
else
{
if(GPS->day > 28 &&GPS->month == 2)
{
GPS->day = 1;
GPS->month ++;
}
}
if(GPS->month > 12)
{
GPS->month -= 12;
GPS->year ++;
}
}
yue=GPS->month;
yuefen=((GPS->month/10)<<4)+(GPS->month%10); //添加
nian=((GPS->year/10)<<4)+(GPS->year%10); //添加
// sj=0x14;//世纪
if(GPS->month==0x01)
{
yue=0x0d;
GPS->year--;
}
if(GPS->month==0x02)
{
yue=0x0e;
GPS->year--;
}
// week=(70+GPS->year+(GPS->year/4)+((26*(yue+1))/10)+GPS->day+(sj/4)-1-(2*sj))%7;
xingqi();
week=(GPS->year+(GPS->year/4)+yhy+GPS->day+6)%7;
if(GPS->month==0x01)
{
GPS->year++;
}
if(GPS->month==0x02)
{
GPS->year++;
}
if(week==0x00)
{
week=0x07;
}
send_UART_one(0xeb);
send_UART_one(miao); //修改后
send_UART_one(fen); //修改后
send_UART_one(shi); //修改后
send_UART_one(ri); //修改后
send_UART_one(yuefen); //修改后
send_UART_one(week);
send_UART_one(nian); //修改后
send_UART_one(0xec);
}
//EB 49 43 09 07 11 03 18 EC
GPS_INFO GPS; //GPS信息结构体
void xingqi()
{
yhy=(26*(yue+1))/10;
}
/*void send_UART_two(unsigned char i)
{
unsigned char temp = 0;
IE2=0x00; //关串口2中断,es2=0
S2CON=S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
S2BUF=i;
do
{
temp=S2CON;
temp=temp & 0x02;
}while(temp==0);
S2CON=S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
IE2=0x01; //允许串口2中断,ES2=1
} */
void send_UART_one(unsigned char i) //外加+++
{
unsigned char temp = 0;
ES=0x00; //关串口1中断,es=0
TI=0; //B'11111101,清零串口1发送完成中断请求标志
SBUF=i;
while(TI==0);
TI=0; //B'11111101,清零串口1发送完成中断请求标志
ES=0x01; //允许串口1中断,ES=1
}
/****************************************
串口初始化
/****************************************/
void Uart_Init(void)
{
TMOD=0x21;
TH0=0x3c;
TL0=0xb0;
ET0=1;//定时/计数器T0中断允许位
TR0=1;//启动定时/计数器工
EX1=0;//开外部中断1 判断程序运行需关闭外部中断
IT1=1;//跳变沿方式
SCON=0x50; //0101,0000 8位可变波特率,无奇偶校验位
S2CON=0x50; //0101,0000 8位可变波特率,无奇偶校验位,允许接收
BRT=RELOAD_COUNT; //设置独立波特率发生器的重载初值
AUXR=0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS
ES=1; //允许串口中断
IE2=0x01; //允许串口2中断,ES2=1
EA=1;//CPU中断总允许
//sf=1;
}
/*************道闸关闭函数******************/
void hong_led()
{
if((RED==1)&&(GREEN==0)&&(flag==1))
{
KAI=0;
GUAN=1;
TING=1;
Delay_ms(1000);
WDT_WDI=~WDT_WDI;
GUAN=0;
KAI=0;
flag=0;
//TING=1;
}
复制代码
作者:
admin
时间:
2020-2-28 01:18
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1