一.光照传感器分析
查看芯片手册,总结GY_30使用注意的几个点:考虑断电通电、单次连续、读取数据时间
1.设置芯片为通电模式、
2.重置数字寄存器值
3.设置连续 H分辨率模式
4.等待一次测量时间max 180ms
5完整过程
- 发送起始信号,发送器件地址与读方向,检测应答。发送高分辨率指令,检测应答,发送结束信号
- 延时等待180ms
- 发送起始信号,发送器件地址与写方向,检测应答。接收高八位,检测应答。接收第八位,检测非应答,发送结束信号
-
/
****
****
****
****
****
**** BH1750初始化函数
****
****
****
****
****
***
-
根据需要参考pdf进行参数修改
-
*****************************************************************/
-
void BH1750_Init(void)
-
{
-
BH1750_Write
_COM(SlaveAddress,0x01); //开电源
-
BH1750_Write
_COM(SlaveAddress,0x07); //重置数字寄存器值
-
BH1750_Write
_COM(SlaveAddress,0x10); //连续模式
-
Delay_ms(180); //等到测量结束
-
}
-
/**
****
****
****
****
****
** BH1750写指令函数 **
****
****
****
****
****
*
-
Dev_Adder:模块IIC通讯地址
-
Common: 需要发送的控制指令
-
******************************************************************/
-
void BH1750_Write_COM(unsigned char Dev_Adder,unsigned char Common)
-
{
-
IIC_Start(); //起始信号
-
IIC_Send_Data(Dev_Adder); //发送从设备地址(从设备地址+读写控制位)
-
if( IIC_Get
_ACK() ) //检测应答
-
{
-
goto WR_End;
-
}
-
IIC_Send_Data(Common); //发送测试指令
-
if( IIC_Get_ACK() ) //检测应答
-
{
-
goto WR_End;
-
}
-
WR_End:
-
IIC_Stop(); //发送结束信号
-
}
-
-
/************************ BH1750读数据函数 ***********************
-
Dev_Adder:模块IIC通讯地址
-
******************************************************************/
-
u16 BH1750_Read_Data(unsigned char Dev_Adder)
-
{
-
unsigned char Buff[2] = {0};
-
u16 Data = 0;
-
IIC_Start(); //起始信号
-
IIC_Send_Data(Dev_Adder | 0x01); //发送从设备地址(从设备地址+读写控制位)
-
if( IIC_Get
_ACK() ) //检测应答
-
{
-
goto WR_End;
-
}
-
/* 读取光照数据 */
-
Buff[0]= IIC_Read_Data(1); //读取高字节光照数据 并发送应答信号
-
Buff[1] = IIC_Read_Data(0); //读取低字节光照数据 并发送非应答信号
-
-
WR_End:
-
IIC_Stop(); //发送结束信号
-
Delay_ms(5);
-
-
/* 合并光强数据 */
-
Data = Buff[0];
-
Data = (Data << 8) | Buff[1]; //合成数据,即光照数据
-
-
return Data; //光照强度数值
-
}
一.软件IIC
-
/
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
***
-
函数功能: SDA初始化
-
*******************************************************************/
-
void SDA_IN(void)
-
{
-
GPIO_InitTypeDef GPIO_InitStruct;
-
/*SDA-----PB11
*/ //浮空输入
-
GPIO_InitStruct.GPIO_Pin = IIC_SDA;
-
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
-
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(IIC_GPIO,&GPIO_InitStruct);
-
}
-
-
/*******************************************************************
-
函数功能: SDA初始化
-
*******************************************************************/
-
void SDA_OUT(void)
-
{
-
GPIO_InitTypeDef GPIO_InitStruct;
-
/*SDA-----PB11
*/ //推挽输出 50MHZ
-
GPIO_InitStruct.GPIO_Pin = IIC_SDA;
-
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
-
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(IIC_GPIO,&GPIO_InitStruct);
-
}
-
-
/*******************************************************************
-
函数功能: 电容按键接口初始化
-
*******************************************************************/
-
void IIC_Init(void)
-
{
-
GPIO_InitTypeDef GPIO_InitStruct;
-
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能B时钟
-
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟
-
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
-
-
/*SDA-----PB11
*/ //推挽输出 50MHZ
-
GPIO_InitStruct.GPIO_Pin = IIC_SDA;
-
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
-
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(IIC_GPIO,&GPIO_InitStruct);
-
-
/*CLK-----PB10
*/ //推挽输出 50MHZ
-
GPIO_InitStruct.GPIO_Pin = IIC_CLK;
-
GPIO_Init(IIC_GPIO,&GPIO_InitStruct);
-
-
CLK_H;
-
SDA_H;
-
}
-
-
/*******************************************************************
-
函数功能: 起始信号
-
*******************************************************************/
-
void IIC_Start(void)
-
{
-
SDA_OUT();
-
SDA_H; //串行数据线高电平(空闲信号)
-
CLK_H; //串行时钟线高电平(空闲信号)
-
Delay_us(5);
-
SDA_L; //串行数据线拉出下降沿
-
Delay_us(5);
-
CLK_L; //串行时钟线拉出下降沿
-
}
-
-
/*******************************************************************
-
函数功能: 结束信号
-
*******************************************************************/
-
void IIC_Stop(void)
-
{
-
SDA_OUT(); //输出模式
-
CLK_L; //串行时钟线低电平
-
SDA_L; //串行数据线低电平
-
CLK_H; //串行时钟线高电平
-
Delay_us(5);
-
SDA_H; //串行数据线高电平 上升沿
-
Delay_us(5);
-
-
}
-
-
/*******************************************************************
-
函数功能: 发送应答信号
-
*******************************************************************/
-
void IIC_Send_ACK(void)
-
{
-
-
CLK_L;
-
SDA_OUT(); //输出模式
-
SDA_L; //串行数据线低电平
-
Delay_us(5);
-
CLK_H; //串行时钟线线高电平 上下
-
Delay_us(5);
-
CLK_L; //串行时钟线线低电平
-
}
-
-
/*******************************************************************
-
函数功能: 发送非应答信号
-
*******************************************************************/
-
void IIC_Send_NoACK(void)
-
{
-
-
CLK_L;
-
SDA_OUT();
-
SDA_H; //串行数据线为高电平
-
Delay_us(5);
-
CLK_H;
-
Delay_us(5);
-
CLK_L;
-
}
-
/*******************************************************************
-
函数功能: 发送8位数据
-
*******************************************************************/
-
void IIC_Send_Data(u8 dat)
-
{
-
u8 i;
-
SDA_OUT();
-
CLK_L;
-
for(i = 0; i < 8; i++) //分8次传输数据 一位一位传递 串行
-
{
-
// Delay_us(5);//SCL拉低后S,SDA要立马改变,(等待时间不能超过0.9us)?????
-
if(dat & 0x80) //先发最高位 1000 0000
-
{
-
SDA_H; //写1
-
}
-
else
-
{
-
SDA_L; //写0
-
}
-
dat <<= 1; //左移操作 次高位-->最高位
-
Delay_us(5);
-
CLK_H;
-
Delay_us(5);
-
CLK_L;
-
Delay_us(5);
-
}
-
}
-
/*******************************************************************
-
函数功能: 等待应答
-
*******************************************************************/
-
u8 IIC_Get_ACK(void)
-
{
-
u8 ERRTIME = 0; //超时变量
-
SDA_IN();
-
//SDA_L;// 没有影响
-
Delay_us(5);
-
CLK_H;
-
Delay_us(5);
-
while( READ_SDA() )
-
{
-
ERRTIME++;
-
if(ERRTIME >=250)
-
{
-
IIC_Stop();
-
return 1;
-
}
-
}
-
CLK_L;
-
return 0;
-
}
-
-
/*******************************************************************
-
函数功能: 读取8位数据
-
*******************************************************************/
-
u8 IIC_Read_Data(u8 ack)
-
{
-
unsigned char i,date = 0;
-
SDA_IN();
-
for(i = 0; i < 8; i++)
-
{
-
-
CLK_L;
-
Delay_us(5);
-
CLK_H;
-
date <<= 1;
-
Delay_us(5);
-
if( READ_SDA() )
-
{
-
date ++;
-
}
-
//Delay_us(2);
-
}
-
if(ack)
-
{
-
IIC_Send_ACK(); //发送应答
-
}
-
else
-
{
-
IIC_Send_NoACK(); //发送非应答
-
}
-
return date;
-
-
}
-
-
-
二.硬件IIC
1.初始化
-
void IIC_Init(void)
-
{
-
GPIO_InitTypeDef GPIO_InitStructure;
-
I2C_InitTypeDef I2C_InitStructure;
-
//初始化时钟
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
-
//配置IO口功能
-
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 |GPIO_Pin_11;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
-
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
-
GPIO_Init(GPIOB,&GPIO_InitStructure);
-
-
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
//IIC模式
-
I2C_InitStructure.I2C_OwnAddress1 =
0x0A;
//作为从机地址
-
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//地址的位数
-
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
//选择有应答信号
-
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_16_9;
//配置高低电平比例
-
I2C_InitStructure.I2C_ClockSpeed =
200000;
//配置时钟
-
I2C_Init(I2C2,&I2C_InitStructure);
-
-
I2C_Cmd(I2C2,ENABLE);
-
// I2C_AcknowledgeConfig(I2C2,ENABLE);
-
}
2.驱动器件
-
typedef
unsigned
char BYTE;
-
typedef
unsigned
short WORD;
-
-
void Single_Write_BH1750(u8 REG_Address)
-
{
-
while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY));
-
//起始信号
-
I2C_GenerateSTART(I2C2,ENABLE);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
-
-
//发送设备地址+写信号
-
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Transmitter);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
-
-
//内部寄存器地址
-
I2C_SendData(I2C2,REG_Address);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS);
-
//发送停止信号
-
I2C_GenerateSTOP(I2C2,ENABLE);
-
}
-
-
//*********************************************************
-
//
-
//连续读出BH1750内部数据
-
//
-
//*********************************************************
-
BYTE BUF[
8];
//接收数据缓存区
-
int dis_data;
//变量
-
void Multiple_read_BH1750(void)
-
{
-
u8 i;
-
while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY));
-
//起始信号
-
I2C_GenerateSTART(I2C2,ENABLE);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
-
//发送设备地址+读信号
-
I2C_Send7bitAddress(I2C2,SlaveAddress,I2C_Direction_Receiver);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS);
-
-
for (i=
0; i<
3
-1; i++)
//连续读取2个地址数据,存储中BUF
-
{
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS);
-
BUF[i] = I2C_ReceiveData(I2C2);
-
}
-
I2C_AcknowledgeConfig(I2C2,DISABLE);
-
while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS);
-
BUF[i] = I2C_ReceiveData(I2C2);
-
-
//停止信号
-
I2C_GenerateSTOP(I2C2,ENABLE);
-
-
I2C_AcknowledgeConfig(I2C2,ENABLE);
-
delay_ms(
5);
-
}
-
-
//初始化BH1750,根据需要请参考pdf进行修改****
-
void Init_BH1750(void)
-
{
-
IIC_Init();
-
Single_Write_BH1750(
0x01);
-
Single_Write_BH1750(
0x10);
// H- resolution mode
-
delay_ms(
180);
-
}
-
-
float BH1750_Value;
-
void BH1750_Read(void)
-
{
-
-
Multiple_read_BH1750();
//连续读出数据,存储在BUF中
-
-
dis_data=BUF[
0];
-
dis_data=(dis_data<<
8)+BUF[
1];
//合成数据,即光照数据
-
-
BH1750_Value=(
float)dis_data/
1.2;
-
-
}
转载:https://blog.csdn.net/qq_45604814/article/details/116132328
查看评论