• 毕昇杯模块之光照强度传感器


    前面介绍了AMD2302这个温度传感器,这里在介绍项目中使用的另外一个传感器

    好像数字光电模块BH1750是所有模块中唯一没有坏过的模块,这点我比较欣慰,

    BH1750采用的也是I2C协议,比较简单,这个模块使用起来,是一个比较让人放心的传感器,下面晒出模块提供的源代码

    //***************************************
    // BH1750FVI IIC测试程序
    // 使用单片机STC89C51 
    // 晶振:11.0592M
    // 显示:LCD1602
    // 编译环境 Keil uVision2
    // 参考宏晶网站24c04通信程序
    // 时间:2011年4月20日
    //****************************************
    #include  <REG51.H>    
    #include  <math.h>    //Keil library  
    #include  <stdio.h>   //Keil library    
    #include  <INTRINS.H>
    #define   uchar unsigned char
    #define   uint unsigned int    
    #define   DataPort P0     //LCD1602数据端口
    sbit      SCL=P1^0;      //IIC时钟引脚定义
    sbit        SDA=P1^1;      //IIC数据引脚定义
    sbit      LCM_RS=P2^0;   //LCD1602命令端口        
    sbit      LCM_RW=P2^1;   //LCD1602命令端口        
    sbit      LCM_EN=P2^2;   //LCD1602命令端口 
    
    #define      SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                                  //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
    typedef   unsigned char BYTE;
    typedef   unsigned short WORD;
    
    BYTE    BUF[8];                         //接收数据缓存区          
    uchar   ge,shi,bai,qian,wan;            //显示变量
    int     dis_data;                       //变量
    
    void delay_nms(unsigned int k);
    void InitLcd();
    void Init_BH1750(void);
    
    void WriteDataLCM(uchar dataW);
    void WriteCommandLCM(uchar CMD,uchar Attribc);
    void DisplayOneChar(uchar X,uchar Y,uchar DData);
    void conversion(uint temp_data);
    
    void  Single_Write_BH1750(uchar REG_Address);               //单个写入数据
    uchar Single_Read_BH1750(uchar REG_Address);                //单个读取内部寄存器数据
    void  Multiple_Read_BH1750();                               //连续的读取内部寄存器数据
    //------------------------------------
    void Delay5us();
    void Delay5ms();
    void BH1750_Start();                    //起始信号
    void BH1750_Stop();                     //停止信号
    void BH1750_SendACK(bit ack);           //应答ACK
    bit  BH1750_RecvACK();                  //读ack
    void BH1750_SendByte(BYTE dat);         //IIC单个字节写
    BYTE BH1750_RecvByte();                 //IIC单个字节读
    
    //-----------------------------------
    
    //*********************************************************
    void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
    {  
        wan=temp_data/10000+0x30 ;
        temp_data=temp_data%10000;   //取余运算
        qian=temp_data/1000+0x30 ;
        temp_data=temp_data%1000;    //取余运算
        bai=temp_data/100+0x30   ;
        temp_data=temp_data%100;     //取余运算
        shi=temp_data/10+0x30    ;
        temp_data=temp_data%10;      //取余运算
        ge=temp_data+0x30;     
    }
    
    //毫秒延时**************************
    void delay_nms(unsigned int k)    
    {                        
    unsigned int i,j;                
    for(i=0;i<k;i++)
    {            
    for(j=0;j<121;j++)            
    {;}}                        
    }
    
    /*******************************/
    void WaitForEnable(void)    
    {                    
    DataPort=0xff;        
    LCM_RS=0;LCM_RW=1;_nop_();
    LCM_EN=1;_nop_();_nop_();
    while(DataPort&0x80);    
    LCM_EN=0;                
    }                    
    /*******************************/
    void WriteCommandLCM(uchar CMD,uchar Attribc)
    {                    
    if(Attribc)WaitForEnable();    
    LCM_RS=0;LCM_RW=0;_nop_();
    DataPort=CMD;_nop_();    
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
    }                    
    /*******************************/
    void WriteDataLCM(uchar dataW)
    {                    
    WaitForEnable();        
    LCM_RS=1;LCM_RW=0;_nop_();
    DataPort=dataW;_nop_();    
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
    }        
    /***********************************/
    void InitLcd()                
    {            
    WriteCommandLCM(0x38,1);    
    WriteCommandLCM(0x08,1);    
    WriteCommandLCM(0x01,1);    
    WriteCommandLCM(0x06,1);    
    WriteCommandLCM(0x0c,1);
    }            
    /***********************************/
    void DisplayOneChar(uchar X,uchar Y,uchar DData)
    {                        
    Y&=1;                        
    X&=15;                        
    if(Y)X|=0x40;                    
    X|=0x80;            
    WriteCommandLCM(X,0);        
    WriteDataLCM(DData);        
    }                        
    
    /**************************************
    延时5微秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数,注意时钟过快时需要修改
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5us()
    {
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
    }
    
    /**************************************
    延时5毫秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5ms()
    {
        WORD n = 560;
    
        while (n--);
    }
    
    /**************************************
    起始信号
    **************************************/
    void BH1750_Start()
    {
        SDA = 1;                    //拉高数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 0;                    //产生下降沿
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
    }
    
    /**************************************
    停止信号
    **************************************/
    void BH1750_Stop()
    {
        SDA = 0;                    //拉低数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 1;                    //产生上升沿
        Delay5us();                 //延时
    }
    
    /**************************************
    发送应答信号
    入口参数:ack (0:ACK 1:NAK)
    **************************************/
    void BH1750_SendACK(bit ack)
    {
        SDA = ack;                  //写应答信号
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    }
    
    /**************************************
    接收应答信号
    **************************************/
    bit BH1750_RecvACK()
    {
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        CY = SDA;                   //读应答信号
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    
        return CY;
    }
    
    /**************************************
    向IIC总线发送一个字节数据
    **************************************/
    void BH1750_SendByte(BYTE dat)
    {
        BYTE i;
    
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;              //移出数据的最高位
            SDA = CY;               //送数据口
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        BH1750_RecvACK();
    }
    
    /**************************************
    从IIC总线接收一个字节数据
    **************************************/
    BYTE BH1750_RecvByte()
    {
        BYTE i;
        BYTE dat = 0;
    
        SDA = 1;                    //使能内部上拉,准备读取数据,
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            dat |= SDA;             //读数据               
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        return dat;
    }
    
    //*********************************
    
    void Single_Write_BH1750(uchar REG_Address)
    {
        BH1750_Start();                  //起始信号
        BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
        BH1750_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页 
      //  BH1750_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页 
        BH1750_Stop();                   //发送停止信号
    }
    
    //********单字节读取*****************************************
    /*
    uchar Single_Read_BH1750(uchar REG_Address)
    {  uchar REG_data;
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress);           //发送设备地址+写信号
        BH1750_SendByte(REG_Address);                   //发送存储单元地址,从0开始    
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        REG_data=BH1750_RecvByte();              //读出寄存器数据
        BH1750_SendACK(1);   
        BH1750_Stop();                           //停止信号
        return REG_data; 
    }
    */
    //*********************************************************
    //
    //连续读出BH1750内部数据
    //
    //*********************************************************
    void Multiple_read_BH1750(void)
    {   uchar i;    
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        
         for (i=0; i<3; i++)                      //连续读取6个地址数据,存储中BUF
        {
            BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
            if (i == 3)
            {
    
               BH1750_SendACK(1);                //最后一个数据需要回NOACK
            }
            else
            {        
              BH1750_SendACK(0);                //回应ACK
           }
       }
    
        BH1750_Stop();                          //停止信号
        Delay5ms();
    }
    
    
    //初始化BH1750,根据需要请参考pdf进行修改****
    void Init_BH1750()
    {
       Single_Write_BH1750(0x01);  
    
    }
    //*********************************************************
    //主程序********
    //*********************************************************
    void main()
    {  
       float temp;
       delay_nms(200);        //延时200ms    
       InitLcd();           //初始化LCD
       Init_BH1750();       //初始化BH1750
     
      while(1)              //循环
      { 
    
        Single_Write_BH1750(0x01);   // power on
        Single_Write_BH1750(0x10);   // H- resolution mode
    
         delay_nms(180);              //延时180ms
    
        Multiple_Read_BH1750();       //连续读出数据,存储在BUF中
    
        dis_data=BUF[0];
        dis_data=(dis_data<<8)+BUF[1];//合成数据 
        
        temp=(float)dis_data/1.2;
    
        conversion(temp);         //计算数据和显示
        DisplayOneChar(0,0,'L'); 
        DisplayOneChar(1,0,'i'); 
        DisplayOneChar(2,0,'g'); 
        DisplayOneChar(3,0,'h'); 
        DisplayOneChar(4,0,'t'); 
        DisplayOneChar(5,0,':'); 
    
        DisplayOneChar(7,0,wan); //显示数据
        DisplayOneChar(8,0,qian);  
        DisplayOneChar(9,0,bai); 
        DisplayOneChar(10,0,shi); 
        DisplayOneChar(11,0,ge); 
    
        DisplayOneChar(13,0,'l'); ////显示数单位
        DisplayOneChar(14,0,'x');  
                
      }
    } 
    View Code

    模块的源代码也提供串口调试的功能,可见串口调试在整个传感器家族中所占的地位,这个模块占用的I/O口的资源比较少,用起来也比较方便

    下面看一下这个东西如何整合到大程序中去的

    STC_BH1750.c

    //***************************************
    // BH1750FVI IIC测试程序
    // 使用单片机STC89C51 
    // 晶振:11.0592M
    // 显示:LCD1602
    // 编译环境 Keil uVision2
    // 参考宏晶网站24c04通信程序
    // 时间:2011年4月20日
    //****************************************
    #include  <REG51.H>    
    #include  <math.h>    //Keil library  
    #include  <stdio.h>   //Keil library    
    #include  <INTRINS.H>
    #include "main.h"
    #include "BH1750.h" 
    
    sbit      SCL=P1^5;      //IIC时钟引脚定义
    sbit        SDA=P1^6;      //IIC数据引脚定义
    
    #define      SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                                  //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
    
    BYTE    BUF[8];                         //接收数据缓存区          
    extern  uchar table[5];            //显示变量
    int     dis_data;                       //变量
    
    
    
    //-----------------------------------
    
    //*********************************************************
    void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
    {  
        table[0]=temp_data/10000+0x30 ;
        temp_data=temp_data%10000;   //取余运算
        table[1]=temp_data/1000+0x30 ;
        temp_data=temp_data%1000;    //取余运算
        table[2]=temp_data/100+0x30   ;
        temp_data=temp_data%100;     //取余运算
        table[3]=temp_data/10+0x30    ;
        temp_data=temp_data%10;      //取余运算
        table[4]=temp_data+0x30; 
    
        
    }
    
    //毫秒延时**************************
    void delay_nms(unsigned int k)    
    {                        
    unsigned int i,j;                
    for(i=0;i<k;i++)
    {            
    for(j=0;j<121;j++)            
    {;}}                        
    }
                                                
    
    /**************************************
    延时5微秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数,注意时钟过快时需要修改
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5us()
    {
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
    }
    
    /**************************************
    延时5毫秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5ms()
    {
        WORD n = 560;
    
        while (n--);
    }
    
    /**************************************
    起始信号
    **************************************/
    void BH1750_Start()
    {
        SDA = 1;                    //拉高数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 0;                    //产生下降沿
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
    }
    
    /**************************************
    停止信号
    **************************************/
    void BH1750_Stop()
    {
        SDA = 0;                    //拉低数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 1;                    //产生上升沿
        Delay5us();                 //延时
    }
    
    /**************************************
    发送应答信号
    入口参数:ack (0:ACK 1:NAK)
    **************************************/
    void BH1750_SendACK(bit ack)
    {
        SDA = ack;                  //写应答信号
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    }
    
    /**************************************
    接收应答信号
    **************************************/
    bit BH1750_RecvACK()
    {
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        CY = SDA;                   //读应答信号
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    
        return CY;
    }
    
    /**************************************
    向IIC总线发送一个字节数据
    **************************************/
    void BH1750_SendByte(BYTE dat)
    {
        BYTE i;
    
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;              //移出数据的最高位
            SDA = CY;               //送数据口
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        BH1750_RecvACK();
    }
    
    /**************************************
    从IIC总线接收一个字节数据
    **************************************/
    BYTE BH1750_RecvByte()
    {
        BYTE i;
        BYTE dat = 0;
    
        SDA = 1;                    //使能内部上拉,准备读取数据,
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            dat |= SDA;             //读数据               
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        return dat;
    }
    
    //*********************************
    
    void Single_Write_BH1750(uchar REG_Address)
    {
        BH1750_Start();                  //起始信号
        BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
        BH1750_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页 
      //  BH1750_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页 
        BH1750_Stop();                   //发送停止信号
    }
    
    //********单字节读取*****************************************
    /*
    uchar Single_Read_BH1750(uchar REG_Address)
    {  uchar REG_data;
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress);           //发送设备地址+写信号
        BH1750_SendByte(REG_Address);                   //发送存储单元地址,从0开始    
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        REG_data=BH1750_RecvByte();              //读出寄存器数据
        BH1750_SendACK(1);   
        BH1750_Stop();                           //停止信号
        return REG_data; 
    }
    */
    //*********************************************************
    //
    //连续读出BH1750内部数据
    //
    //*********************************************************
    void Multiple_read_BH1750(void)
    {   uchar i;    
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        
         for (i=0; i<3; i++)                      //连续读取6个地址数据,存储中BUF
        {
            BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
            if (i == 3)
            {
    
               BH1750_SendACK(1);                //最后一个数据需要回NOACK
            }
            else
            {        
              BH1750_SendACK(0);                //回应ACK
           }
       }
    
        BH1750_Stop();                          //停止信号
        Delay5ms();
    }
    
    
    //初始化BH1750,根据需要请参考pdf进行修改****
    void Init_BH1750()
    {
       Single_Write_BH1750(0x01);  
    
    }
    //*********************************************************
    //主程序********
    //*********************************************************
    void gzqd()
    {  
        float temp;
        delay_nms(200);        //延时200ms    
        Init_BH1750();       //初始化BH1750
        Single_Write_BH1750(0x01);   // power on
        Single_Write_BH1750(0x10);   // H- resolution mode
    
        delay_nms(180);              //延时180ms
    
        Multiple_Read_BH1750();       //连续读出数据,存储在BUF中
    
        dis_data=BUF[0];
        dis_data=(dis_data<<8)+BUF[1];//合成数据 
        
        temp=(float)dis_data/1.2;
    
        conversion(temp);         //计算数据和显示   
    } 
    View Code

    STC_BH1750.h

    #ifndef __BH1750_H__
    #define __BH1750_H__
    #include"main.h"
    #define   uchar unsigned char
    #define   uint unsigned int
    typedef   unsigned char BYTE;
    typedef   unsigned short WORD;    
     
    void delay_nms(unsigned int k);
    
    void Init_BH1750(void);
    
    void conversion(uint temp_data);
    
    
    void  Single_Write_BH1750(uchar REG_Address);               //单个写入数据
    
    uchar Single_Read_BH1750(uchar REG_Address);                //单个读取内部寄存器数据
    
    void  Multiple_Read_BH1750();                               //连续的读取内部寄存器数据
    //------------------------------------
    void Delay5us();
    void Delay5ms();
    void BH1750_Start();                    //起始信号
    void BH1750_Stop();                     //停止信号
    void BH1750_SendACK(bit ack);           //应答ACK
    bit  BH1750_RecvACK();                  //读ack
    void BH1750_SendByte(BYTE dat);         //IIC单个字节写
    BYTE BH1750_RecvByte();                 //IIC单个字节读
    
    void gzqd();
    
    #endif
    View Code

    从STC_BH1750.c这个文件中可以看出,我们新建了一个函数gzqd(),调用这个函数就可以对关照进行测量了,到的光照强度,关照强度存放在全局变量table[]中

    具体的模块资料可以在这里进行下载:http://download.csdn.net/detail/generoius/7142251

    版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3643409.html

    技术QQ1070937053

  • 相关阅读:
    出现System.web.mvc冲突的原因及解决方法CS0433
    看完此文还不懂NB-IoT,你就过来掐死我吧...
    html5调用手机陀螺仪实现方向辨识
    黑盒测试和白盒测试的区别
    CentOS7 下 keepalived 的安装和配置
    centos 下 mysql+keepalived实现双主自由切换
    MySQL 高可用性—keepalived+mysql双主(有详细步骤和全部配置项解释)
    备份VMware虚拟磁盘文件 移植到其他虚拟机
    Centos7 Mysql 双机热备实现数据库高可用
    CentOS7配置Mysql热备份
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3643409.html
Copyright © 2020-2023  润新知