51微控制器解析衛星定位資料來源碼+DHT11,1602顯示
什麼都不多說,直接看程式碼:
#include <REG52.H>
#include <stdio.h>
#include <intrins.h>
////////////========================================================================================
/*
1602A(16*2)模擬口線接線方式
連線線圖:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
--------------------------------------------------|
|DB0-----P0.0 | DB4-----P0.4 | RW-------P1.5 |
|DB1-----P0.1 | DB5-----P0.5 | RS-------P1.4 |
|DB2-----P0.2 | DB6-----P0.6 | E--------P1.6 |
|DB3-----P0.3 | DB7-----P0.7 | V0接10K電阻到GND |
---------------------------------------------------
溫溼度DHT11接線:模組data接 P3^2
******************/
sbit Data= P3^2; //定義資料線 溫溼度感測器DHT11資料接入
unsigned char rec_dat[9]; //用於顯示的接收資料陣列
unsigned char flag_rec=0;
unsigned char num_rec=0;
unsigned char code kaijihuamian[]="BeiDou_DHT11"; //開機顯示
unsigned char code kaijihuamian2[]="AnShan_17-12-01";
unsigned char code receiving[]="Receiving!";
unsigned char code nodata[]="No BD data!";
unsigned char code LCD_161[]="BD_HeGuang Studios";
unsigned char code LCD_162[]="TEL:15117255049";
char code TIME_AREA= 8; //時區
unsigned char flag_data; //資料標誌位
//BD資料儲存陣列
unsigned char JD[10]; //經度
unsigned char JD_a; //經度方向
unsigned char WD[9]; //緯度
unsigned char WD_a; //緯度方向
unsigned char date[6]; //日期
unsigned char time[6]; //時間
unsigned char time1[6]; //時間
unsigned char speed[5]={'0','0','0','0','0'}; //速度
unsigned char high[6]; //高度
unsigned char angle[5]; //方位角
unsigned char use_sat[2]; //使用的衛星數
unsigned char total_sat[2]; //天空中總衛星數
unsigned char lock; //定位狀態
//串列埠中斷需要的變數
unsigned char seg_count; //逗號計數器
unsigned char dot_count; //小數點計數器
unsigned char byte_count; //位數計數器
unsigned char cmd_number; //命令型別
unsigned char mode; //0:結束模式,1:命令模式,2:資料模式
unsigned char buf_full; //1:整句接收完成,相應資料有效。0:快取資料無效。
unsigned char cmd[5]; //命令型別儲存陣列
sbit rs = P1^4;
sbit rw = P1^5;
sbit ep = P1^6;
//-----------------------------------------------------------------------------------------------
//延時子程式
void delayms(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
bit lcd_bz(void)
{ // 測試LCD忙碌狀態
bit result;
rs = 0;
rw = 1;
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);
ep = 0;
return result;
}
void lcd_wcmd(unsigned char cmd)
{ // 寫入指令資料到LCD
while(lcd_bz());
rs = 0;
rw = 0;
ep = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_pos(unsigned char pos)
{ //設定顯示位置
lcd_wcmd(pos | 0x80);
}
void lcd_pos_2(unsigned char pos)
{ //設定顯示位置
lcd_wcmd(pos | 0xC0);
}
void lcd_wdat(unsigned char dat)
{ //寫入字元顯示資料到LCD
while(lcd_bz());
rs = 1;
rw = 0;
ep = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_string(unsigned char *ptr,unsigned char pos)
{
unsigned char i;
lcd_pos(pos);
while(*(ptr+i) != '\0')
{ // 顯示字元"welcome!"
lcd_wdat(*(ptr+i));
i++;
}
}
lcd_init()
{ //LCD初始化設定
lcd_wcmd(0x38); //
delayms(1);
lcd_wcmd(0x0c); //
delayms(1);
lcd_wcmd(0x06); //
delayms(1);
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(1);
}
//-----------------------------------------------------------------------------------------------
//延時子程式
void delaym(unsigned int ms)
{
unsigned int i,j;
for(i = 0;i < ms ;i++)
{
for(j = 0;j < 125 ;j++)
;
}
}
void DHT11_delay_us(unsigned char n)
{
while(--n);
}
void DHT11_delay_ms(unsigned int z)
{
unsigned int i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void DHT11_start()
{
Data=1;
DHT11_delay_us(2);
Data=0;
DHT11_delay_ms(20); //延時18ms以上
Data=1;
DHT11_delay_us(30);
}
//----------------------- 溫溼度讀取 -----------------------------------
unsigned char DHT11_rec_byte() //接收一個位元組
{
unsigned char i,dat=0;
for(i=0;i<8;i++) //從高到低依次接收8位資料
{
while(!Data); ////等待50us低電平過去
DHT11_delay_us(8); //延時60us,如果還為高則資料為1,否則為0
dat<<=1; //移位使正確接收8位資料,資料為0時直接移位
if(Data==1) //資料為1時,使dat加1來接收資料1
dat+=1;
while(Data); //等待資料線拉低
}
return dat;
}
void DHT11_receive() //接收40位的資料
{
unsigned char R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
DHT11_start();
if(Data==0)
{
while(Data==0); //等待拉高
DHT11_delay_us(40); //拉高後延時80us
R_H=DHT11_rec_byte(); //接收溼度高八位
R_L=DHT11_rec_byte(); //接收溼度低八位
T_H=DHT11_rec_byte(); //接收溫度高八位
T_L=DHT11_rec_byte(); //接收溫度低八位
revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //結束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*資料處理,方便顯示*/
rec_dat[0]='0'+(RH/10);
rec_dat[1]='0'+(RH%10);
rec_dat[2]='R';
rec_dat[3]='H';
rec_dat[4]=' ';
rec_dat[5]=' ';
rec_dat[6]='0'+(TH/10);
rec_dat[7]='0'+(TH%10);
rec_dat[8]='C';
}
}
//------------------------- <初始化設定 結束> -------------------------------------
void DHT11_main(unsigned int zxi){
lcd_init(); //初始化1602
lcd_wcmd(0x01); //清除LCD的顯示內容
delaym(1);
//============溫溼度讀取============================================================
DHT11_delay_ms(1500); //DHT11上電後要等待1S以越過不穩定狀態在此期間不能傳送任何指令
DHT11_receive();
lcd_pos(3); // 設定顯示位置
for(zxi = 0;zxi<6;zxi++)
{
lcd_wdat(kaijihuamian[zxi+6]); // 顯示字元dht11
}
zxi = 0;
delayms(100);
lcd_pos_2(2);
while(rec_dat[zxi] != '\0'){
lcd_wdat(rec_dat[zxi]); //顯示
zxi++;
}
delaym(1000);
}
//==================================================================================
//傳送位元組
void sendbyte(unsigned char ptr)
{
SBUF=ptr;
while(TI==0);
TI=0;
}
//---------------------------------------------------------------------------
//傳送資料流
void sendstring(unsigned char *ptr,unsigned char len)
{
int i=0;
while(i<len)
{
SBUF=*(ptr+i); //SUBF接受/傳送緩衝器
while(TI==0);
TI=0;
i++;
}
num_rec=0;
}
void init_all(void) //9600 11.05926
{
SCON = 0x50; //REN=1允許序列接受狀態,串列埠工作模式1
TMOD|= 0x20; //定時器工作方式2
PCON|= 0x80;
TH1 = 0xFa; //baud*2 /* reload value 9600、資料位8、停止位1。效驗位無 (11.0592)
TL1 = 0xF3;
TR1 = 1;
ES = 1; //開串列埠中斷
EA = 1; // 開總中斷
lcd_init() ;
}
//將UTC時間轉成BJ時間
void trans_time(void)
{
unsigned char temp,hour_shi,hour_ge;
temp=(time[0]-'0')*10+(time[1]-'0');
if(temp<=16)
{
temp=temp+8;
hour_shi=temp/10;
hour_ge=temp%10;
time[0]=hour_shi+'0';
time[1]=hour_ge+'0';
}
else
{
temp=temp+8-24;
time[0]='0';
time[1]=temp%10+'0';
}
}
//判斷是否有BD資料 有1,無0
bit BD_data(void)
{
if(buf_full&0x01!=0)
return 1;
else
return 0;
}
//----------------------------------------------------------------------------
void main ()
{
unsigned int X;
unsigned char i;
init_all();
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(10);
i = 0;
X = 0;
lcd_pos(1); // 設定顯示位置
while(kaijihuamian[i] != '\0')
{
lcd_wdat(kaijihuamian[i]); // 顯示字元時間
i++;
}
delayms(10);
i=0 ;
lcd_pos_2(0); // 設定顯示位置
while(kaijihuamian2[i] != '\0')
{
lcd_wdat(kaijihuamian2[i]); // 顯示字元時間
i++;
}
i = 0;
delayms(5000);
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(10);
while(1)
{
if(flag_data==0)// 如果沒有資料
{
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(10);
i=0 ;
lcd_pos(2); // 設定顯示位置
while(nodata[i] != '\0')
{
lcd_wdat(nodata[i]); // 顯示字元
i++;
}
delayms(1000);
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(10);
//第三頁開始==================================================================
DHT11_main(i);// 顯示字元DHT11 溫度 溼度 資訊
delaym(3000);
i = 0;
lcd_wcmd(0x01);
delaym(1);
//第四頁開始==================================================================
lcd_pos(0); // 設定顯示位置
while(LCD_161[i] != '\0'){
lcd_wdat(LCD_161[i]); // 顯示字元禾灮資訊
i++;
}
delayms(1);
i=0 ;
lcd_pos_2(0); // 設定顯示位置
while(LCD_162[i] != '\0'){
lcd_wdat(LCD_162[i]); // 顯示字元禾灮資訊
i++;
}
//結束==================================================================
delayms(5000);
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(1);
}
if(flag_rec==1) //data 解碼完畢
{
flag_rec=0; //清資料有效標誌位
if (lock==1) //如果已經定位
{
for(X;X <10;X++){
trans_time();//UTC--BJ TIME轉換為北京時間
lcd_pos_2(0); // 設定顯示位置
lcd_wdat(' '); //顯示 北京時間
lcd_wdat(time[5]);
}
delayms(1); //第一頁顯示完畢======經緯度+北京時間====定位+授時
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(1);
X = 0;
for(X;X <10;X++){
//第二頁開始=================================================================================
lcd_pos(0); // 設定顯示位置
lcd_wdat('H'); // 顯示海拔 衛星個數
delayms(100);
lcd_pos(1);
while(high[i] != '\0'){
lcd_wdat(high[i]); //顯示海拔
i++;
}
delayms(100);
while(use_sat[i] != '\0'){
lcd_wdat(use_sat[i]); // // 顯示 衛星個數
i++;
}
delayms(100);
i=0 ;
//delayms(5000); //第二頁顯示完畢======顯示海拔+衛星個數===速度+方位
//lcd_wcmd(0x01); //清除LCD的內容
while(angle[i] != '\0'){
lcd_wdat(angle[i]); // // 顯示 方位角
i++;
}
i=0 ;
}
delayms(10); //第二頁顯示完畢======顯示海拔+衛星個數===速度+方位
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(1);
X = 0;
//第三頁開始==================================================================
DHT11_main(i);// 顯示字元DHT11 溫度 溼度 資訊
delaym(3000);
i = 0;
lcd_wcmd(0x01);
delaym(1);
//第四頁開始==================================================================
lcd_pos(0); // 設定顯示位置
while(LCD_161[i] != '\0'){
lcd_wdat(LCD_161[i]); // 顯示字元禾灮資訊
i++;
}
delayms(1);
i=0 ;
lcd_pos_2(0); // 設定顯示位置
while(LCD_162[i] != '\0'){
lcd_wdat(LCD_162[i]); // 顯示字元禾灮資訊
i++;
}
//結束==================================================================
delayms(5000);
delayms(1); //顯示完畢======顯示禾灮資訊
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(1);
}
else if(lock==0)
{ //未定位 //display relative message
lcd_wcmd(0x01); //清除LCD的顯示內容
delayms(10);
i=0 ;
lcd_pos(3); // 設定顯示位置
while(receiving[i] != '\0')
{
lcd_wdat(receiving[i]); // 顯示字元時間
i++;
}
delaym(1000);
lcd_wcmd(0x01); //清除LCD的顯示內容
delaym(10);
X = 0;
//第三頁開始==================================================================
DHT11_main(i);// 顯示字元DHT11 溫度 溼度 資訊
delaym(3000);
i = 0;
lcd_wcmd(0x01);
delaym(1);
//第四頁開始==================================================================
lcd_pos(0); // 設定顯示位置
while(LCD_161[i] != '\0'){
lcd_wdat(LCD_161[i]); // 顯示字元禾灮資訊
i++;
}
delayms(1);
i=0 ;
lcd_pos_2(0); // 設定顯示位置
while(LCD_162[i] != '\0'){
lcd_wdat(LCD_162[i]); // 顯示字元禾灮資訊
i++;
}
//結束==================================================================
delayms(5000);
delayms(1);
}
}
}
}
//--------------------------------------------------------------------
//串列埠中斷程式
void ser_int (void) interrupt 4 using 1
{
unsigned char tmp;
if(RI)
{
RI=0;
tmp=SBUF;
switch(tmp)
{
case '$':
cmd_number=0; //命令型別清空
mode=1; //接收命令模式
byte_count=0; //接收位數清空
flag_data=1;
flag_rec=1; //資料標誌位置一
break;
case ',':
seg_count++; //逗號計數加1
byte_count=0;
break;
case '*':
switch(cmd_number)
{
case 1:
buf_full|=0x01;
break;
case 2:
buf_full|=0x02;
break;
case 3:
buf_full|=0x04;
break;
}
mode=0;
break;
default:
if(mode==1) //命令種類判斷
{
cmd[byte_count]=tmp; //接收字元放入型別快取
if(byte_count>=4)
{ //如果型別資料接收完畢,判斷型別
if(cmd[0]=='G')
{
if(cmd[1]=='N')
{
if(cmd[2]=='G')
{
if(cmd[3]=='G')
{
if(cmd[4]=='A')
{
cmd_number=1; //data type
mode=2;
seg_count=0;
byte_count=0;
}
}
else if(cmd[3]=='S')
{
if(cmd[4]=='V')
{
cmd_number=2;
mode=2;
seg_count=0;
byte_count=0;
}
}
}
switch (cmd_number)
{
case 1: //型別1資料接收。GNGGA————北斗與GPS組合資料
switch(seg_count)
{
case 2: //緯度處理
if(byte_count<9)
{
WD[byte_count]=tmp;
}
break;
case 3: //緯度方向處理
if(byte_count<1)
{
WD_a=tmp;
}
break;
case 4: //經度處理
if(byte_count<10)
{
JD[byte_count]=tmp;
}
break;
case 5: //經度方向處理
if(byte_count<1)
{
JD_a=tmp;
}
break;
case 6: //定位判斷
if(byte_count<1)
{
lock=tmp;
}
break;
case 7: //定位使用的衛星數
if(byte_count<2)
{
use_sat[byte_count]=tmp;
}
break;
case 9: //高度處理
if(byte_count<6)
{
high[byte_count]=tmp;
}
break;
}
break;
}
byte_count++; //接收數位加1
break;
}
}
}
相關測試結果:
測試視訊地址:點選進入
感謝一直關注著禾灮成長進步的朋友們。你們的信任、支援和鼓勵,鞭策著我們一路走到了今天。
感謝所有的合作伙伴,我們相互促進,共同見證了彼此的成長。
感謝所有曾經在禾灮彼此倚靠、相互鼓勵、攜手同心、砥礪同行的兄弟姐妹。這裡承載了我們的青春與熱血。
禾灮,感謝有你。
未來,我們將一如既往,砥礪前行。
禾灮·小楊
2018.08.10
相關文章
- 51微控制器實現數碼管顯示
- 51微控制器定時器數碼管顯示定時器
- 51微控制器開發系列三_數碼管動態掃描顯示
- myBatis原始碼解析-資料來源篇(3)MyBatis原始碼
- LBS基站定位和GPS衛星定位對比
- 51微控制器lcd程式碼
- 51微控制器學習資料書籍分享
- hadoop(7)–下載資料來源碼解析(上)Hadoop
- vtk單視窗顯示多個源資料程式碼
- 我想用jsp顯示資料表表頭的值?可是顯示出來是亂碼!JS
- 從資料在頁面顯示不解析
- CSS #定位 #顯示方式CSS
- 關於衛星定位,你想知道的一切
- 研究顯示51%網際網路流量來自非人為操作
- 顯示來自多個表的資料——JOIN
- 世界衛生組織:資料顯示害怕變老的人可能更短命
- 51微控制器—矩陣鍵盤-程式碼矩陣
- Windows 7工作列無法顯示電源圖示解析Windows
- 數碼管顯示動態資料
- 51微控制器 16X16點陣迴圈滾動顯示漢字(基於proteus)
- 51微控制器學習歷程(二)快速入門51微控制器
- 【定位不準的煩心事系列】第1篇:談談衛星定位的位置干擾
- Oracle OCP(07):顯示來自多個表的資料Oracle
- WebpageFX:資料顯示美國富裕區用iPhone收入低用三星WebiPhone
- 51微控制器流水燈電路以及C程式碼C程式
- 51微控制器mcp4728驅動程式原始碼原始碼
- 介紹專門顯示資料表格開源taglib
- 51微控制器彙編教程
- 快速入門51微控制器
- 初學51微控制器--網上教程(51自學網)
- Mac OS X怎麼系統顯示資源庫資料夾Mac
- 如何在終端輸入密碼時顯示星號密碼
- element table不顯示任何資料,無資料倒是顯示出無資料的了
- java實現將資料庫資料轉化成excel表格顯示出來Java資料庫Excel
- (畢業設計資料)基於微控制器51微控制器智慧藥盒控制系統設計
- 自然資源部:2019年衛星遙感應用報告
- 記錄一次獲取czml衛星軌道資料
- 51微控制器序列通訊原理