|
樓主 |
發表於 2014-1-6 01:37:32
|
顯示全部樓層
完整程式如下:
/*20131120 完成 GPS顯示時間 與速度節 超速50公里(27節)ALARM
40公里以上 選擇性 警報 50公里以上一定警報 60公里以上警報停止
$GPRMC,115900.000,A,3723.2475,N,12158.3416,E,00.38,, test pattern
*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include<intrins.h>
bit disp_flag;
bit dispt_flag;//切換顯示
bit rec; // receive rs232 OK_flag
bit alrm_flag;
bit Gok_flag;
sbit AL40=P3^1;//alarm 40/50Km selection
sbit BZ=P3^7;// buzzer output
sbit RS = P2^4; // LCM 2402 pin i/o
sbit RW = P2^5;
sbit EN = P2^6;
#define DataPort P0
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
unsigned char DisplayWord[24];
unsigned char DisplayWord1[24];
unsigned char CLCK[6];
unsigned char count;
//--------------------------------
unsigned char GPS_AV;//GPS 信號 A強 V弱
unsigned char CLCK[6];//GPS hr min sec store
unsigned char DATE[6];// yy mm dd
unsigned char LATI[9];//latitude
unsigned char LONGI[10];//longitude
unsigned char SPED[6];//速度 000.00
unsigned char RSPED[4];//實際速度 00.xx 節---20131106
unsigned char ALRMSPEED;//實際數度---節
unsigned char Gok;// "$GPRMC," 確認完成
unsigned char REV_DATA;//儲存RS232緩衝區的暫存變數
//unsigned char disp_tcount;//切換時間計數器
//----------------------------------------------
void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);
bit LCD_Check_Busy(void) ;//忙線檢查
void LCD_Write_Com(unsigned char com) ;//lcm寫命令
void LCD_Write_Data(unsigned char Data) ;//lcm寫資料
void LCD_Clear(void) ;//清除 lcm
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ;//寫字串
void LCD_Init(void) ;//lcm 參數重設
void Display(void);//顯示lcm資料
void Init_Timer0(void);//定时器初始化
void Timer0_isr(void);// interrupt 1 ;
void UART_Init(void);
void UART_SER (void);// interrupt 4 //來自串口時鐘 1602 程式;
unsigned char NUMSPED(void);//小數點檢查
void TRNUM(void);//轉換顯示位置
void CLCKFL(unsigned char CLCKCT);//填入6個時 分 秒資料
void LATIFL(unsigned char LATICT);//LATICT: Latitude count
void LONGIFL(unsigned char LONGICT);//LONGICT: Longitude count
void SPEDFL(unsigned char SPEDCT);//SPEDCT: speed count
void DATEFL(unsigned char DATECT);//填入6個時 分 秒資料
void JPDM(unsigned char DM);
unsigned char Get_Gps(void);//改寫 gps 讀取程式 把 Gok=GPRMC_K() 取消
//------------------------------------------------
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
//---------------------------------
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
//nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
while(LCD_Check_Busy()); //忙则等待
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
//_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
while(LCD_Check_Busy()); //忙则等待
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();//---------------2014 add
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
/*
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
*/
// write string line 1
void LCD_Write_String0(unsigned char x,unsigned char *s)
{
LCD_Write_Com(0x80 + x); //表示第一行
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
//write string line 2
void LCD_Write_String1(unsigned char x,unsigned char *s)
{
LCD_Write_Com(0xC0 + x); //表示第二行
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
/*
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
*/
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
//--------------------------------------------------------------------------------------------
void Display_WFL(void)
{
//$GPRMC,115900.000,A,3723.2475,N,12158.3416,E,00.38,123.56,010414,,
DisplayWord[0]='2';
DisplayWord[1]='0';//
DisplayWord[2]=DATE[4];// mm dd yy
DisplayWord[3]=DATE[5];// mm dd
DisplayWord[4]='/';
DisplayWord[5]=DATE[0];// mm dd
DisplayWord[6]=DATE[1];// mm dd
DisplayWord[7]= '/';
DisplayWord[8]=DATE[2];// mm dd
DisplayWord[9]= DATE[3];// mm dd
DisplayWord[10]=' ';
DisplayWord[11]=CLCK[0]+'0';//GPS hr min sec store
DisplayWord[12]=CLCK[1]+'0';//GPS hr min sec store
DisplayWord[13]=':';
DisplayWord[14]=CLCK[2]+'0';//GPS hr min sec store
DisplayWord[15]=CLCK[3]+'0';//GPS hr min sec store
DisplayWord[16]=':';
DisplayWord[17]=CLCK[4]+'0';//GPS hr min sec store
DisplayWord[18]=CLCK[5]+'0';//GPS hr min sec store
DisplayWord[19]=' ';
DisplayWord[20]=' ';//RSPED[0];
DisplayWord[21]=(Gok/100)+'0';//RSPED[1];
DisplayWord[22]=(Gok%100)/10+'0';//'.';
DisplayWord[23]=(Gok%10)+'0';//RSPED[2];
DelayMs(20);
LCD_Write_String1(0,DisplayWord);//显示第一行 time & date
}
void Display(void)
{
DisplayWord1[0]='N';
DisplayWord1[1]=':';
DisplayWord1[2]='0';//LATI[0];
DisplayWord1[3]='0';//LATI[1];
DisplayWord1[4]='0';//LATI[2];
DisplayWord1[5]='0';//LATI[3];
DisplayWord1[6]='0';// LATI[4];
DisplayWord1[7]='0';// LATI[5];
DisplayWord1[8]= '0';//LATI[6];
DisplayWord1[9]= '0';//LATI[7];
DisplayWord1[10]='0';//LATI[8];
DisplayWord1[11]=' ';
DisplayWord1[12]='E';
DisplayWord1[13]=':';
DisplayWord1[14]='0';//LONGI[0];
DisplayWord1[15]='0';//LONGI[1];
DisplayWord1[16]='0';//LONGI[2];
DisplayWord1[17]='0';//LONGI[3];
DisplayWord1[18]='0';//LONGI[4];
DisplayWord1[19]='0';//LONGI[5];
DisplayWord1[20]='0';//LONGI[6];
DisplayWord1[21]='0';//LONGI[7];
DisplayWord1[22]='0';//LONGI[8];
DisplayWord1[23]='0';//LONGI[9];
DelayMs(5);
LCD_Write_String0(0,DisplayWord1);//显示第一行 longitude
}
// ///////////////FROM GPS ///////////////////////////////////////////////////
//----- FROM GPS PROG -----
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
// static unsigned int count;
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
count++;//顯示用 20ms*30=600ms
if (count==30)
{
count=0;//
disp_flag=1;
// Gok++;
}
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFA; // TH1: 重装值 4800 11.0592MHz
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void UART_SER (void) interrupt 4 //來自串口時鐘 1602 程式
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
REV_DATA =SBUF; //读入缓冲区的值
rec=1;
// rec_led=1;
}
if(TI) //如果是发送标志位,清零
TI=0;
}
//--20131110--------------------------------
//-------------檢查出小數點 以前的位數-------------2013 11106
unsigned char NUMSPED(void)
{
unsigned char yt=0;
while(SPED[yt]!='.')//內容不得為"," 一但是逗號就跳出
{
yt++;
}
return yt;
}
//------ 把顯示值變成計算值---- 2013 11106
void TRNUM(void)
{
unsigned char aa;
aa=NUMSPED();
switch(aa)
{
case 1:
RSPED[0]='0';
RSPED[1]=SPED[0];
RSPED[2]=SPED[2];
RSPED[3]=SPED[3];
ALRMSPEED=(RSPED[1]-'0');
break;
case 2:
RSPED[0]=SPED[0];
RSPED[1]=SPED[1];
RSPED[2]=SPED[3];
RSPED[3]=SPED[4];
ALRMSPEED=(RSPED[0]-'0')*10+(RSPED[1]-'0');
break;
}
}
void CLCKFL(unsigned char CLCKCT)//填入6個時 分 秒資料
{
unsigned char ct=0;
rec=0;//必要的
while(CLCKCT>ct)//儲存數量
{
while(rec==0);
if(rec==1)
{
CLCK[ct]=REV_DATA-0x30;
rec=0;
ct++;
}
}
}
void LATIFL(unsigned char LATICT)//LATICT: Latitude count
{
unsigned char yt=0;
rec=0;//必要的
while(LATICT >yt)//儲存數量
{
while(rec==0);
if(rec==1)
{
LATI[yt]=REV_DATA;
rec=0;
yt++;
}
}
}
void LONGIFL(unsigned char LONGICT)//LONGICT: Longitude count
{
unsigned char yt=0;
rec=0;//必要的
while(LONGICT >yt)//儲存數量
{
while(rec==0);
if(rec==1)
{
LONGI[yt]=REV_DATA;
rec=0;
yt++;
}
}
}
//填入6個速度資料
void SPEDFL(unsigned char SPEDCT)//SPEDCT: speed count
{
unsigned char yt=0;
rec=0;//必要的
while(SPEDCT >yt)//儲存數量
{
while(rec==0);
if(rec==1)
{
SPED[yt]=REV_DATA;
rec=0;
yt++;
}
}
}
void DATEFL(unsigned char DATECT)//SPEDCT: speed count
{
unsigned char yt=0;
rec=0;//必要的
while(DATECT >yt)//儲存數量
{
while(rec==0);
if(rec==1)
{
DATE[yt]=REV_DATA;
rec=0;
yt++;
}
}
}
//0819 跳過幾個逗號
void JPDM(unsigned char DM)
{
rec=0;
while(DM)//>dmt
{
while(rec==0);
{
if(REV_DATA == ',')
{
rec=0;
DM--;//dmt++
}
}
}
}
unsigned char Get_Gps(void)//改寫 gps 讀取程式 把 Gok=GPRMC_K() 取消
{
unsigned char TT;
if(rec==1)
{
if(REV_DATA == '$')
{
rec=0;
}
}
else
{
return 0;
}
while(rec==0);
if(REV_DATA == 'G')
{
rec=0;
}
while(rec==0);
if(REV_DATA == 'P')
{
rec=0;
}
while(rec==0);
if(REV_DATA == 'R')//一路比較下去全部要相同 "GPVTG,"
{
rec=0;
}
else
{
return 0;
}
while(rec==0);
if(REV_DATA == 'M')//一路比較下去全部要相同 "GPRMC,"
{
rec=0;
}
while(rec==0);
if(REV_DATA == 'C')//一路比較下去全部要相同 "GPRMC,"
{
rec=0;
}
while(rec==0);
if(REV_DATA == ',')//一路比較下去全部要相同 "GPRMC,"
{
rec=0;
}
else
{
return 0;
}
CLCKFL(6);//取 時分秒
JPDM(1);
while(rec==0);
{
GPS_AV = REV_DATA;
}
JPDM(1);
LATIFL(9);//get latitude data
JPDM(2);
LONGIFL(10);//get longitude data
JPDM(2);
SPEDFL(6);//取 速度000.00km
//***********************************************
JPDM(1);
DATEFL(6);
TT=CLCK[0]*10+CLCK[1]+8;//時間補差格林威治對中原標準
if(TT>23)
TT-=24;
CLCK[0]=TT/10;
CLCK[1]=TT%10;
TRNUM();
//--------------
Gok++;
Gok_flag=1;
//----------------
return 1;
//$GPRMC,115900.000,A,3723.2475,N,12158.3416,E,00.38,123.56,010414,,
}
/*
void GokTR(void)
{
}
*/
//$GPRMC,115900.000,A,3723.2475,N,12158.3416,E,00.38,123.56,010414,,
// --------- GPS MAIN PROGRAM -------------
/*
起始設定 中斷定時器 UART LCM (串聯式LCM 的 74595)
迴圈 取 GPS 得到 時間 經緯度 方向 高度 速度 等資料
送到顯示區處理
比較速度資料 進行判斷警報
*/
void main(void)
{
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
Init_Timer0(); //定时器0初始化
UART_Init();
Gok=0;
while(1)
{
Get_Gps();
//Gok_flag=1;//----------------------------test
/*
if(Gok==1)
{
if(dispt_flag && alrm_flag )
{
Display_tData_Operation ();
}
else
{
Display_Data_Operation ();//轉換相關值到顯示
}
}
if(ALRMSPEED>26 && ALRMSPEED<30)//時速在 50~60之間警報
{
alrm_flag=0;//-
BZ=0;
}
else
{
alrm_flag=1;//*
BZ=1;
}
if(AL40==0)
{
if(ALRMSPEED>21 && ALRMSPEED<30)//時速在 40~60之間警報
{
alrm_flag=0;//-
BZ=0;
}
else
{
alrm_flag=1;//*
BZ=1;
}
}
*/
if(disp_flag && Gok_flag)//==1)
{
/*
if(dispt_flag)
{
Display();
}
else
{
Display2();
}
*/
DelayMs(5);
Display();// longitude MOVE FROM MAIN
// DelayMs(5);
// LCD_Write_String0(0,DisplayWord1);//显示第一行 longitude
DelayMs(20);
Display_WFL();// time & date
// DelayMs(20);
//LCD_Write_String1(0,DisplayWord);//显示第一行 time & date
disp_flag=0;
Gok_flag=0;
}
}
}
//$GPRMC,115900.000,A,,N,,E,00.38,, test pattern
//problem is get character from word-matrix
|
|