找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1432|回复: 2
打印 上一主题 下一主题
收起左侧

这个单片机程序中 感觉GPS的 GPGGA这条信息没有被保存

[复制链接]
跳转到指定楼层
楼主
ID:408809 发表于 2020-1-2 10:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我移植了论坛里一位师兄的 程序,但是存储PAGGA信息的数组内没有数据。
  1. #include <reg52.h>
  2. #include "pcf8574lcd.h"


  3. unsigned char RX_Buffer[68];                //此数组用于直接储存来自GPS的原始数据,
  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的数据
  8. unsigned char xdata Display_GPRMC_Buffer[68]={0};                //用于储存GPRMC的数据

  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;                   //已找出前面的逗号的标志变量
  11. bit First_Share_OK=0;  //已开始LCD显示的标志变量
  12. bit jiajian=1;                    //进行加或减的标志变量


  13. bit Flag_Calc_GPGGA_OK = 0;           //GPGGA完整有效的数据已收到的标志变量
  14. bit Flag_Calc_GPRMC_OK = 0;           //GPRMC完整有效的数据已收到的标志变量

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

  16. void GPSUart_Init()                        //  GPS串口初始化                                             
  17. {
  18.         
  19.                                              //    针对的是 STC89C52的,但是发现STC12C5A60S2单片机也可以用 ,同样都是11.0592的晶振。
  20.         SCON = 0X50;  //UART方式1;8位UART
  21.         REN  = 1;     //允许串行口接收数据
  22.         PCON = 0x00;  //SMOD=0;波特率不加倍   9600
  23.         TMOD = 0x20;  //T1方式2,用于产生波特率
  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                  //串口中断函数,收到GPS的数据时进入此中断        
  32. {
  33.         unsigned char temp = 0;
  34.         ES=0;                                                                                    //先关闭串行口中断
  35.         temp = SBUF;                                                                //接收SBUF中的数据
  36.         RI = 0;                                                                                  //接收完成的标志位清零
  37.         
  38.         if(temp == '


  39. )                                                                //若是统一的数据头,则作为数组第一个元素
  40.                 {
  41.                                 RX_Count = 0;
  42.                                 Flag_GPS_OK = 0;               
  43.                 }

  44.         RX_Buffer[RX_Count++] = temp;                                //收到的数据放到数组中

  45.         if(RX_Count >= 66)                                                        //序号大于66的数据无用,统一放到第66位覆盖掉
  46.                 {
  47.                                 RX_Count = 66;
  48.                 }

  49.         if(temp == '*')                                                                //收到*,则完成一帧数据的接收,不管是否完整有效
  50.                 {
  51.                                  Flag_GPS_OK = 1;                         //标志变量置为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. * 函 数 名         : datapros()
  78. * 函数功能                   : 温度读取处理转换函数
  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;        //尽量避免浮点型运算//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  88.                                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  89.                                 //算加上0.5,还是在小数点后面。

  90.                 if(temp< 0)                                           //当温度值为负数
  91.   {
  92.                 DisplayOneChar(2,1,'-');  //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  93.                 temp=temp-1;
  94.                 temp=~temp;
  95.                 tp=temp;
  96.                 temp=tp*0.0625*100+0.5;        
  97.                                          //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  98.                                          //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  99.                                          //算加上0.5,还是在小数点后面。

  100.   }
  101.          else
  102.   {                        
  103.                 DisplayOneChar(2,1,' ');
  104.                 tp=temp;                   //因为数据处理有小数点所以将温度赋给一个浮点型变量
  105.                                            //如果温度是正的那么,那么正数的原码就是补码它本身
  106.                 temp=tp*0.0625*100+0.5;        
  107.                                            //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  108.                                            //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  109.                                            //算加上0.5,还是在小数点后面。
  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');       // 小数点后 1 位
  117.   //DisplayOneChar(7,1,(temp%10)+'0');           // 小数点后 2 位
  118.         
  119. }

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

  121. void dataprosN(int temp)          // 车内温度不考虑零下
  122. {
  123.   float tp;  
  124.         tp=temp;//temp=tp*0.0625*100+0.5;        
  125.         temp=tp/16*100;//+0.5;        //尽量避免浮点型运算//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  126.                                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  127.                                 //算加上0.5,还是在小数点后面。
  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');                         // 小数点后 1 位                                            
  136.   //DisplayOneChar(7,0,(temp%10)+'0');                             // 小数点后 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;        //尽量避免浮点型运算//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  144.                                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  145.                                 //算加上0.5,还是在小数点后面。
  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');       // 小数点后 1 位
  153.         

  154.                                                    
  155. //DisplayOneChar(7,1,(temp%10)+'0');           // 小数点后 2 位
  156. }


  157. //*********************************   主函数   ******************************************************

  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倍秒的关系)
  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());         //数据处理函数        
  191.                         dataprosN(Ds18b20ReadTempN());         //数据处理函数        
  192.                         dataprosS(Ds18b20ReadTempS());         //数据处理函数
  193.                 }               
  194.             LCD_write_command(0x01);  //  清屏
  195.                
  196.                
  197. //---------------------------- 第二屏:测试用 ------------------------------------------
  198.                
  199.                 for(a=15;a;a--)      //保持屏幕 5秒 左右(大概10倍秒的关系)
  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;                                                                        //标志变量归零
  219.                 k=0;                                                                                    //累计量归零

  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') )                //确认是否收到"GPGGA"这一帧完整有效的数据
  228.                
  229.                                                 {
  230.                                                         for( i = 0; i < 67 ; i++)                                                                //必须为i<67,因为要确保Display_GPGGA_Buffer[67]为'\0',便于串口发送
  231.                                                                 {
  232.                                                                                 Display_GPGGA_Buffer[i] = RX_Buffer[i];                      //储存到数组中
  233.                                                                 }
  234.                                                         Flag_Calc_GPGGA_OK = 1;                                                                        //收到完整有效数据后,置为1
  235.                                                 }


  236.                         LCD_write_command(0x85);  
  237.                   LCD_write_data(RX_Buffer[45]);        // 测试用,有每一帧的  第45 位的数据,
  238.                                                 
  239.                                 LCD_write_command(0x88);  
  240.                         LCD_write_data(Display_GPGGA_Buffer[2]);           //   没数据
  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 串口结束 *******************************************

  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个字节 ******************************************

  318. void IIC_writeByte(char temp)
  319. {
  320.         char i;
  321.         for(i=0;i<8;i++)
  322.         {
  323.                 SDA=(bit)(temp & 0x80) ;   // 根据规定1602的数据最高位必须为  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 的地址  (应该是相当于选中的意思吧)
  361.         
  362.         tmp = comm & 0xF0;    // 与0xf0 应该是取第四位的意思吧
  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写数据 ********************************************

  378. void LCD_write_data(char data1)
  379. {
  380.         char tmp;
  381.         IIC_start();
  382.         IIC_writeByte(ADDR);   // 先选PCF 8574T 的地址  (应该是相当于选中的意思吧)
  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位数据线,显示2行,5*7点阵字符  !如果是0x38  则为8位数据线,显示2行,5*7点阵字符
  406.         delay(50) ;
  407.         LCD_write_command(0x0C); // 开显示,关闭光标,不闪烁
  408.         delay(50) ;  
  409.         LCD_write_command(0x06); // 设定输入方式,增量不位移
  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)   //显示字符串的函数
  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  移动光标
  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; //当要显示第二行时地址码+0x40;
  454. X |= 0x80; // 算出指令码
  455. LCD_write_command(X); //这里不检测忙信号,发送地址码
  456. LCD_write_data(DData);
  457. }


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

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

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


  461. /*******************************************************************************
  462. * 函 数 名         : Delay1ms
  463. * 函数功能                       : 延时函数
  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. * 函 数 名         : Ds18b20Init
  489. * 函数功能                                   : 初始化
  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做出反应会将在15us~60us后总线拉低
  501.         delay_us(30);   //等待15-60微秒,18b20作出回应
  502.         flag=DSPORT;    //检测是否为低电平
  503.         delay_us(255);
  504.         delay_us(255);  //延时足够长,最少480us,完成复位周期
  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做出反应会将在15us~60us后总线拉低
  516.         delay_us(30);   //等待15-60微秒,18b20作出回应
  517.         flag=DSPORTN;    //检测是否为低电平
  518.         delay_us(255);
  519.         delay_us(255);  //延时足够长,最少480us,完成复位周期
  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做出反应会将在15us~60us后总线拉低
  531.         delay_us(30);   //等待15-60微秒,18b20作出回应
  532.         flag=DSPORTS;    //检测是否为低电平
  533.         delay_us(255);
  534.         delay_us(255);  //延时足够长,最少480us,完成复位周期
  535.         return (flag);
  536.         
  537. }

  538. /*******************************************************************************
  539. * 函 数 名         : Ds18b20WriteByte
  540. * 函数功能                      : 向18B20写入一个字节
  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;//向数据线传送最低位
  553.         delay_us(40);//延时约50us,供18b20采样数据
  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;//向数据线传送最低位
  569.         delay_us(40);//延时约50us,供18b20采样数据
  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;//向数据线传送最低位
  585.         delay_us(40);//延时约50us,供18b20采样数据
  586.         DSPORTS=1;//释放总线
  587.         delay_1us();
  588.         dat>>=1;//右移一位
  589.         }
  590. delay_us(2);//写完一个指令稍作延时

  591. }
  592. /*******************************************************************************
  593. * 函 数 名         : Ds18b20ReadByte
  594. * 函数功能                                    : 读取一个字节
  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,主机采样
  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,主机采样
  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,主机采样
  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. * 函 数 名         : Ds18b20ChangTemp
  663. * 函数功能                       : 让18b20开始转换温度
  664. * 输    入         : 无
  665. * 输    出         : 无
  666. *******************************************************************************/

  667. void  Ds18b20ChangTemp()
  668. {
  669.         Ds18b20Init();
  670.   Delay1ms(1);
  671.         Ds18b20WriteByte(0xcc);                //跳过ROM操作命令                 
  672.         Ds18b20WriteByte(0x44);            //温度转换命令
  673.         //Delay1ms(100);        //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

  674. }

  675. void  Ds18b20ChangTempN()
  676. {
  677.         Ds18b20InitN();
  678.   Delay1ms(1);
  679.         Ds18b20WriteByteN(0xcc);                //跳过ROM操作命令                 
  680.         Ds18b20WriteByteN(0x44);            //温度转换命令
  681.         //Delay1ms(100);        //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

  682. }

  683. void  Ds18b20ChangTempS()
  684. {
  685.         Ds18b20InitS();
  686.   Delay1ms(1);
  687.         Ds18b20WriteByteS(0xcc);                //跳过ROM操作命令                 
  688.         Ds18b20WriteByteS(0x44);            //温度转换命令
  689.         //Delay1ms(100);        //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

  690. }


  691. /*******************************************************************************
  692. * 函 数 名         : Ds18b20ReadTempCom
  693. * 函数功能                       : 发送读取温度命令
  694. * 输    入         : 无
  695. * 输    出         : 无
  696. *******************************************************************************/

  697. void  Ds18b20ReadTempCom()
  698. {        

  699.         Ds18b20Init();
  700.   Delay1ms(1);
  701.         Ds18b20WriteByte(0xcc);         //跳过ROM操作命令
  702.         Ds18b20WriteByte(0xbe);         //发送读取温度命令
  703. }

  704. void  Ds18b20ReadTempComN()
  705. {        

  706.         Ds18b20InitN();
  707.   Delay1ms(1);
  708.         Ds18b20WriteByteN(0xcc);         //跳过ROM操作命令
  709.         Ds18b20WriteByteN(0xbe);         //发送读取温度命令
  710. }

  711. void  Ds18b20ReadTempComS()
  712. {        

  713.         Ds18b20InitS();
  714.   Delay1ms(1);
  715.         Ds18b20WriteByteS(0xcc);         //跳过ROM操作命令
  716.         Ds18b20WriteByteS(0xbe);         //发送读取温度命令
  717. }


  718. /*******************************************************************************
  719. * 函 数 名         : Ds18b20ReadTemp
  720. * 函数功能                       : 读取温度
  721. * 输    入         : 无
  722. * 输    出         : 无
  723. *******************************************************************************/

  724. int Ds18b20ReadTemp()
  725. {
  726.         int temp = 0;
  727.         uchar tmh, tml;
  728.         Ds18b20ChangTemp();                                 //先写入转换命令
  729.         Ds18b20ReadTempCom();                        //然后等待转换完后发送读取温度命令
  730.         tml = Ds18b20ReadByte();                //读取温度值共16位,先读低字节
  731.         tmh = Ds18b20ReadByte();                //再读高字节
  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();                                 //先写入转换命令
  742.         Ds18b20ReadTempComN();                        //然后等待转换完后发送读取温度命令
  743.         tml = Ds18b20ReadByteN();                //读取温度值共16位,先读低字节
  744.         tmh = Ds18b20ReadByteN();                //再读高字节
  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();                                 //先写入转换命令
  755.         Ds18b20ReadTempComS();                        //然后等待转换完后发送读取温度命令
  756.         tml = Ds18b20ReadByteS();                //读取温度值共16位,先读低字节
  757.         tmh = Ds18b20ReadByteS();                //再读高字节
  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 串口结束

  777. void IIC_writeByte(char temp);      //    IIC 串口写1个字节

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

  779. void LCD_write_data(char data1);    //   1602写数据

  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. //--声明全局函数--//
  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;   // 车内温度接口

  797. //--声明全局函数--//

  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. //--声明全局函数--//

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

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



  813. #endif
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:648281 发表于 2020-1-2 12:11 | 只看该作者
你好!
你这个程序太长了,没时间去逐句排查;
一般数据读取不到,应该是协议解析错误;
不同GPS模块协议有所不同,仔细看看协议吧。
回复

使用道具 举报

板凳
ID:408809 发表于 2020-1-3 11:47 | 只看该作者
51hei**1140 发表于 2020-1-2 12:11
你好!
你这个程序太长了,没时间去逐句排查;
一般数据读取不到,应该是协议解析错误;

我基础差,是排查不了啦。谢谢你!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表