|
樓主 |
發表於 2012-9-9 13:50:25
|
顯示全部樓層
晴兒:
這技巧我不太懂ㄟ!! 我把原程式 PO出來好了!! CLCK[7] 是 時 分 秒 的儲存區!! 這算是BUFFER ?
/* 20120731 變數名稱 dc 不可以,會亂跑,原因不明 改成 dca dcb 就可以11 0801 改成顯示 23時 59分 調整計時 20120816開始改寫給gps使用 要增加GPS 讀取部分+GPS port 平常顯示 "TIME by GPS 之後顯示*/
/* 20120731 變數名稱 dc 不可以,會亂跑,原因不明 改成 dca dcb 就可以11 0801 改成顯示 23時 59分 調整計時 */
/* 20120824 一直搞不出來 先放一邊 最大問題 LED 無法從第一排顯示出來
20120906 scan ok 原因是595 scan 先前抄人家的不完全了解問題,本來是共陽極現在 5*8是共陰極所以輸出相反 於是用 j=0 把第一個值為零 送出給ser_b 之後j=1~23 都不是0 所以 ser都會是1 這樣就不會有問題了 */
#include<reg52.h>
#include <intrins.h> //use nop
//#include <delay.h>
sbit LATCH = P2^4; //byte 1 green Byte 2 RED
sbit SRCLK= P2^5;
sbit SER = P2^3;// Lo active pull down LED cathode to ground
sbit LATCH_B = P2^1;//P2^1;LED commond Lo active
sbit SRCLK_B= P2^2;//P2^2;
sbit SER_B= P2^0;// P2^0; LED commond Lo active to supply 5V to LED
sbit Gok_LED = P1^0;
//sbit ch_color=P1^2;
unsigned char cd,color,ms2,ms3;
unsigned char dca,dcb,dcc;
unsigned int ms4;
unsigned char disp[24];
unsigned char dispbf[4];
bit ch_flag;//need flash count display
void DelayMs(unsigned char t);
void DelayUs2x(unsigned char t);
//-------GPS相關資料區---------
unsigned char REV_DATA,Gok,GPS_ST;//GPS_ST 存放 a v 狀態
bit rec;
unsigned char CLCK[7];//GPS 時1,2 分3,4 秒5,6 & A V 值7
unsigned char YMD[6];//年月日存放
//-------GPS相關資料區---------
/* 使用相對的位置來顯示出相對的自來 14:00
需要 相對的顯示如 WD[1] WD[2] WD[3] WD[4] 6*8
DISWD(x,y) x:位置 y:內容*/
// unsigned char DISPWD[4,6]//四個字每個字6BYTE
unsigned char code DP[10][5]={
{0x7e,0x81,0x81,0x81,0x7e},//0
{0x80,0x82,0xff,0x80,0x80},//1
{0xc2,0xa1,0x91,0x89,0x86},//2
{0x62,0x81,0x89,0x89,0x76},//3
{0x38,0x24,0x22,0xff,0x20},//4
{0x86,0x89,0x89,0x89,0x71},//5
{0x7e,0x89,0x89,0x89,0x70},//6
{0x01,0xf1,0x09,0x05,0x03},//7
{0x76,0x89,0x89,0x89,0x76},//8
{0x0e,0x91,0x91,0x91,0x7e}};//9
unsigned char code font6x11[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, //SP
0x00, 0x00, 0x00, 0x00, 0x00, //SP
0x00,0x1c,0x22,0x41,0x49,0x79,0x00,//G
0x00,0x7f,0x11,0x11,0x11,0x0e,0x00,//P
0x00,0x26,0x49,0X49,0x49,0x4a,0x30,//S
0x00, 0x00, //SP
0x00,0x1c,0x22,0x41,0x41,0x22,0x00,//C
0x7f,0x40,0x40,0x40,0x40,0x00,//L
0x00,0x3e,0x41,0x41,0x41,0x3e,//O
0x00,0x1c,0x22,0x41,0x41,0x22,0x00,//C
0x7f,0x08,0x14,0x22,0x41,0x00,//K
0x00, 0x00, //SP
0x00,0x1c,0x22,0x41,0x49,0x79,0x00,//G
0x00,0x7f,0x11,0x11,0x11,0x0e,0x00,//P
0x00,0x26,0x49,0X49,0x49,0x4a,0x30,//S
0x00, 0x00, //SP
};
void Display (void);
void Get_Gps(void);
/*------------------------------------------------
timer initial
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //mode 1,16bit timer
EA=1; //interrupt enable
ET0=1; //et0
TR0=1; //tr0
}
/*------------------------------------------------
service sub
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-4010)/256; //reset 4ms
TL0=(65536-4010)%256;
ms2++;// 2ms setflag
ms4++;
// Display();
if(ms2>7)//2*74*5=1000ms
{
ms2=0;
ms3++;
if(ch_flag==1)
Display();
}
if(ms3>44)
{
ms3=0;
dca++;//dc=1sec count
}
if(dca>59)//內部自己計數 時 分秒
{
dcb++;
dca=0;
}
/*
if(dcb>59)
{
dcb=0;
dcc++;
}
if(dcc>23)
{
dcc=0;
}
*/
}
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
*/
void SendByte(unsigned char dat,bit direction)
{
unsigned char i,temp;
if(direction==0)
temp=0x80;//要比較第7bit
else
temp=0x01;//要比較第0bit
for(i=0;i<8;i++)
{
SRCLK=0;
SER=dat&temp;//不是0就是1
if(direction==0)
dat<<=1;
else
dat>>=1;
SRCLK=1;
}
}
void Out595(void)
{
LATCH=0;
_nop_();
LATCH=1;
}
void cd_pr (void)
{
dispbf[0]=CLCK[2];//dcb/10;//10 min
dispbf[1]=CLCK[3];//dcb%10;//1 min
dispbf[2]=CLCK[4];//dca/10;//10 sec
dispbf[3]=CLCK[5];//1 sec
}
void Dis_tr(void)
//程式 把資料送到 DISPWD[4,5]裡面資料顯示出來
{
unsigned char dp,d6p;
for(dp=0;dp<4;dp++)
{
for(d6p=0;d6p<5;d6p++)
{
disp[d6p+dp*5]=DP[dispbf[dp]][d6p];// DP內部放著0~9的字库 對應1~4位數的dp,以及每一位數的5個byte的點陣 DP[dispbf[dp],d6p];
}
}
}
void Display (void)
{
unsigned char l,j;
// for(l=0;l<25;l++)//顯示5次
{
for(j=0;j<24;j++) // 字型會反轉 (正 24>>0)
{
SRCLK_B=0;//----- sendseg start
SER_B=j;
SRCLK_B=1;
LATCH_B=0; //
_nop_();
LATCH_B=1;
SendByte(disp[j],0);//"~" 明暗反轉 紅色
Out595();
DelayUs2x(150);
SendByte(0x00,0);// 0 字正 1 字顛倒
Out595();
}
}//for l
}
void normal_disp(void)
{
unsigned char i,l;
unsigned int k;
for(k=0;k<65;k++) //流動方向 由左到右 88>>0
{
for(l=0;l<5;l++)
{
for(i=0;i<24;i++) // 字型會反轉 (正 24>>0)
{
SRCLK_B=0;//----- sendseg start
SER_B=i;
SRCLK_B=1;
LATCH_B=0; //
_nop_();
LATCH_B=1;
SendByte(font6x11[i+k+8],0);//"~" 明暗反轉紅色
Out595();
DelayUs2x(250);
SendByte(0x00,0);// 0 字正 1 字顛倒
Out595();
}//for i
}//for l
}//for k
}
/*------------------------------------------------
串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
// TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
// TH1 = 0xfa; // TH1: 重装值 GPS 4800 波特率 晶振 11.0592MHz
T2CON = 0x34; // timer2 parameter set
RCAP2H = 0xff; //set uart baud rate 38400
RCAP2L = 0xf7;
ET2 = 1;// enable timer2 overflow flag
TR2 = 1;// timer2 enable
// TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void UART_SER (void) interrupt 4 //來自GPS 程式
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
REV_DATA =SBUF; //读入缓冲区的值
rec=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(1);
while(rec==0);
if(rec==1)
{
CLCK[6]=REV_DATA;//取A(正常)或是 V(搜尋中)
}
JPDM(7);//跳過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," 字元
}
}
}
main()
{
Init_Timer0();
UART_Init();
cd_pr();
Dis_tr();
while(1)
{
while(Gok==0)
{
Get_Gps();//取GPS信號
}
cd_pr();
Dis_tr();
Gok=0;
if(dca>30)
{
ch_flag=0;
normal_disp();
}
ch_flag=1;
}
}//main
|
|