今天采用硬件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);
}
}