单片机控制数字光照强度传感模块GY-30(主芯片BH1750FVI)之模块化编程(持续更新中)

这里将我写的STC12C5A60S2单片机控制数字光照强度模块GY-30(主芯片BH1750FVI)的程序共享一下,是为了让前辈给予斧正。

更新:

2014/04/29 14:05

(补充:以下代码只需要修改.h文件中含有 “选择” 字样的部分,就可以达到复用的效果)

对于串口调试部分,请参考《单片机程序协助调试方法(一)串口调试点击进入

对于BH1750FVI有6种工作模式,文章中选用的模式为 Continuously H-Resolution Mode

单片机控制数字光照强度传感模块GY-30(主芯片BH1750FVI)之模块化编程(持续更新中)_第1张图片

单片机控制数字光照强度传感模块GY-30(主芯片BH1750FVI)之模块化编程(持续更新中)_第2张图片

单片机控制数字光照强度传感模块GY-30(主芯片BH1750FVI)之模块化编程(持续更新中)_第3张图片


测试程序:

#include 
#include "BH1750FVI.h"
#include "uart.h"

void main()
{  
	UartInit() ;
	BH1750FVIInit();      
	while(1)              
	{ 
		UartSendValue("Ambient Light Value  (lx): ", BH1750FVIReadResult() );         
	}
} 




/*################BH1750FVI.h start ################*/

#ifndef __BH1750FVI_H__
#define __BH1750FVI_H__

#include 
#include "common.h"

sbit  BH1750FVI_sclk_bit=P2^0;      /*根据硬件选择*/
sbit  BH1750FVI_sda_bit=P2^1;       /*根据硬件选择*/ 

#define   BH1750FVI_ADDRESS_ON_ADD_LOW_LEVEL  0x46
#define   BH1750FVI_ADDRESS_ON_ADD_HIGH_LEVEL 0Xb8


/*注意:这里当ADD引脚接VCC时选择BH1750FVI_ADDRESS_ON_ADD_HIGH_LEVEL,
           当ADD引脚接GND时选择BH1750FVI_ADDRESS_ON_ADD_LOW_LEVEL。
           在实验室,我接了GND,所以选择了BH1750FVI_ADDRESS_ON_ADD_LOW_LEVEL

           根据硬件连接选择*/
#define	  BH1750FVI_ADDRESS   BH1750FVI_ADDRESS_ON_ADD_LOW_LEVEL

#define BH1750FVI_READ	 0x01
#define BH1750FVI_WRITE	 (0x01 & (~(0x01<<0)))


//命令 (参照datasheet)
#define BH1750FVI_POWER_DOWM	0x00
#define BH1750FVI_POWER_ON 		0x01
#define BH1750FVI_RESET			0x07
#define BH1750FVI_CONTINUOUSLY_H_RESOLUTION_MODE 	0x10
#define BH1750FVI_CONTINUOUSLY_H_RESOLUTION_MODE2	0x11
#define BH1750FVI_CONTINUOUSLY_L_RESOLUTION_MODE    0x13
#define BH1750FVI_ONE_TIME_H_RESOLUTION_MODE		0x20
#define BH1750FVI_ONE_TIME_H_RESOLUTION_MODE2		0X21
#define BH1750FVI_ONE_TIME_L_RESOLUTION_MODE		0x23



/*****************外部接口函数******************/
//初始化,上电,模式选择
extern void BH1750FVIInit() ;

//读取结果
extern UW16 BH1750FVIReadResult(void) ;

//写命令
extern void BH1750FVIWriteCommand(UB8 command) ;
/**********************************************/

							
#endif /*__BH1750FVI_H__*/


/*################BH1750FVI.h end ################*/


/*################BH1750FVI.c start ################*/

/***************************************************************************
Module	:BH1750FVI.c

Purpose	:Implementation of BH1750FVI module.(数字光照强度模块GY-30)

Version	:0.01							2014/02/03 12:00(OK)

Complier:Keil 8051 C complier V9.01

MCU		:STC12C5A60S2

Author	:yangrui

QQ		:279729201

Email	:[email protected]


Modification:
=================
	2014/04/29 14:35
	Reason:
		1.这里采用的工作方式为 Continuously H-Resolution Mode,即连续高分辨率模式。
		除此之外,还有其他工作模式,关于6中工作模式总结如下:
		Continuously H-Resolution Mode  ;(at 1LX resolution,Measurement Time is  typically 120ms)
		
		Continuously H-Resolution Mode2 ;(at 0.5LX resolution,Measurement Time is  typically 120ms)
		
		Continuously L-Resolution Mode  ;(at 4LX resolution,Measurement Time is  typically 16ms)
		
		One Time H-Resolution Mode      ;(at 1LX resolution,Measurement Time is  typically 120ms,
										  It is autionmatically set to power dowm mode after measurement,
										  so if want to read ,you shoule set "power on")
		
		One Time H-Resolution Mode      ;(at 0.5LX resolution,Measurement Time is  typically 120ms,
										  It is autionmatically set to power dowm mode after measurement,
										  so if want to read ,you shoule set "power on")
		
		One Time L-Resolution Mode      ;(at 4LX resolution,Measurement Time is  typically 16ms,
										  It is autionmatically set to power dowm mode after measurement,
										  so if want to read ,you shoule set "power on")


		2.BH1750FVI在内部地址写数据和其他IIC器件稍有不同,其他IIC器件在传输器件地址后,还需要传输器件内部
		  地址,但是BH1750FVI写数据时,写的是命令,所以不需要内部器件地址,所以将函数直接命名成了
		  BH1750FVIWriteCommand(...),这里的代码由我的的at24c02.c演化而来,如果在工程中有很多IIC器件,
		  想把IIC通信协议封装起来,一定要注意这个细节。

=================



***************************************************************************/

#include 
#include "BH1750FVI.h"

/*外部接口函数在BH1750FVI.h中声明*/

/*****************内部函数******************/
//static void delay5usForBH1750FVI(void) ;
static void delay180msForBH1750FVI(void) ;
static void BH1750FVIStartSignal(void) ;
static void BH1750FVIStopSignal(void) ;
static void BH1750FVIFreeBus(void) ;
static void BH1750FVIAcknowledge(void) ;
static void mcuAcknowledge(void) ;
static void BH1750FVIWriteByte(UB8 dat) ;
static UB8 BH1750FVIReadByte() ;
static void BH1750FVIPowerOn(void) ;

/**********************************************/

///******************************************************
//Function	:delay5usForBH1750FVI
//Input		:N/A
//Output		:N/A
//Return		:N/A
//Description	:N/A
//Note		:由STC-ISP V6.69软件针对相应MCU生成,若MCU不同
//			最好也要修改此函数。
//******************************************************/
//static void delay5usForBH1750FVI(void)		//@11.0592MHz
//{
//	unsigned char i;
//
//	_nop_();
//	_nop_();
//	_nop_();
//	i = 10;
//	while (--i);
//}

/******************************************************
Function	:delay180msForBH1750FVI
Input		:N/A
Output		:N/A
Return		:N/A
Description	:N/A
Note		:由STC-ISP V6.69软件针对相应MCU生成,若MCU不同
			最好也要修改此函数。
******************************************************/
static void delay180msForBH1750FVI(void)		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 8;
	j = 145;
	k = 99;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


/******************************************************
Function	:BH1750FVIStartSignal
Input		:N/A
Output		:N/A
Return		:N/A
Description	:BH1750FVI start signal
Note		:N/A
******************************************************/
static void BH1750FVIStartSignal(void)
{
	BH1750FVI_sda_bit = HIGH_LEVEL ;
	//_nop_() ;
	BH1750FVI_sclk_bit = HIGH_LEVEL ;
	//_nop_() ;
	BH1750FVI_sda_bit = LOW_LEVEL ;  
	//_nop_(); 
}

/******************************************************
Function	:BH1750FVIStopSignal
Input		:N/A
Output		:N/A
Return		:N/A
Description	:BH1750FVI stop signal
Note		:N/A
******************************************************/
static void BH1750FVIStopSignal(void)
{
	BH1750FVI_sda_bit = LOW_LEVEL ;
	//_nop_() ;
	BH1750FVI_sclk_bit = HIGH_LEVEL ;
	//_nop_() ;
	BH1750FVI_sda_bit = HIGH_LEVEL ;
	//_nop_(); 
}

/******************************************************
Function	:BH1750FVIFreeBus
Input		:N/A
Output		:N/A
Return		:N/A
Description	:释放总线
Note		:N/A
******************************************************/
static void BH1750FVIFreeBus(void)
{
	//free bus
	BH1750FVI_sclk_bit = HIGH_LEVEL ;
	BH1750FVI_sda_bit = HIGH_LEVEL ;
}

/******************************************************
Function	:BH1750FVIAcknowledge
Input		:N/A
Output		:N/A
Return		:N/A
Description	:主机等待BH1750FVI应答
Note		:N/A
******************************************************/
static void BH1750FVIAcknowledge(void)
{
	UB8 i=0 ;

	BH1750FVI_sclk_bit = LOW_LEVEL ;
	//_nop_() ;

	BH1750FVI_sclk_bit = HIGH_LEVEL ;
	//_nop_() ;

	
	while((BH1750FVI_sda_bit) && (i<250))
	{
		i++;//暂时,具体见调试
		//经过测试,这里的250足够大了
	}
	BH1750FVI_sclk_bit = LOW_LEVEL ;
}

/******************************************************
Function	:mcuAcknowledge
Input		:N/A
Output		:N/A
Return		:N/A
Description	:主机作为接收机收到BH1750FVI数据后,发出应答信号
Note		:N/A
******************************************************/
static void mcuAcknowledge(void)
{
	BH1750FVI_sclk_bit = LOW_LEVEL ;
	//_nop_();
	BH1750FVI_sda_bit = LOW_LEVEL ;
	//_nop_();
	BH1750FVI_sclk_bit = HIGH_LEVEL;
}

/******************************************************
Function	:BH1750FVIWriteByte
Input		:dat
Output		:N/A
Return		:N/A
Description	:write byte-data to BH1750FVI
Note		:N/A
******************************************************/
static void BH1750FVIWriteByte(UB8 dat)
{
    UB8 i;

    for (i=0; i<8; i++)        
    {
		BH1750FVI_sclk_bit = LOW_LEVEL ;
		//_nop_();

		//方法一
		BH1750FVI_sda_bit = (bit)(dat & (0x80>>i)) ;

		//方法二
		//temp <<= 1 ;
		//BH1750FVI_sda_bit = CY ;

		//delay5usForBH1750FVI();/*经过测试可以屏蔽*/

		//_nop_();
		BH1750FVI_sclk_bit = HIGH_LEVEL ;
		//_nop_();
        
    } 
}

/******************************************************
Function	:BH1750FVIReadByte
Input		:N/A
Output		:N/A
Return		:byte-data from BH1750FVI
Description	:读取字节数据
Note		:N/A
******************************************************/
static UB8 BH1750FVIReadByte()
{
    	UB8 i ;
	UB8 dataCode = 0x00 ;

	//Ready
	/*Data on sda pin may change during scl low timer period*/
	BH1750FVI_sclk_bit = LOW_LEVEL ;
	//_nop_() ;
	BH1750FVI_sda_bit = HIGH_LEVEL ;
	//_nop_() ;

	for(i=0; i<8 ; i++)
	{
		BH1750FVI_sclk_bit = HIGH_LEVEL ;
		//_nop_() ;
		dataCode<<= 1;
		dataCode |= BH1750FVI_sda_bit ;
		//_nop_() ;
		BH1750FVI_sclk_bit = LOW_LEVEL ;
		//_nop_() ;
	}

	return dataCode ;
}

/******************************************************
Function	:BH1750FVIWriteCommand
Input		:command Code
Output		:N/A
Return		:N/A
Description	:写BH1750FVI内置命令
Note		:N/A
******************************************************/
void BH1750FVIWriteCommand(UB8 command)
{
    BH1750FVIStartSignal();  

    BH1750FVIWriteByte(BH1750FVI_ADDRESS | BH1750FVI_WRITE);   
	BH1750FVIAcknowledge();
    
    BH1750FVIWriteByte(command); 
    BH1750FVIAcknowledge();

    BH1750FVIFreeBus() ;
}

/******************************************************
Function	:BH1750FVIReadResult
Input		:N/A
Output		:N/A
Return		:Ambient Light Value
Description	:读取亮度值
Note		:N/A
******************************************************/
UW16 BH1750FVIReadResult(void)

{   
	UW16 temp ;
	UB8 msb,lsb ;

    BH1750FVIStartSignal();  
    
    BH1750FVIWriteByte(BH1750FVI_ADDRESS | BH1750FVI_READ ) ;
    BH1750FVIAcknowledge();

    msb= BH1750FVIReadByte() ;
    mcuAcknowledge();                
    
    lsb= BH1750FVIReadByte();
    /*后一个字节读取后,主机以结束信号代替应答信号*/
	
    BH1750FVIStopSignal();                         

    BH1750FVIFreeBus() ;

    temp = ((UW16)(msb)) <<8 | lsb ;

    temp = (float)temp/1.2 ;
    /*这里有隐含的类型转换:float -- >  unsigned int */

    return temp ;
}

/******************************************************
Function	:BH1750FVIPowerOn
Input		:N/A
Output		:N/A
Return		:N/A
Description	:"上电"命令
Note		:对于"上电"命令,如果使用"One Time...."模式,
			 在转换结果后,硬件会自动切换到POWER DOWM模式,
			 因此还需要重新使用上电命令,在程序中,我使用了
			 的模式是"Continuously H-Resolution Mode",因此
			 不会自动切换到掉电模式,只需要在初始化时,调用
			 此函数。如果使用其他模式,可能还需要在其他地方调用。
			 并需要根据实际情况封装其他功能。
******************************************************/
static void BH1750FVIPowerOn(void)
{
	BH1750FVIWriteCommand(BH1750FVI_POWER_ON); 	//power on
}

/******************************************************
Function	:Init_BH1750
Input		:N/A
Output		:N/A
Return		:N/A
Description	:初始化
Note		:N/A
******************************************************/
void BH1750FVIInit()
{
   BH1750FVIPowerOn();
   /*模式选择为 Continuously H-Resolution Mode*/
   BH1750FVIWriteCommand(BH1750FVI_CONTINUOUSLY_H_RESOLUTION_MODE); 
   
   delay180msForBH1750FVI();
}


/*################BH1750FVI.c end################*/



补充:common.h

#ifndef __COMMON_H__
#define __COMMON_H__

typedef unsigned char UB8 ;
typedef unsigned short int UW16 ;
typedef unsigned long UL32 ;

typedef char SB8;
typedef short int SW16 ;
typedef long SL32 ;
	
#define HIGH_LEVEL 1	
#define LOW_LEVEL  0


#endif	/*__COMMON_H__*/


你可能感兴趣的:(单片机)