今天采用硬件IIC进行光照强度实验,光照强度模块为BH1750,然后在昨天的OLED的屏幕上显示(OLED采用软件模拟IIC,代码不变)

#include "stm32f4xx.h"
#include "SysTick.h"
#include "light.h"
#include "oled.h"

void Hardware_IIC_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	I2C_InitTypeDef  I2C_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//通电还是断电
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	
	//开始配置F端口下的9号跟10号引脚。
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7; 
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF; //输出模式
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD; //推挽输出
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; //上拉模式,暂时没讲
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed; //引脚响应速度
	
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
	
	
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_ClockSpeed = 100000; //时钟速度、低于400000hz即可
	I2C_InitStructure.I2C_OwnAddress1 = 0x00; //设备自身地址
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //应答使能
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7位地址
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	
	I2C_Init(I2C1, &I2C_InitStructure);
	I2C_Cmd(I2C1, ENABLE);


}


//发送数据
void BH1750_Write(uint8_t data)
{
	//1.判断总线是否被占用
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
	
	//2.发送开始信号
	I2C_GenerateSTART(I2C1, ENABLE);
	
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //等待事件,开始信号发送完成
	
	
	//3.发送器件地址+数据方向(读写)
	I2C_Send7bitAddress(I2C1, BH1750ADDR_GND<<1|0 , I2C_Direction_Transmitter);
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //等待事件6,地址发送+读写位
	
	
	//4.发送数据
	I2C_SendData(I2C1, data);
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING)); //等待事件8,等待发送开始
	

	I2C_AcknowledgeConfig(I2C1, ENABLE); //产生应答信号	
	
	I2C_GenerateSTOP(I2C1, ENABLE);

}

//读取数据
uint16_t BH1750_Read(void)
{
	uint8_t H_data;
	uint8_t L_data;
	uint16_t data;
	
	//1.判断总线是否被占用
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
	
	//2.发送开始信号
	I2C_GenerateSTART(I2C1, ENABLE);
	
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //等待事件,开始信号发送完成
	
	
	//3.发送器件地址+数据方向(读写)
	I2C_Send7bitAddress(I2C1, BH1750ADDR_GND<<1|1 , I2C_Direction_Receiver);
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); //等待事件6,地址发送+读写位
	
		
	I2C_AcknowledgeConfig(I2C1, ENABLE); //产生应答信号
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); //等待事件7
	//4.接收数据
	H_data = I2C_ReceiveData(I2C1);
	I2C_AcknowledgeConfig(I2C1, ENABLE); //产生应答信号	
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); //等待事件7
	
	L_data = I2C_ReceiveData(I2C1);
	I2C_AcknowledgeConfig(I2C1, DISABLE); //产生应答信号	
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); //等待事件7
	

	I2C_GenerateSTOP(I2C1, ENABLE);
	
	data = ((uint16_t)H_data << 8 ) + L_data;
	
	return data;
}

//BH1750通电和设置分辨率
void Get_BH1750ready (void)
{
    BH1750_Write(BH1750_ON);//上电
    Delay_us(3);
    BH1750_Write(BH1750_Mode);//连续分辨率0.51X,连续测量
    Delay_us(3);
}

//获取BH1750的光照强度
void Get_BH1750Data (void)
{
    int dis_data;                       //变量	
    float temp1;
    float temp2;
    
    Get_BH1750ready ();
    dis_data = BH1750_Read();
    Delay_ms(200);
    temp1=dis_data/1.2;//计算光照度
    temp2=10*dis_data/1.2;//把光照度放大10倍,目的是把小数点后一位数据也提取出来	
    temp2=(int)temp2%10;//求余得到小数点后一位

    OLED_ShowNum(2,1,temp1,10);//OLED显示正数
    OLED_ShowString(3,1,"a");//OLED显示小数点	
    OLED_ShowNum(4,1,temp2,10);//OLED显示小数
}


int main(void)
{	
    SysTick_Init();
	
    //初始化IIC
	IIC_init();
	
    ///初始化OLED
	OLED_Init();
    
    //硬件IIC通信,上传
	Hardware_IIC_Init();
     OLED_ShowString(1, 1, "cz");
	while(1)
	{
		Get_BH1750Data ();
		Delay_ms(100);
	}
}

OLED流程见https://blog.51cto.com/u_16897475/11413458