您的位置:首页 > 编程语言

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

2014-04-29 14:25 1046 查看
这里将我写的STC12C5A60S2单片机控制数字光照强度模块GY-30(主芯片BH1750FVI)的程序共享一下,是为了让前辈给予斧正。
更新:
2014/04/29 14:05
(补充:以下代码只需要修改.h文件中含有 “选择” 字样的部分,就可以达到复用的效果)

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

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







测试程序:

#include <reg52.h>
#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 <reg52.h>
#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__*/


/*################[b]BH1750FVI.h end
################*/[/b]


/*################[b]BH1750FVI.c start
################*/[/b]

/***************************************************************************
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	:yangrui90s@163.com

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 <intrins.h>
#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();
}


/*################[b]BH1750FVI.c end################*/[/b]

补充: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__*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: