|
樓主 |
發表於 2012-8-19 23:03:13
|
顯示全部樓層
更新 latch 版本 可以顯示 時 分 秒 在50~59秒時顯示 月 日 年,有興趣的請笑納!!
//20120808 modify OK while(rec==0); 等待直到1才跳離 實驗板電路 ,7段顯示用
#include<reg52.h>
#define DataPort P0 // display LED segment
#define DrivePort P1 //display LED digit
//unsigned char code GPS_ASC[]="GPRMC,";
unsigned char CLCK[6];//時分秒存放={1,2,3,4,5,6}
unsigned char YMD[6]={1,2,0,8,1,9};//年月日存放
unsigned char Gok;// "$GPRMC," 確認完成
sbit Gok_LED =P1^2;// 收到"$GPRMC,"送出LED
sbit rec_led =P1^3;
bit rec; // receive rs232 OK_flag
unsigned char REV_DATA;//儲存RS232緩衝區的暫存變數
void Init_Timer0(void);//定时器初始化
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;// 位锁存
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]; //存储显示值的全局变量
void CLCKFL(unsigned char CLCKCT);//簡化時分秒的儲存程式
void JPDM(unsigned char DM);//跳過幾個',"號
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;
DataPort=0; //清空数据,防止有交替重影
LATCH1=1; //段锁存
LATCH1=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码
LATCH1=1; //段锁存
LATCH1=0;
i++;
if(i==Num)
i=0;
}
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-2010)/256;//0xd8; //重新赋值 2ms
TL0=(65536-2010)%256; //0xf0;
Display(0,6);
}
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;
}
void CLCKFL(unsigned char CLCKCT)
{
unsigned char ct=0;
rec=0;//必要的
while(CLCKCT>ct)//儲存數量
{
while(rec==0);
if(rec==1)
{
CLCK[ct]=REV_DATA-0x30;
rec=0;
ct++;
}
}
}
//0819 填入6個年月日資料
void YMDFL(unsigned char YMDCT)
{
unsigned char yt=0;
rec=0;//必要的
while(YMDCT>yt)//儲存數量
{
while(rec==0);
if(rec==1)
{
YMD[yt]=REV_DATA-0x30;
rec=0;
yt++;
}
}
}
//---------------------------
//0819 跳過幾個逗號
void JPDM(unsigned char DM)
{
// unsigned char dmt=0;
rec=0;
while(DM)//>dmt
{
while(rec==0);
if (rec==1)
{
if(REV_DATA == ',')
{
rec=0;
DM--;//dmt++
}
}
}
}
//-------------------
unsigned char GPRMC_K(void)//比較 $GPRMC
{
unsigned char TT;//轉換用
while(rec==0);
if(rec==1)
if(REV_DATA == 'G')//一路比較下去全部要相同 "GPRMC,"
rec=0;
else
return 0;
while(rec==0);
if(rec==1)
if(REV_DATA == 'P')
rec=0;
while(rec==0);
if(rec==1)
if(REV_DATA == 'R')//一路比較下去全部要相同 "GPRMC,"
rec=0;
else
return 0;
while(rec==0);
if(rec==1)
if(REV_DATA == 'M')//一路比較下去全部要相同 "GPRMC,"
rec=0;
while(rec==0);
if(rec==1)
if(REV_DATA == 'C')//一路比較下去全部要相同 "GPRMC,"
rec=0;
while(rec==0);
if(rec==1)
if(REV_DATA == ',')//一路比較下去全部要相同 "GPRMC,"
rec=0;
else
return 0;
CLCKFL(6);//取 時分秒
JPDM(8);//跳過8個逗號
YMDFL(6);//取 年月日
TT=CLCK[0]*10+CLCK[1]+8;
if(TT>23)
TT-=24;
CLCK[0]=TT/10;
CLCK[1]=TT%10;
return 1;
}
void Get_Gps(void)
{
if(rec==1)
{
rec=0;//清除授信旗標
if(REV_DATA == '$')
{
Gok=GPRMC_K();//確認收到 "GPRMC," 字元
}
}
}
void Dis_tr(void)//轉換相關值到顯示
{
unsigned j;
for(j=0;j<6;j++)
{
if(CLCK[4]==5)//50~59秒顯示年 月 日
TempData[j]=dofly_DuanMa[YMD[j]];//CLCK
else
TempData[j]=dofly_DuanMa[CLCK[j]];//
}
}
void main(void)
{
Init_Timer0();
UART_Init();
while(1)
{
Get_Gps();
if(Gok==1)
{
Dis_tr();//轉換相關值到顯示
}
}
}
|
|