找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1901|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

這個單片機(jī)程序中 感覺GPS的 GPGGA這條信息沒有被保存

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:408809 發(fā)表于 2020-1-2 10:39 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
我移植了論壇里一位師兄的 程序,但是存儲PAGGA信息的數(shù)組內(nèi)沒有數(shù)據(jù)。
  1. #include <reg52.h>
  2. #include "pcf8574lcd.h"


  3. unsigned char RX_Buffer[68];                //此數(shù)組用于直接儲存來自GPS的原始數(shù)據(jù),
  4. unsigned char RX_Count = 0;     //
  5.        bit Flag_GPS_OK = 0;
  6. extern bit Flag_GPS_OK;

  7. unsigned char xdata Display_GPGGA_Buffer[68]={0};                //用于儲存GPGGA的數(shù)據(jù)
  8. unsigned char xdata Display_GPRMC_Buffer[68]={0};                //用于儲存GPRMC的數(shù)據(jù)

  9. unsigned int k=0,qian_a=0,hou_a=0,qian_b=0,hou_b=0,qian_c=0,hou_c=0;        //存儲前后逗號的位置序號的變量



  10. bit qian_OK=0;                   //已找出前面的逗號的標(biāo)志變量
  11. bit First_Share_OK=0;  //已開始LCD顯示的標(biāo)志變量
  12. bit jiajian=1;                    //進(jìn)行加或減的標(biāo)志變量


  13. bit Flag_Calc_GPGGA_OK = 0;           //GPGGA完整有效的數(shù)據(jù)已收到的標(biāo)志變量
  14. bit Flag_Calc_GPRMC_OK = 0;           //GPRMC完整有效的數(shù)據(jù)已收到的標(biāo)志變量

  15. //*****************************************************************************

  16. void GPSUart_Init()                        //  GPS串口初始化                                             
  17. {
  18.         
  19.                                              //    針對的是 STC89C52的,但是發(fā)現(xiàn)STC12C5A60S2單片機(jī)也可以用 ,同樣都是11.0592的晶振。
  20.         SCON = 0X50;  //UART方式1;8位UART
  21.         REN  = 1;     //允許串行口接收數(shù)據(jù)
  22.         PCON = 0x00;  //SMOD=0;波特率不加倍   9600
  23.         TMOD = 0x20;  //T1方式2,用于產(chǎn)生波特率
  24.         TH1  = 0xFD;  //裝初值
  25.         TL1  = 0xFD;
  26.         TR1  = 1;     //啟動定時器1
  27.         EA   = 1;     //打開全局中斷控制
  28.         ES   = 1;     //打開串行口中斷               
  29. }

  30. //-----------------------------------------------------------------
  31. void RECEIVE_DATA(void) interrupt 4 using 3                  //串口中斷函數(shù),收到GPS的數(shù)據(jù)時進(jìn)入此中斷        
  32. {
  33.         unsigned char temp = 0;
  34.         ES=0;                                                                                    //先關(guān)閉串行口中斷
  35.         temp = SBUF;                                                                //接收SBUF中的數(shù)據(jù)
  36.         RI = 0;                                                                                  //接收完成的標(biāo)志位清零
  37.         
  38.         if(temp == '


  39. )                                                                //若是統(tǒng)一的數(shù)據(jù)頭,則作為數(shù)組第一個元素
  40.                 {
  41.                                 RX_Count = 0;
  42.                                 Flag_GPS_OK = 0;               
  43.                 }

  44.         RX_Buffer[RX_Count++] = temp;                                //收到的數(shù)據(jù)放到數(shù)組中

  45.         if(RX_Count >= 66)                                                        //序號大于66的數(shù)據(jù)無用,統(tǒng)一放到第66位覆蓋掉
  46.                 {
  47.                                 RX_Count = 66;
  48.                 }

  49.         if(temp == '*')                                                                //收到*,則完成一幀數(shù)據(jù)的接收,不管是否完整有效
  50.                 {
  51.                                  Flag_GPS_OK = 1;                         //標(biāo)志變量置為1
  52.                 }

  53.         ES=1;                                                                                 //重新打開串行口中斷
  54. }

  55. //----------------------------------------------------------------------------------


  56. /********************************************************/
  57. void Delay1s(uchar A)                //  1秒,主要用來做歡迎詞延時,STC12系列專用
  58. {
  59.         
  60.         while(A--)
  61.         {
  62.         unsigned char i, j, k;

  63.         i = 43;
  64.         j = 6;
  65.         k = 203;
  66.         do
  67.         {
  68.                 do
  69.                 {
  70.                         while (--k);
  71.                 } while (--j);
  72.         } while (--i);
  73.         
  74. }
  75. }

  76. /*******************************************************************************
  77. * 函 數(shù) 名         : datapros()
  78. * 函數(shù)功能                   : 溫度讀取處理轉(zhuǎn)換函數(shù)
  79. * 輸    入         : temp
  80. * 輸    出         : 無
  81. *******************************************************************************/

  82. void datapros(int temp)    // 車外溫度考慮零下溫度         
  83. {
  84.   float tp;  
  85.         //tp=temp;
  86.         //temp=tp*0.0625*100+0.5;        
  87.         //temp=tp/16*100;//+0.5;        //盡量避免浮點(diǎn)型運(yùn)算//留兩個小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時候把小數(shù)點(diǎn)
  88.                                 //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  89.                                 //算加上0.5,還是在小數(shù)點(diǎn)后面。

  90.                 if(temp< 0)                                           //當(dāng)溫度值為負(fù)數(shù)
  91.   {
  92.                 DisplayOneChar(2,1,'-');  //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
  93.                 temp=temp-1;
  94.                 temp=~temp;
  95.                 tp=temp;
  96.                 temp=tp*0.0625*100+0.5;        
  97.                                          //留兩個小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時候把小數(shù)點(diǎn)
  98.                                          //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  99.                                          //算加上0.5,還是在小數(shù)點(diǎn)后面。

  100.   }
  101.          else
  102.   {                        
  103.                 DisplayOneChar(2,1,' ');
  104.                 tp=temp;                   //因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個浮點(diǎn)型變量
  105.                                            //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
  106.                 temp=tp*0.0625*100+0.5;        
  107.                                            //留兩個小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時候把小數(shù)點(diǎn)
  108.                                            //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  109.                                            //算加上0.5,還是在小數(shù)點(diǎn)后面。
  110.         }
  111.         
  112.         if(temp/10000 ==0)  DisplayOneChar(2,1,(temp/10000)+' ');      //假如溫度百位等于0就不在顯示
  113.         else DisplayOneChar(2,1,(temp/10000)+'0');                     // 百位
  114.         DisplayOneChar(3,1,(temp%10000)/1000+'0');   // 十位
  115.         DisplayOneChar(4,1,(temp%1000/100)+'0');     // 個位
  116.         DisplayOneChar(6,1,(temp%100/10)+'0');       // 小數(shù)點(diǎn)后 1 位
  117.   //DisplayOneChar(7,1,(temp%10)+'0');           // 小數(shù)點(diǎn)后 2 位
  118.         
  119. }

  120. /////////////////////////////////////////////////////////////////////////////////////////////////////////////

  121. void dataprosN(int temp)          // 車內(nèi)溫度不考慮零下
  122. {
  123.   float tp;  
  124.         tp=temp;//temp=tp*0.0625*100+0.5;        
  125.         temp=tp/16*100;//+0.5;        //盡量避免浮點(diǎn)型運(yùn)算//留兩個小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時候把小數(shù)點(diǎn)
  126.                                 //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  127.                                 //算加上0.5,還是在小數(shù)點(diǎn)后面。
  128.         
  129.         
  130.         
  131.         if(temp/10000 ==0)  DisplayOneChar(2,0,(temp/10000)+' ');      //假如溫度百位等于0就不在顯示
  132.         else DisplayOneChar(2,0,(temp/10000)+'0');                     // 百位  
  133.         DisplayOneChar(3,0,(temp%10000)/1000+'0');                     // 十位
  134.         DisplayOneChar(4,0,(temp%1000/100)+'0');                       // 個位
  135.         DisplayOneChar(6,0,(temp%100/10)+'0');                         // 小數(shù)點(diǎn)后 1 位                                            
  136.   //DisplayOneChar(7,0,(temp%10)+'0');                             // 小數(shù)點(diǎn)后 2 位
  137. }

  138. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  139. void dataprosS(int temp)          // 水溫度不考慮零下
  140. {
  141.   float tp;  
  142.         tp=temp;//temp=tp*0.0625*100+0.5;        
  143.         temp=tp/16*100;//+0.5;        //盡量避免浮點(diǎn)型運(yùn)算//留兩個小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時候把小數(shù)點(diǎn)
  144.                                 //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  145.                                 //算加上0.5,還是在小數(shù)點(diǎn)后面。
  146.         
  147.         
  148.         if(temp/10000 ==0)  DisplayOneChar(11,1,(temp/10000)+' ');      //假如溫度百位等于0就不在顯示
  149.         else DisplayOneChar(11,1,(temp/10000)+'0');                     // 百位
  150.         DisplayOneChar(12,1,(temp%10000)/1000+'0');   // 十位
  151.         DisplayOneChar(13,1,(temp%1000/100)+'0');     // 個位
  152.         DisplayOneChar(15,1,(temp%100/10)+'0');       // 小數(shù)點(diǎn)后 1 位
  153.         

  154.                                                    
  155. //DisplayOneChar(7,1,(temp%10)+'0');           // 小數(shù)點(diǎn)后 2 位
  156. }


  157. //*********************************   主函數(shù)   ******************************************************

  158. void main()
  159. {                                                                                                               
  160.         unsigned int i = 0;
  161.         
  162.         
  163.         Init_Lcd();        //  初始化1602液晶顯示器
  164.         GPSUart_Init();
  165.         Write_LCD(0,0,"   Good  Luck   ");
  166.         Write_LCD(0,1,"Happy  ever  day");        
  167.         
  168.   Delay1s(1);    //延時3S

  169.         LCD_write_command(0x01);  //  清屏
  170.         
  171.         
  172.         
  173.         while(1)      
  174.         {               
  175.                
  176.                
  177.                 unsigned int a;
  178.                
  179. //------------------------------第一屏:顯示溫度----------------------
  180.                
  181.                 for(a=15;a;a--)      //保持溫度采樣顯示 7秒 左右(大概2.2倍秒的關(guān)系)
  182.                         
  183.                 { Write_LCD(0,0,"n:");               
  184.                         Write_LCD(5,0,".");        
  185.                         Write_LCD(8,0,"H:");               
  186.                         Write_LCD(0,1,"w:");               
  187.                         Write_LCD(5,1,".");               
  188.                         Write_LCD(8,1,"S:");
  189.                         Write_LCD(14,1,".");
  190.                         datapros(Ds18b20ReadTemp());         //數(shù)據(jù)處理函數(shù)        
  191.                         dataprosN(Ds18b20ReadTempN());         //數(shù)據(jù)處理函數(shù)        
  192.                         dataprosS(Ds18b20ReadTempS());         //數(shù)據(jù)處理函數(shù)
  193.                 }               
  194.             LCD_write_command(0x01);  //  清屏
  195.                
  196.                
  197. //---------------------------- 第二屏:測試用 ------------------------------------------
  198.                
  199.                 for(a=15;a;a--)      //保持屏幕 5秒 左右(大概10倍秒的關(guān)系)
  200.                         
  201.                 {
  202.                         
  203.                         Write_LCD(0,0,"Let's go.....");        // 用做測試第二屏顯示
  204.                
  205.                 }
  206.                
  207.                  LCD_write_command(0x01);  //  清屏

  208. //-----------------------------------------------------------------------------------------------------               
  209. //---------------------------- 第三屏:處理GPS 顯示海拔、速度 ------------------------------------------
  210. //-----------------------------------------------------------------------------------------------------               
  211.                
  212.         
  213.         
  214.         Write_LCD(0,0,"BBBBBB.....");        // 測試用
  215.         Delay1s(1);    //延時3S
  216.          LCD_write_command(0x01);  //  清屏        
  217.                
  218.                 qian_OK=0;                                                                        //標(biāo)志變量歸零
  219.                 k=0;                                                                                    //累計(jì)量歸零

  220.         
  221.                 if (   Flag_GPS_OK  == 1
  222.                               && RX_Buffer[1] == 'G'
  223.                              && RX_Buffer[3] == 'G'
  224.                              && RX_Buffer[4] == 'G'
  225.                              && RX_Buffer[5] == 'A'
  226.                              && (RX_Buffer[28] == 'N'|| RX_Buffer[28] == 'S')
  227.                              && (RX_Buffer[41] == 'E'|| RX_Buffer[41] == 'W') )                //確認(rèn)是否收到"GPGGA"這一幀完整有效的數(shù)據(jù)
  228.                
  229.                                                 {
  230.                                                         for( i = 0; i < 67 ; i++)                                                                //必須為i<67,因?yàn)橐_保Display_GPGGA_Buffer[67]為'\0',便于串口發(fā)送
  231.                                                                 {
  232.                                                                                 Display_GPGGA_Buffer[i] = RX_Buffer[i];                      //儲存到數(shù)組中
  233.                                                                 }
  234.                                                         Flag_Calc_GPGGA_OK = 1;                                                                        //收到完整有效數(shù)據(jù)后,置為1
  235.                                                 }


  236.                         LCD_write_command(0x85);  
  237.                   LCD_write_data(RX_Buffer[45]);        // 測試用,有每一幀的  第45 位的數(shù)據(jù),
  238.                                                 
  239.                                 LCD_write_command(0x88);  
  240.                         LCD_write_data(Display_GPGGA_Buffer[2]);           //   沒數(shù)據(jù)
  241.                  Delay1s(1);    //延時3S
  242.                  LCD_write_command(0x01);  //  清屏
  243.         
  244.                 Write_LCD(0,0,"VVVVVV.....");        
  245.           Delay1s(1);    //延時3S
  246. }
  247. }        

  248. //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  249. /****************************************************************************************************************


  250. *****************************************************************************************************************/

  251. #include "pcf8574lcd.h"
  252. char ADDR = 0x4E;    // PCF8574T  模塊的地址碼

  253. //***************************** 延時 XX  ms ***********************************************

  254. void delay(int y)   
  255. {
  256.          ;
  257.         while(y--)
  258.         {
  259.         unsigned char a,b,c;
  260.         for(c=1;c>0;c--)
  261.         for(b=142;b>0;b--)
  262.         for(a=2;a>0;a--);
  263.         }
  264. }

  265. /***************************** 這是從其他地方移植過來的 *********************
  266. void delay(int ms)   
  267. {
  268.         unsigned char y ;
  269.         while(ms--)
  270.         {
  271.                 for(y = 0 ; y<250 ; y++)     //  這是從其他地方移植過來的
  272.                 {
  273.                         _nop_() ;
  274.                         _nop_() ;
  275.                         _nop_() ;
  276.                         _nop_() ;
  277.                 }
  278.         }
  279. }
  280. *************************************************************************************/


  281. //******************************** IIC 串口開始 ********************************************

  282. void IIC_start(void)
  283. {
  284.         SDA=1;
  285.         _nop_();
  286.         SCL=1;
  287.         _nop_();
  288.         _nop_();
  289.         _nop_();
  290.         _nop_();
  291.         _nop_();
  292.         SDA=0;
  293.         _nop_();
  294.         _nop_();
  295.         _nop_();
  296.         _nop_();
  297.         _nop_();
  298.         SCL=0;
  299. }


  300. //********************************* IIC 串口結(jié)束 *******************************************

  301. void IIC_stop(void)
  302. {
  303.         SDA=0;
  304.         _nop_();
  305.         SCL=1;
  306.         _nop_();
  307.         _nop_();
  308.         _nop_();
  309.         _nop_();
  310.         _nop_();
  311.         SDA=1;
  312.         _nop_();
  313.         _nop_();
  314.         _nop_();
  315.         _nop_();
  316. }

  317. //********************************** IIC 串口寫1個字節(jié) ******************************************

  318. void IIC_writeByte(char temp)
  319. {
  320.         char i;
  321.         for(i=0;i<8;i++)
  322.         {
  323.                 SDA=(bit)(temp & 0x80) ;   // 根據(jù)規(guī)定1602的數(shù)據(jù)最高位必須為  1  
  324.                 temp <<=1;
  325.                 _nop_();
  326.                 _nop_();
  327.                 SCL=1;
  328.                 _nop_();
  329.                 _nop_();
  330.                 _nop_();
  331.                 _nop_();
  332.                 _nop_();
  333.                 SCL=0;
  334.         }
  335.         _nop_();
  336.         _nop_();
  337.         _nop_();
  338.         _nop_();
  339.         SDA=1;
  340.         _nop_();
  341.         _nop_();
  342.         _nop_();
  343.         _nop_();
  344.         SCL=1;
  345.         _nop_();
  346.         _nop_();
  347.         _nop_();
  348.         while(SDA);
  349.         _nop_();
  350.         SCL=0;
  351. }



  352. //**************************************************************************************************************
  353. //********************************************* 以下是對1602 的操作  ******************************************
  354. //**************************************************************************************************************


  355. //******************************** 1602寫命令 ********************************************

  356. void LCD_write_command(char comm)
  357. {
  358.         char tmp;
  359.         IIC_start();          // 串口開始
  360.         IIC_writeByte(ADDR);  // 先選PCF 8574T 的地址  (應(yīng)該是相當(dāng)于選中的意思吧)
  361.         
  362.         tmp = comm & 0xF0;    // 與0xf0 應(yīng)該是取第四位的意思吧
  363.         tmp |= 0x0C;         //保留高4位為指令的高四位,低四位為   RS = 0, RW = 0, EN = 1  
  364.         IIC_writeByte(tmp);  //從串口送出
  365.         delay(20);
  366.         tmp &= 0xFB;        //Make EN = 0
  367.         IIC_writeByte(tmp);
  368.         
  369.         tmp = (comm & 0x0F) << 4 ;  //將指令的低四位 送到高位置保存
  370.         tmp |= 0x0C;        //RS = 0, RW = 0, EN = 1
  371.         IIC_writeByte(tmp);
  372.         delay(20);
  373.         tmp &= 0xFB; // Make EN = 0
  374.         IIC_writeByte(tmp);
  375.         //stop_8574();
  376. }

  377. //******************************** 1602寫數(shù)據(jù) ********************************************

  378. void LCD_write_data(char data1)
  379. {
  380.         char tmp;
  381.         IIC_start();
  382.         IIC_writeByte(ADDR);   // 先選PCF 8574T 的地址  (應(yīng)該是相當(dāng)于選中的意思吧)
  383.         
  384.         tmp = data1 & 0xF0;
  385.         tmp |= 0x0D; //RS = 0, RW = 0, EN = 1
  386.         IIC_writeByte(tmp);
  387.         delay(20);
  388.         tmp &= 0xFB; //Make EN = 0
  389.         IIC_writeByte(tmp);
  390.         
  391.         tmp = (data1 & 0x0F) << 4 ;
  392.         tmp |= 0x0D; //RS = 0, RW = 0, EN = 1
  393.         IIC_writeByte(tmp);
  394.         delay(20);
  395.         tmp &= 0xFB ; // Make EN = 0
  396.         IIC_writeByte(tmp);
  397. }

  398. //******************************** 1602初始化 ********************************************

  399. void Init_Lcd(void)
  400. {
  401.         LCD_write_command(0x33); //
  402.         delay(50) ;
  403.         LCD_write_command(0x32); //
  404.         delay(50) ;
  405.         LCD_write_command(0x28); // 4位數(shù)據(jù)線,顯示2行,5*7點(diǎn)陣字符  !如果是0x38  則為8位數(shù)據(jù)線,顯示2行,5*7點(diǎn)陣字符
  406.         delay(50) ;
  407.         LCD_write_command(0x0C); // 開顯示,關(guān)閉光標(biāo),不閃爍
  408.         delay(50) ;  
  409.         LCD_write_command(0x06); // 設(shè)定輸入方式,增量不位移
  410.         delay(50) ;
  411.         LCD_write_command(0x01); // 清屏
  412.         delay(50) ;
  413. }


  414. //********************************** 1602清屏 ******************************************

  415. void Clear_Lcd(void)
  416. {
  417.         LCD_write_command(0x01);
  418. }

  419. //****************************************************************************

  420. void Write_LCD(int x, int y, char *str)   //顯示字符串的函數(shù)
  421. {
  422.         char addr;
  423.         if( x < 0)
  424.         {
  425.                 x = 0;
  426.         }
  427.         if(x > 15)
  428.         {
  429.                 x = 15;
  430.         }
  431.         if(y<0)
  432.         {
  433.                 y = 0;
  434.         }
  435.         if(y > 1)
  436.         {
  437.                 y = 1;
  438.         }
  439.         
  440.         addr = 0x80 + 0x40 * y + x;   // Move cursor  移動光標(biāo)
  441.         LCD_write_command(addr);
  442.         while (*str)
  443.         {
  444.                 LCD_write_data(*str++);
  445.         }
  446. }

  447. //****************************************************************************

  448. //按指定位置顯示一個字符
  449. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  450. {
  451. Y &= 0x1;
  452. X &= 0xF; //限制X不能大于15,Y不能大于1
  453. if (Y) X |= 0x40; //當(dāng)要顯示第二行時地址碼+0x40;
  454. X |= 0x80; // 算出指令碼
  455. LCD_write_command(X); //這里不檢測忙信號,發(fā)送地址碼
  456. LCD_write_data(DData);
  457. }


  458. //*****************************************************************************************************************************************************************************************************

  459. //********************************************* 以下是對18b20 的操作  **********************************************************************************************************************************

  460. //*****************************************************************************************************************************************************************************************************


  461. /*******************************************************************************
  462. * 函 數(shù) 名         : Delay1ms
  463. * 函數(shù)功能                       : 延時函數(shù)
  464. * 輸    入         : 無
  465. * 輸    出         : 無
  466. *******************************************************************************/

  467. void Delay1ms(uint y) //誤差 0us  STC12系列專用
  468. {
  469.         while(y--)
  470.         {
  471.         unsigned char a,b,c;
  472.         for(c=1;c>0;c--)
  473.         for(b=142;b>0;b--)
  474.         for(a=2;a>0;a--);
  475.         }
  476. }



  477. ////////////////////////////////////////////////////////

  478. void delay_us(uchar x)      //延時 X  us    STC12系列專用
  479. {uchar i;
  480. for(i=0;i<x;i++);
  481. }

  482. void delay_1us()            //延時 1 us
  483. {
  484. uchar i;
  485. for(i=0;i<1;i++);
  486. }




  487. /*******************************************************************************
  488. * 函 數(shù) 名         : Ds18b20Init
  489. * 函數(shù)功能                                   : 初始化
  490. * 輸    入         : 無
  491. * 輸    出         : 初始化成功返回1,失敗返回0
  492. *******************************************************************************/

  493. uchar Ds18b20Init()
  494. {
  495.         bit flag;
  496.         DSPORT = 1;        
  497.         delay_1us();
  498.         DSPORT = 0;                        
  499.         delay_us(255);    //將總線拉低480us~960us
  500.         DSPORT = 1;                        //然后拉高總線,如果DS18B20做出反應(yīng)會將在15us~60us后總線拉低
  501.         delay_us(30);   //等待15-60微秒,18b20作出回應(yīng)
  502.         flag=DSPORT;    //檢測是否為低電平
  503.         delay_us(255);
  504.         delay_us(255);  //延時足夠長,最少480us,完成復(fù)位周期
  505.         return (flag);
  506.         
  507. }

  508. uchar Ds18b20InitN()
  509. {
  510.         bit flag;
  511.         DSPORTN = 1;        
  512.         delay_1us();
  513.         DSPORTN = 0;                        
  514.         delay_us(255);    //將總線拉低480us~960us
  515.         DSPORTN = 1;                        //然后拉高總線,如果DS18B20做出反應(yīng)會將在15us~60us后總線拉低
  516.         delay_us(30);   //等待15-60微秒,18b20作出回應(yīng)
  517.         flag=DSPORTN;    //檢測是否為低電平
  518.         delay_us(255);
  519.         delay_us(255);  //延時足夠長,最少480us,完成復(fù)位周期
  520.         return (flag);
  521.         
  522. }


  523. uchar Ds18b20InitS()
  524. {
  525.         bit flag;
  526.         DSPORTS = 1;        
  527.         delay_1us();
  528.         DSPORTS = 0;                        
  529.         delay_us(255);    //將總線拉低480us~960us
  530.         DSPORTS = 1;                        //然后拉高總線,如果DS18B20做出反應(yīng)會將在15us~60us后總線拉低
  531.         delay_us(30);   //等待15-60微秒,18b20作出回應(yīng)
  532.         flag=DSPORTS;    //檢測是否為低電平
  533.         delay_us(255);
  534.         delay_us(255);  //延時足夠長,最少480us,完成復(fù)位周期
  535.         return (flag);
  536.         
  537. }

  538. /*******************************************************************************
  539. * 函 數(shù) 名         : Ds18b20WriteByte
  540. * 函數(shù)功能                      : 向18B20寫入一個字節(jié)
  541. * 輸    入         : 無
  542. * 輸    出         : 無
  543. *******************************************************************************/

  544. void Ds18b20WriteByte(uchar dat)
  545. {
  546.         uchar i;
  547.         for(i=0;i<8;i++)
  548.         {
  549.         DSPORT=1;
  550.         delay_1us();//稍作延時
  551.         DSPORT=0;//啟動寫時序
  552.         DSPORT=dat&0x01;//向數(shù)據(jù)線傳送最低位
  553.         delay_us(40);//延時約50us,供18b20采樣數(shù)據(jù)
  554.         DSPORT=1;//釋放總線
  555.         delay_1us();
  556.         dat>>=1;//右移一位
  557.         }
  558. delay_us(2);//寫完一個指令稍作延時

  559. }

  560. void Ds18b20WriteByteN(uchar dat)
  561. {
  562.         uchar i;
  563.         for(i=0;i<8;i++)
  564.         {
  565.         DSPORTN=1;
  566.         delay_1us();//稍作延時
  567.         DSPORTN=0;//啟動寫時序
  568.         DSPORTN=dat&0x01;//向數(shù)據(jù)線傳送最低位
  569.         delay_us(40);//延時約50us,供18b20采樣數(shù)據(jù)
  570.         DSPORTN=1;//釋放總線
  571.         delay_1us();
  572.         dat>>=1;//右移一位
  573.         }
  574. delay_us(2);//寫完一個指令稍作延時

  575. }

  576. void Ds18b20WriteByteS(uchar dat)
  577. {
  578.         uchar i;
  579.         for(i=0;i<8;i++)
  580.         {
  581.         DSPORTS=1;
  582.         delay_1us();//稍作延時
  583.         DSPORTS=0;//啟動寫時序
  584.         DSPORTS=dat&0x01;//向數(shù)據(jù)線傳送最低位
  585.         delay_us(40);//延時約50us,供18b20采樣數(shù)據(jù)
  586.         DSPORTS=1;//釋放總線
  587.         delay_1us();
  588.         dat>>=1;//右移一位
  589.         }
  590. delay_us(2);//寫完一個指令稍作延時

  591. }
  592. /*******************************************************************************
  593. * 函 數(shù) 名         : Ds18b20ReadByte
  594. * 函數(shù)功能                                    : 讀取一個字節(jié)
  595. * 輸    入         : 無
  596. * 輸    出         : 無
  597. *******************************************************************************/


  598. uchar Ds18b20ReadByte()
  599. {
  600.         uchar i=0,dat;
  601.         for(i=0;i<8;i++)
  602.         {
  603.                
  604.         DSPORT=1;//先拉高
  605.         delay_1us();//稍作延時
  606.         DSPORT=0;//啟動讀時序
  607.         delay_1us();//稍作延時
  608.         DSPORT=1;//釋放總線
  609.         delay_us(6);//延時7us,主機(jī)采樣
  610.         dat>>=1;//先右移一位,使最高位為0
  611.         if(DSPORT==1)
  612.                    dat|=0x80;//與10000000或,dat=10000000
  613.         else
  614.                 dat|=0x00;//取值為0
  615.         delay_us(50);
  616.         }
  617. return(dat);

  618. }

  619. uchar Ds18b20ReadByteN()
  620. {
  621.         uchar i=0,dat;
  622.         for(i=0;i<8;i++)
  623.         {
  624.                
  625.         DSPORTN=1;//先拉高
  626.         delay_1us();//稍作延時
  627.         DSPORTN=0;//啟動讀時序
  628.         delay_1us();//稍作延時
  629.         DSPORTN=1;//釋放總線
  630.         delay_us(6);//延時7us,主機(jī)采樣
  631.         dat>>=1;//先右移一位,使最高位為0
  632.         if(DSPORTN==1)
  633.                    dat|=0x80;//與10000000或,dat=10000000
  634.         else
  635.                 dat|=0x00;//取值為0
  636.         delay_us(50);
  637.         }
  638. return(dat);

  639. }

  640. uchar Ds18b20ReadByteS()
  641. {
  642.         uchar i=0,dat;
  643.         for(i=0;i<8;i++)
  644.         {
  645.                
  646.         DSPORTS=1;//先拉高
  647.         delay_1us();//稍作延時
  648.         DSPORTS=0;//啟動讀時序
  649.         delay_1us();//稍作延時
  650.         DSPORTS=1;//釋放總線
  651.         delay_us(6);//延時7us,主機(jī)采樣
  652.         dat>>=1;//先右移一位,使最高位為0
  653.         if(DSPORTS==1)
  654.                    dat|=0x80;//與10000000或,dat=10000000
  655.         else
  656.                 dat|=0x00;//取值為0
  657.         delay_us(50);
  658.         }
  659. return(dat);

  660. }


  661. /*******************************************************************************
  662. * 函 數(shù) 名         : Ds18b20ChangTemp
  663. * 函數(shù)功能                       : 讓18b20開始轉(zhuǎn)換溫度
  664. * 輸    入         : 無
  665. * 輸    出         : 無
  666. *******************************************************************************/

  667. void  Ds18b20ChangTemp()
  668. {
  669.         Ds18b20Init();
  670.   Delay1ms(1);
  671.         Ds18b20WriteByte(0xcc);                //跳過ROM操作命令                 
  672.         Ds18b20WriteByte(0x44);            //溫度轉(zhuǎn)換命令
  673.         //Delay1ms(100);        //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個延時了

  674. }

  675. void  Ds18b20ChangTempN()
  676. {
  677.         Ds18b20InitN();
  678.   Delay1ms(1);
  679.         Ds18b20WriteByteN(0xcc);                //跳過ROM操作命令                 
  680.         Ds18b20WriteByteN(0x44);            //溫度轉(zhuǎn)換命令
  681.         //Delay1ms(100);        //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個延時了

  682. }

  683. void  Ds18b20ChangTempS()
  684. {
  685.         Ds18b20InitS();
  686.   Delay1ms(1);
  687.         Ds18b20WriteByteS(0xcc);                //跳過ROM操作命令                 
  688.         Ds18b20WriteByteS(0x44);            //溫度轉(zhuǎn)換命令
  689.         //Delay1ms(100);        //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個延時了

  690. }


  691. /*******************************************************************************
  692. * 函 數(shù) 名         : Ds18b20ReadTempCom
  693. * 函數(shù)功能                       : 發(fā)送讀取溫度命令
  694. * 輸    入         : 無
  695. * 輸    出         : 無
  696. *******************************************************************************/

  697. void  Ds18b20ReadTempCom()
  698. {        

  699.         Ds18b20Init();
  700.   Delay1ms(1);
  701.         Ds18b20WriteByte(0xcc);         //跳過ROM操作命令
  702.         Ds18b20WriteByte(0xbe);         //發(fā)送讀取溫度命令
  703. }

  704. void  Ds18b20ReadTempComN()
  705. {        

  706.         Ds18b20InitN();
  707.   Delay1ms(1);
  708.         Ds18b20WriteByteN(0xcc);         //跳過ROM操作命令
  709.         Ds18b20WriteByteN(0xbe);         //發(fā)送讀取溫度命令
  710. }

  711. void  Ds18b20ReadTempComS()
  712. {        

  713.         Ds18b20InitS();
  714.   Delay1ms(1);
  715.         Ds18b20WriteByteS(0xcc);         //跳過ROM操作命令
  716.         Ds18b20WriteByteS(0xbe);         //發(fā)送讀取溫度命令
  717. }


  718. /*******************************************************************************
  719. * 函 數(shù) 名         : Ds18b20ReadTemp
  720. * 函數(shù)功能                       : 讀取溫度
  721. * 輸    入         : 無
  722. * 輸    出         : 無
  723. *******************************************************************************/

  724. int Ds18b20ReadTemp()
  725. {
  726.         int temp = 0;
  727.         uchar tmh, tml;
  728.         Ds18b20ChangTemp();                                 //先寫入轉(zhuǎn)換命令
  729.         Ds18b20ReadTempCom();                        //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
  730.         tml = Ds18b20ReadByte();                //讀取溫度值共16位,先讀低字節(jié)
  731.         tmh = Ds18b20ReadByte();                //再讀高字節(jié)
  732.         temp = tmh;
  733.         temp <<= 8;
  734.         temp |= tml;
  735.         return temp;
  736. }

  737. int Ds18b20ReadTempN()
  738. {
  739.         int temp = 0;
  740.         uchar tmh, tml;
  741.         Ds18b20ChangTempN();                                 //先寫入轉(zhuǎn)換命令
  742.         Ds18b20ReadTempComN();                        //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
  743.         tml = Ds18b20ReadByteN();                //讀取溫度值共16位,先讀低字節(jié)
  744.         tmh = Ds18b20ReadByteN();                //再讀高字節(jié)
  745.         temp = tmh;
  746.         temp <<= 8;
  747.         temp |= tml;
  748.         return temp;
  749. }


  750. int Ds18b20ReadTempS()
  751. {
  752.         int temp = 0;
  753.         uchar tmh, tml;
  754.         Ds18b20ChangTempS();                                 //先寫入轉(zhuǎn)換命令
  755.         Ds18b20ReadTempComS();                        //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
  756.         tml = Ds18b20ReadByteS();                //讀取溫度值共16位,先讀低字節(jié)
  757.         tmh = Ds18b20ReadByteS();                //再讀高字節(jié)
  758.         temp = tmh;
  759.         temp <<= 8;
  760.         temp |= tml;
  761.         return temp;
  762. }


  763. //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
  764. #ifndef __PCF8574LCD_H__
  765. #define __PCF8574LCD_H__
  766. #include <reg52.h>
  767. #include "intrins.h"
  768. #define uchar unsigned char
  769. #define uint unsigned int
  770.         
  771. sbit SCL = P1^0;
  772. sbit SDA = P1^1;
  773.         
  774. void delay(int ms);    //   延時 XX  ms

  775. void IIC_start(void);  //   IIC 串口開始

  776. void IIC_stop(void);   //   IIC 串口結(jié)束

  777. void IIC_writeByte(char temp);      //    IIC 串口寫1個字節(jié)

  778. void LCD_write_command(char comm);  //   1602寫命令

  779. void LCD_write_data(char data1);    //   1602寫數(shù)據(jù)

  780. void Init_Lcd(void);                //   1602初始化

  781. void Clear_Lcd(void);               //   1602清屏

  782. void Write_LCD(int x, int y, char *str);   //  顯示字符串(小張寫的)



  783. void Write_Customer(int x, int y, char str[]);

  784. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);  //按指定位置顯示一個字符




  785. //**************** 18B20*************************************************


  786. //--定義使用的IO口--//

  787. sbit DSPORT=P2^1;   // 車外溫度接口

  788. //--聲明全局函數(shù)--//
  789. void Delay1ms(uint );
  790. uchar Ds18b20Init();
  791. void Ds18b20WriteByte(uchar com);
  792. uchar Ds18b20ReadByte();
  793. void  Ds18b20ChangTemp();
  794. void  Ds18b20ReadTempCom();
  795. int Ds18b20ReadTemp();

  796. sbit DSPORTN=P2^2;   // 車內(nèi)溫度接口

  797. //--聲明全局函數(shù)--//

  798. uchar Ds18b20InitN();
  799. void  Ds18b20WriteByteN(uchar com);
  800. uchar Ds18b20ReadByteN();
  801. void  Ds18b20ChangTempN();
  802. void  Ds18b20ReadTempComN();
  803. int Ds18b20ReadTempN();


  804. sbit DSPORTS=P2^3;   // 水溫度接口

  805. //--聲明全局函數(shù)--//

  806. uchar Ds18b20InitS();
  807. void Ds18b20WriteByteS(uchar com);
  808. uchar Ds18b20ReadByteS();
  809. void  Ds18b20ChangTempS();
  810. void  Ds18b20ReadTempComS();
  811. int Ds18b20ReadTempS();

  812. //****************************************



  813. #endif
復(fù)制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:648281 發(fā)表于 2020-1-2 12:11 | 只看該作者
你好!
你這個程序太長了,沒時間去逐句排查;
一般數(shù)據(jù)讀取不到,應(yīng)該是協(xié)議解析錯誤;
不同GPS模塊協(xié)議有所不同,仔細(xì)看看協(xié)議吧。
回復(fù)

使用道具 舉報(bào)

板凳
ID:408809 發(fā)表于 2020-1-3 11:47 | 只看該作者
51hei**1140 發(fā)表于 2020-1-2 12:11
你好!
你這個程序太長了,沒時間去逐句排查;
一般數(shù)據(jù)讀取不到,應(yīng)該是協(xié)議解析錯誤;

我基礎(chǔ)差,是排查不了啦。謝謝你!
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表