找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机实现大气压传感器GY68测量程序

[复制链接]
跳转到指定楼层
楼主
51单片机实现大气压传感器GY68测量程序


单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <math.h>    //Keil library
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define        BMP085_SlaveAddress   0xee          //定义器件在IIC总线中的从地址                              

  7. #define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)
  8.                                                           
  9. typedef unsigned char  BYTE;
  10. typedef unsigned short WORD;

  11. sbit duoji = P1^2;
  12. sbit lcden = P2^1;
  13. sbit rs = P2^2;
  14. sbit key_1 = P3^4;
  15. sbit key_2 = P3^5;
  16. sbit key_3 = P3^6;
  17. sbit key_4 = P3^7;
  18. sbit SCL=P1^0;      //IIC时钟引脚定义
  19. sbit SDA=P1^1;      //IIC数据引脚定义
  20. uchar count3;
  21. uchar ge,shi,bai,qian,wan,shiwan;           //显示变量
  22. int  dis_data;
  23. short ac1;
  24. short ac2;
  25. short ac3;
  26. unsigned short ac4;
  27. unsigned short ac5;
  28. unsigned short ac6;
  29. short b1;
  30. short b2;
  31. short mb;
  32. short mc;
  33. short md;

  34. uchar code table1[]="Pressure:    HPa";
  35. uchar code table2[]="status: normal  ";
  36. uchar code table3[]="status: abnormal";
  37. uchar code table4[]="MQ7:      T:    ";
  38. uchar code table5[]="Revise success!!";
  39. uchar code table6[]="  Revise  Menu  ";

  40. void LCD_DISPLAY(uchar num); //LCD显示

  41. void delay(uint z) //毫秒延时
  42. {
  43.         uint x,y;
  44.         for(x=z;x>0;x--)
  45.         for(y=110;y>0;y--);
  46. }



  47. //****************************LCD1602的初始化*******************************
  48. /**************************************************************************/


  49. void write_com(uchar com)//LCD写字节
  50. {         
  51.         rs=0;
  52.         lcden=0;
  53.         P0=com;
  54.         delay(5);
  55.         lcden=1;
  56.         delay(5);
  57.         lcden=0;        
  58. }
  59.                
  60. void write_date(uchar date)//LCD读字节
  61. {        
  62.         rs=1;
  63.         lcden=0;
  64.         P0=date;
  65.         delay(5);
  66.         lcden=1;
  67.         delay(5);
  68.         lcden=0;        
  69. }

  70. void lcd_sfm(uchar add,int date)//显示位置和数字
  71. {
  72.         uchar qian,bai,shi,ge;
  73.         qian = date/1000;
  74.         bai  = date%1000/100;
  75.         shi  = date%100/10;
  76.         ge   = date%10;
  77.         write_com(0x80+add);
  78.         write_date(0x30+qian);
  79.         write_date(0x30+bai);
  80.         write_date(0x30+shi);
  81.         write_date(0x30+ge);
  82. }

  83. void SetCurPosition(uchar X, uchar Y)//设置光标
  84. {
  85.         Y &= 0x01;
  86.         X &= 0x0F; // 限制X不能大于15,Y不能大于1
  87.         if (Y)
  88.         {
  89.           X |= 0xc0; // 当要显示第二行时地址码:0xc0
  90.         }
  91.         X |= 0x80; // 第一行的地址码:0x80
  92.         write_com(X); // 这里不检测忙信号,发送地址码
  93.         //write_com(0x02); //光标归位
  94.         write_com(0x0f); //关光标,闪烁
  95.        
  96. }

  97. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  98. {                                               
  99.         Y&=1;                                               
  100.         X&=15;                                               
  101.         if(Y)X|=0x40;                                       
  102.         X|=0x80;                       
  103.         write_com(X);               
  104.         write_date(DData);
  105.        
  106. }       

  107. void conversion(long temp_data)  
  108. {  
  109.    
  110.     shiwan=temp_data/100000+0x30 ;
  111.     temp_data=temp_data%100000;   //取余运算
  112.     wan=temp_data/10000+0x30 ;
  113.     temp_data=temp_data%10000;   //取余运算
  114.           qian=temp_data/1000+0x30 ;
  115.     temp_data=temp_data%1000;    //取余运算
  116.     bai=temp_data/100+0x30   ;
  117.     temp_data=temp_data%100;     //取余运算
  118.     shi=temp_data/10+0x30    ;
  119.     temp_data=temp_data%10;      //取余运算
  120.     ge=temp_data+0x30;        
  121. }

  122. /**********************************************************************************************
  123. **                              BMP180初始化及测试函数
  124. **********************************************************************************************/
  125. void Delay5us()
  126. {
  127.     _nop_();_nop_();_nop_();_nop_();
  128.     _nop_();_nop_();_nop_();_nop_();
  129.         _nop_();_nop_();_nop_();_nop_();
  130.         _nop_();_nop_();_nop_();_nop_();
  131. }

  132. /**************************************
  133. 延时5毫秒(STC90C52RC@12M)
  134. 不同的工作环境,需要调整此函数
  135. 当改用1T的MCU时,请调整此延时函数
  136. **************************************/
  137. void Delay5ms()
  138. {
  139.     WORD n = 560;

  140.     while (n--);
  141. }

  142. /**************************************
  143. 起始信号
  144. **************************************/
  145. void BMP085_Start()
  146. {
  147.     SDA = 1;                    //拉高数据线
  148.     SCL = 1;                    //拉高时钟线
  149.     Delay5us();                 //延时
  150.     SDA = 0;                    //产生下降沿
  151.     Delay5us();                 //延时
  152.     SCL = 0;                    //拉低时钟线
  153. }

  154. /**************************************
  155. 停止信号
  156. **************************************/
  157. void BMP085_Stop()
  158. {
  159.     SDA = 0;                    //拉低数据线
  160.     SCL = 1;                    //拉高时钟线
  161.     Delay5us();                 //延时
  162.     SDA = 1;                    //产生上升沿
  163.     Delay5us();                 //延时
  164. }

  165. /**************************************
  166. 发送应答信号
  167. 入口参数:ack (0:ACK 1:NAK)
  168. **************************************/
  169. void BMP085_SendACK(bit ack)
  170. {
  171.     SDA = ack;                  //写应答信号
  172.     SCL = 1;                    //拉高时钟线
  173.     Delay5us();                 //延时
  174.     SCL = 0;                    //拉低时钟线
  175.     Delay5us();                 //延时
  176. }

  177. /**************************************
  178. 接收应答信号
  179. **************************************/
  180. bit BMP085_RecvACK()
  181. {
  182.     SCL = 1;                    //拉高时钟线
  183.     Delay5us();                 //延时
  184.     CY = SDA;                   //读应答信号
  185.     SCL = 0;                    //拉低时钟线
  186.     Delay5us();                 //延时

  187.     return CY;
  188. }

  189. /**************************************
  190. 向IIC总线发送一个字节数据
  191. **************************************/
  192. void BMP085_SendByte(BYTE dat)
  193. {
  194.     BYTE i;

  195.     for (i=0; i<8; i++)         //8位计数器
  196.     {
  197.         dat <<= 1;              //移出数据的最高位
  198.         SDA = CY;               //送数据口
  199.         SCL = 1;                //拉高时钟线
  200.         Delay5us();             //延时
  201.         SCL = 0;                //拉低时钟线
  202.         Delay5us();             //延时
  203.     }
  204.     BMP085_RecvACK();
  205. }

  206. /**************************************
  207. 从IIC总线接收一个字节数据
  208. **************************************/
  209. BYTE BMP085_RecvByte()
  210. {
  211.     BYTE i;
  212.     BYTE dat = 0;

  213.     SDA = 1;                    //使能内部上拉,准备读取数据,
  214.     for (i=0; i<8; i++)         //8位计数器
  215.     {
  216.         dat <<= 1;
  217.         SCL = 1;                //拉高时钟线
  218.         Delay5us();             //延时
  219.         dat |= SDA;             //读数据               
  220.         SCL = 0;                //拉低时钟线
  221.         Delay5us();             //延时
  222.     }
  223.     return dat;
  224. }

  225. //*********************************************************
  226. //读出BMP085内部数据,连续两个
  227. //*********************************************************
  228. short Multiple_read(uchar ST_Address)
  229. {   
  230.         uchar msb, lsb;
  231.         short _data;
  232.     BMP085_Start();                          //起始信号
  233.     BMP085_SendByte(BMP085_SlaveAddress);    //发送设备地址+写信号
  234.     BMP085_SendByte(ST_Address);             //发送存储单元地址
  235.     BMP085_Start();                          //起始信号
  236.     BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号

  237.     msb = BMP085_RecvByte();                 //BUF[0]存储
  238.     BMP085_SendACK(0);                       //回应ACK
  239.     lsb = BMP085_RecvByte();     
  240.         BMP085_SendACK(1);                       //最后一个数据需要回NOACK

  241.     BMP085_Stop();                           //停止信号
  242.     Delay5ms();
  243.     _data = msb << 8;
  244.         _data |= lsb;       
  245.         return _data;
  246. }

  247. //*************************************************************
  248. long bmp085ReadPressure(void)
  249. {
  250.         long pressure = 0;

  251.     BMP085_Start();                   //起始信号
  252.     BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
  253.     BMP085_SendByte(0xF4);                  // write register address
  254.     BMP085_SendByte(0x34);                 // write register data for pressure
  255.     BMP085_Stop();                    //发送停止信号
  256.         delay(10);                              // max time is 4.5ms
  257.        
  258.         pressure = Multiple_read(0xF6);
  259.         pressure &= 0x0000FFFF;
  260.        
  261.         return pressure;       
  262.         //return (long) bmp085ReadShort(0xF6);
  263. }

  264. //**************************************************************

  265. //初始化BMP085,根据需要请参考pdf进行修改**************
  266. void Init_BMP085()
  267. {
  268.         ac1 = Multiple_read(0xAA);
  269.         ac2 = Multiple_read(0xAC);
  270.         ac3 = Multiple_read(0xAE);
  271.         ac4 = Multiple_read(0xB0);
  272.         ac5 = Multiple_read(0xB2);
  273.         ac6 = Multiple_read(0xB4);
  274.         b1 =  Multiple_read(0xB6);
  275.         b2 =  Multiple_read(0xB8);
  276.         mb =  Multiple_read(0xBA);
  277.         mc =  Multiple_read(0xBC);
  278.         md =  Multiple_read(0xBE);
  279. }

  280. //***********************************************************************
  281. void bmp085Convert()//bmp180转换
  282. {
  283.         long up;
  284.         long x1, x2, b5, b6, x3, b3, p;
  285.         unsigned long b4, b7;
  286.         long  pressure;
  287.         float temp;
  288.         int pressure_int;

  289.         up = bmp085ReadPressure();
  290.         up = bmp085ReadPressure();  // 读取压强
  291.        
  292.   //*************
  293.        
  294.         b6 = b5 - 4000;
  295.         x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  296.         x2 = ac2 * b6 >> 11;
  297.         x3 = x1 + x2;
  298.         b3 = (((long)ac1 * 4 + x3) + 2)/4;
  299.         x1 = ac3 * b6 >> 13;
  300.         x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  301.         x3 = ((x1 + x2) + 2) >> 2;
  302.         b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
  303.         b7 = ((unsigned long) up - b3) * (50000 >> OSS);
  304.         if( b7 < 0x80000000)
  305.              p = (b7 * 2) / b4 ;
  306.            else  
  307.                     p = (b7 / b4) * 2;
  308.         x1 = (p >> 8) * (p >> 8);
  309.         x1 = (x1 * 3038) >> 16;
  310.         x2 = (-7357 * p) >> 16;
  311.         pressure = p + ((x1 + x2 + 3791) >> 4);
  312.         temp = (float)pressure / 100.0 + 0.5;//转换为百帕 并四舍五入
  313.         pressure_int = (int)temp; //强制转换
  314.         lcd_sfm(0x09,pressure_int);//显示
  315.                                          
  316. }


  317. void init()
  318. {
  319.         lcden=0;   
  320.         write_com(0x38);                                        //打开显示模式设置
  321.         write_com(0x0c);                                        //打开显示,光标等等设置未零
  322.         write_com(0x06);                                        //当读或写一个字符后地址指针加一,且光标加一,当写一个字符后整频显示左移,
  323.         write_com(0x01);                                        //清零指令
  324.         write_com(0x80);   
  325.        
  326.         TMOD = 0x01;
  327.         TH0 = (65536-100)/256;//100us进入一次中断
  328.         TL0 = (65536-100)%256;
  329.         TR0 = 1;
  330.         ET0 = 1;
  331.         EA = 0;//开启总中断
  332.        
  333. }

  334. /**********************************************************************************************
  335. **                              TIMER0中断服务子函数产生PWM
  336. **********************************************************************************************/
  337. uchar count = 0;
  338. uchar pwm = 15;
  339. void timer0()interrupt 1   using 0
  340. {       
  341.         TH0 = (65536-100)/256;
  342.         TL0 = (65536-100)%256;
  343.         count++;
  344.         if(count >= 200)
  345.         {
  346.                 count = 0;
  347.         }
  348.         if(count <= pwm) duoji = 1;
  349.         else             duoji = 0;
  350.        
  351. }

  352. /**********************************************************************************************
  353. **                                                              主函数
  354. **********************************************************************************************/
  355. int max_pressure = 910;//大气压阈值

  356. void main()
  357. {
  358.   delay(100);//开机延时
  359.         init();//初始化
  360.         Init_BMP085();//BMP初始化
  361.         //lcd_sfm(0x05,666);
  362.         LCD_DISPLAY(1);
  363.         LCD_DISPLAY(2);
  364.         while(1)
  365.         {
  366.                 bmp085Convert();
  367.                 delay(1000);
  368.         }
  369. }

  370. /********************************************************************************************
  371. *                                                                                                                                   LCD显示函数
  372. ********************************************************************************************/
  373. void LCD_DISPLAY(uchar num) //LCD显示
  374. {      
  375.         if(num == 1)
  376.         {
  377.                 //write_com(0x01);
  378.                 write_com(0x80);
  379.                 for(count3=0;count3<16;count3++)
  380.                 {
  381.                         write_date(table1[count3]);        //
  382.                         delay(5);
  383.                 }
  384.   }
  385.         if(num == 2)
  386. ……………………

  387. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
test.zip (62.13 KB, 下载次数: 26)

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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