首页 > 其他分享 >基于STM32F407ZGT6用BH1750在OLED显示屏上显示光照数据,根据光照强度控制小灯亮灭(路灯效果)

基于STM32F407ZGT6用BH1750在OLED显示屏上显示光照数据,根据光照强度控制小灯亮灭(路灯效果)

时间:2024-08-29 21:22:46浏览次数:15  
标签:BH1750 0x08 STM32F407ZGT6 光照强度 0x20 0x00 0x80 IIC GPIO

占空比:高电平占整个电平周期的持续时长,从而控制小灯的亮度,小灯亮度的控制需用定时器的输出比较功能。

PWM部分可以参考这篇文章

PWM——基于STM32F407ZGT6开发板-CSDN博客

此外我们还需要了解IIC的工作原理

1.pwm.c    

#include "public.h"

/*
pwm控制led实现呼吸灯


1.看原理图确定GPIO以及定时器OC引脚  PF9     TIM14_CH1
2.GPIO配置
    复用模式    GPIO_PinAFConfig
3.定时器配置

4.频道配置
    a.申明结构体    TIM_OCInitTypeDef
    b.结构体配置    模式、极性、输出使能
    c.初始化(每个频道函数的下标不一样)            TIM_OC1Init

5.定时器ARR寄存器与频道CCR寄存器使能
    TIM_OC1PreloadConfig
    TIM_ARRPreloadConfig
    
6.定时器使能
    TIM_Cmd
    
7.修改占空比
    调用TIM_SetCompare1

*/

void tim14_pwm_led0(uint16_t psc, uint32_t arr)
{
    
    GPIO_InitTypeDef  GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//通电还是断电
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);    //时钟使能
    
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14);        //复用为定时器14
    
    //开始配置F端口下的9号跟10号引脚
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //led0 led1
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF; //复用模式
    GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉模式
    GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed; //引脚响应速度
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
    TIM_TimeBaseStructure.TIM_Prescaler = psc-1;                //PSC值
    TIM_TimeBaseStructure.TIM_Period = arr-1;                    //ARR值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);
    
    
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                 //pwm模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    //输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;        //输出极性低
    TIM_OC1Init(TIM14, &TIM_OCInitStructure);
    
    TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);    //使能TIM14在OC1上的CCR预装载寄存器
    TIM_ARRPreloadConfig(TIM14, ENABLE);                //定时器14 ARR寄存器
    
    TIM_Cmd(TIM14, ENABLE);            //定时器使能
}

//封装TIM_SetCompare1 - 固定定时器TIM14 - 方便传参只传一个
void PWM_SetCompare1(uint32_t Compare)
{
  TIM_SetCompare1(TIM14,Compare);
}

2.iic.c(注意这里用的软件iic)

#include "public.h"
/*
1.梳理IIC流程思路:时序图
2.代码封装
	起始命令
	终止命令
	发送一个字节数绝
	接收一个字节数据
	应答与非应答
	等待应答
	IIC引脚初始化
	IIC引脚切换
*/
void IICx_GPIO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	//GPIO时钟
	RCC_AHB1PeriphClockCmd(RCC_IIC_SCL, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_IIC_SDA, ENABLE);
	
	//SCL GPIO初始化
	GPIO_InitStructure.GPIO_Pin=IIC_SCL; 
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; 
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD; //开漏输出
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure);
	
	//SDA GPIO初始化
	GPIO_InitStructure.GPIO_Pin=IIC_SDA; 
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; 
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD; //开漏输出
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
	
	IIC_SCL_H;
	IIC_SDA_H;
}

//配置SDA数据线为输出
void IIC_SDA_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	//SDA GPIO初始化
	GPIO_InitStructure.GPIO_Pin=IIC_SDA; 
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; 
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD; //开漏输出
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
}


//配置SDA数据线为输入
void IIC_SDA_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	//SDA GPIO初始化
	GPIO_InitStructure.GPIO_Pin=IIC_SDA; 
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN; 
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉,仅对输入有效
	
	GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
}

//IIC时序信号

//IIC开始信号
void IIC_Start(void)
{
	IIC_SDA_OUT();
	
	IIC_SCL_H;
	IIC_SDA_H;
	Delay_us(4);//让高电平保持稳定
	
	IIC_SDA_L;  // 拉低SDA
	Delay_us(4);
	IIC_SCL_L;	//钳住IIC总线,准备发送或者接收数据	
}

//IIC停止信号
void IIC_Stop(void)
{
	IIC_SDA_OUT();
	IIC_SCL_H;
	IIC_SDA_L;  //SAD低
	Delay_us(4);//等待时序稳定
	IIC_SDA_H;  //SDA高
}

//IIC应答
void IIC_ACK(void)
{
	IIC_SDA_OUT();
	IIC_SCL_L;  //在SCL低电平的时候,SDA可以进行数据切换(1和0切换)
	IIC_SDA_L;  //SDA低电平表示应答型号
	Delay_us(1);//让电平稳定
	
	IIC_SCL_H;  //拉高SCL,表示此时SDA的数据有效
	Delay_us(1);
	IIC_SCL_L;  //拉低SCL,表示SCL一个周期结束
}

//IIC非应答
void IIC_NACK(void)
{
	IIC_SDA_OUT();
	IIC_SCL_L;  //在SCL低电平的时候,SDA可以进行数据切换(1和0切换)
	IIC_SDA_H;  //SDA高电平表示非应答型号
	Delay_us(1);//让电平稳定
	
	IIC_SCL_H;  //拉高SCL,表示此时SDA的数据有效
	Delay_us(1);
	IIC_SCL_L;  //拉低SCL,表示SCL一个周期结束
}

//IIC发送一个字节
void IIC_SendByte(uint8_t data)
{
	IIC_SDA_OUT();
	IIC_SCL_L; //在SCL低电平的时候,SDA可以进行数据切换(1和0切换)
	
	uint8_t i=0;
	for(i=0;i<8;i++)
	{
		if((data&0x80)>0)   //0x80  1000 0000  
		{
			IIC_SDA_H;
		}
		else
		{
			IIC_SDA_L;
		}
		IIC_SCL_H;  //拉高SCL ,数据有效
		Delay_us(1); //延时,将数据发送出去
		
		IIC_SCL_L;
		Delay_us(1);
		data<<=1;
	}
}


//IIC读取一个字节
uint8_t IIC_ReadByte(uint8_t ack) //ack 1 应答 0 非应答
{
	IIC_SDA_IN();
	
	uint8_t i=0;
	uint8_t receive=0;
	
	for(i=0;i<8;i++)
	{
		IIC_SCL_L;
		Delay_us(1);
		IIC_SCL_H;
		
		receive<<=1; 
		if(READ_SDA)
		{
			receive++; 
		}
		Delay_us(1);
		
	}
	if(ack)
		IIC_ACK();
	else
		IIC_NACK();
	
	return receive;
	
}


//IIC等待应答 ,返回0表示应答,返回1表示非应答
uint8_t IIC_WaitACK(void)
{
	IIC_SDA_IN();
	
	uint8_t temp=0;
	IIC_SDA_H;
	Delay_us(1);
	IIC_SCL_H;
	Delay_us(1);
	while(READ_SDA)
	{
		temp++;
		if(temp>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL_L;
	return 0;
	
}

3.iic.h

#ifndef __IIC_H
#define __IIC_H

#include "public.h"
//选择PE3和PE4 做为通讯引脚  PE3:SCL  PE4:SDA

#define RCC_IIC_SCL   RCC_AHB1Periph_GPIOE //端口时钟
#define IIC_SCL_PORT  GPIOE				   //端口号
#define IIC_SCL 	  GPIO_Pin_3		   //引脚

#define RCC_IIC_SDA   RCC_AHB1Periph_GPIOE
#define	IIC_SDA_PORT  GPIOE
#define	IIC_SDA 	  GPIO_Pin_4

//io操作

#define IIC_SCL_H     GPIO_SetBits(IIC_SCL_PORT,IIC_SCL);  //SCL置1
#define	IIC_SCL_L     GPIO_ResetBits(IIC_SCL_PORT,IIC_SCL);//SCL置0

#define IIC_SDA_H     GPIO_SetBits(IIC_SDA_PORT,IIC_SDA);  //SDA置1
#define	IIC_SDA_L     GPIO_ResetBits(IIC_SDA_PORT,IIC_SDA);//SDA置0

#define READ_SDA 	  GPIO_ReadInputDataBit(IIC_SDA_PORT,IIC_SDA)//读取SDA输入引脚电平

void IICx_GPIO_Init(void);
void IIC_SDA_OUT(void);
void IIC_SDA_IN(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_ACK(void);
void IIC_NACK(void);
void IIC_SendByte(uint8_t data);
uint8_t IIC_ReadByte(uint8_t ack);
uint8_t IIC_WaitACK(void);
uint16_t BH1750_ReadData(void);


#endif

4.oled.c(因为通信协议是IIC所以这里的OLED显示屏是四针脚的)

VCC接3.3V   GND接板子上的GND  SCK接PE3  SDA接PE4

/********************OLED屏幕操作函数***************************/
#include "public.h"
#include "oled_font.h"

void OLED_WriteCommand(uint8_t Command)
{
	IIC_Start();
	IIC_SendByte(0x78); 	//从机地址,并且写数据
	IIC_WaitACK();
	IIC_SendByte(0x00);     //
	IIC_WaitACK();
	IIC_SendByte(Command); // 写入命令
	IIC_WaitACK();
	IIC_Stop();
}

void OLED_WriteData(uint8_t Data)
{
	IIC_Start();
	IIC_SendByte(0x78); 	//从机地址
	IIC_WaitACK();
	IIC_SendByte(0x40);
	IIC_WaitACK();
	IIC_SendByte(Data); 	// 写入命令
	IIC_WaitACK();
	IIC_Stop();
}

/**
 * @brief  OLED设置光标位置
 * @param  Y 以左上角为原点,向下方向的坐a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a标,范围:0~7
 * @param  X 以左上角为原点,向右方向的坐标,范围:0~127
 * @retval 无
 */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
		//协议规定
    OLED_WriteCommand(0xB0 | Y);                 // 设置Y位置
    OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); // 设置X位置高4位
    OLED_WriteCommand(0x00 | (X & 0x0F));        // 设置X位置低4位
}

/**
 * @brief  OLED清屏
 * @param  无
 * @retval 无
 */
void OLED_Clear(void)
{
    uint8_t i, j;
    for (j = 0; j < 8; j++)
    {
        OLED_SetCursor(j, 0);
        for (i = 0; i < 128; i++)
        {
            OLED_WriteData(0x00);
        }
    }
}

/**
 * @brief  OLED显示一个字符
 * @param  Line 行位置,范围:1~4
 * @param  Column 列位置,范围:1~16
 * @param  Char 要显示的一个字符,范围:ASCII可见字符
 * @retval 无
 */
void OLED_ShowCN(uint8_t Line, uint8_t Column, uint8_t Num)  
{      	
	uint8_t i;
	uint8_t wide=20;//字宽
	
	OLED_SetCursor((Line-1)*2, (Column-1)*wide);		//参数1:把光标设置在第几页. 参数2:把光标设置在第几列
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F10x16[Num][i]);			//显示上半部分内容
	}
	
	OLED_SetCursor((Line-1)*2+1,(Column-1)*wide);		
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F10x16[Num][i+wide]);		//显示下半部分内容
	}
 
}

void OLED_ShowName(uint8_t Line, uint8_t Column, uint8_t Num)  
{      	
	uint8_t i;
	uint8_t wide=16;//字宽
	
	OLED_SetCursor((Line-1)*2, (Column-1)*wide);		//参数1:把光标设置在第几页. 参数2:把光标设置在第几列
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F8x16_name[Num][i]);			//显示上半部分内容
	}
	
	OLED_SetCursor((Line-1)*2+1,(Column-1)*wide);		
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F8x16_name[Num][i+wide]);		//显示下半部分内容
	}
 
}

void OLED_ShowLight(uint8_t Line, uint8_t Column, uint8_t Num)  
{      	
	uint8_t i;
	uint8_t wide=16;//字宽
	
	OLED_SetCursor((Line-1)*2, (Column-1)*wide);		//参数1:把光标设置在第几页. 参数2:把光标设置在第几列
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F8x16_light[Num][i]);			//显示上半部分内容
	}
	
	OLED_SetCursor((Line-1)*2+1,(Column-1)*wide);		
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(OLED_F8x16_light[Num][i+wide]);		//显示下半部分内容
	}
 
}


void OLED_ShowLove(uint8_t Line, uint8_t Column)
{
	uint8_t i;
	uint8_t wide=8;//字宽
	
	OLED_SetCursor((Line-1)*2, (Column-1)*wide);		//参数1:把光标设置在第几页. 参数2:把光标设置在第几列
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(Love_Heart0[i]);			//显示空心
	}
	OLED_SetCursor((Line-1)*2 + 1, (Column-1)*wide);
	for (i = 0; i < wide; i++)
	{
		OLED_WriteData(Love_Heart1[i]);			//显示实心
	}
}

void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{
    uint8_t i;
    OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); 		// 设置光标位置在上半部分
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(OLED_F8x16[Char - ' '][i]); 			// 显示上半部分内容
    }
    OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); 	// 设置光标位置在下半部分
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]); 		// 显示下半部分内容
    }
}

/**
 * @brief  OLED显示字符串
 * @param  Line 起始行位置,范围:1~4
 * @param  Column 起始列位置,范围:1~16
 * @param  String 要显示的字符串,范围:ASCII可见字符
 * @retval 无
 */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
    uint8_t i;
    for (i = 0; String[i] != '\0'; i++)
    {
        OLED_ShowChar(Line, Column + i, String[i]);
    }
}

/**
 * @brief  OLED次方函数
 * @retval 返回值等于X的Y次方
 */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    while (Y--)
    {
        Result *= X;
    }
    return Result;
}

/**
 * @brief  OLED显示数字(十进制,正数)
 * @param  Line 起始行位置,范围:1~4
 * @param  Column 起始列位置,范围:1~16
 * @param  Number 要显示的数字,范围:0~4294967295
 * @param  Length 要显示数字的长度,范围:1~10
 * @retval 无
 */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
    }
}

/**
 * @brief  OLED显示数字(十进制,带符号数)
 * @param  Line 起始行位置,范围:1~4
 * @param  Column 起始列位置,范围:1~16
 * @param  Number 要显示的数字,范围:-2147483648~2147483647
 * @param  Length 要显示数字的长度,范围:1~10
 * @retval 无
 */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
    uint8_t i;
    uint32_t Number1;
    if (Number >= 0)
    {
        OLED_ShowChar(Line, Column, '+');
        Number1 = Number;
    }
    else
    {
        OLED_ShowChar(Line, Column, '-');
        Number1 = -Number;
    }
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
    }
}

/**
 * @brief  OLED显示数字(十六进制,正数)
 * @param  Line 起始行位置,范围:1~4
 * @param  Column 起始列位置,范围:1~16
 * @param  Number 要显示的数字,范围:0~0xFFFFFFFF
 * @param  Length 要显示数字的长度,范围:1~8
 * @retval 无
 */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i, SingleNumber;
    for (i = 0; i < Length; i++)
    {
        SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
        if (SingleNumber < 10)
        {
            OLED_ShowChar(Line, Column + i, SingleNumber + '0');
        }
        else
        {
            OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
        }
    }
}

/**
 * @brief  OLED显示数字(二进制,正数)
 * @param  Line 起始行位置,范围:1~4
 * @param  Column 起始列位置,范围:1~16
 * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
 * @param  Length 要显示数字的长度,范围:1~16
 * @retval 无
 */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
    }
}

/**
 * @brief  OLED初始化
 * @param  无
 * @retval 无
 */
void OLED_Init(void)
{
  

	Delay_ms(100);

    OLED_WriteCommand(0xAE); // 关闭显示

    OLED_WriteCommand(0xD5); // 设置显示时钟分频比/振荡器频率
    OLED_WriteCommand(0x80);

    OLED_WriteCommand(0xA8); // 设置多路复用率
    OLED_WriteCommand(0x3F);

    OLED_WriteCommand(0xD3); // 设置显示偏移
    OLED_WriteCommand(0x00);

    OLED_WriteCommand(0x40); // 设置显示开始行

    OLED_WriteCommand(0xA1); // 设置左右方向,0xA1正常 0xA0左右反置

    OLED_WriteCommand(0xC8); // 设置上下方向,0xC8正常 0xC0上下反置

    OLED_WriteCommand(0xDA); // 设置COM引脚硬件配置
    OLED_WriteCommand(0x12);

    OLED_WriteCommand(0x81); // 设置对比度控制
    OLED_WriteCommand(0xCF);

    OLED_WriteCommand(0xD9); // 设置预充电周期
    OLED_WriteCommand(0xF1);

    OLED_WriteCommand(0xDB); // 设置VCOMH取消选择级别
    OLED_WriteCommand(0x30);

    OLED_WriteCommand(0xA4); // 设置整个显示打开/关闭

    OLED_WriteCommand(0xA6); // 设置正常/倒转显示

    OLED_WriteCommand(0x8D); // 设置充电泵
    OLED_WriteCommand(0x14);

    OLED_WriteCommand(0xAF); // 开启显示

    OLED_Clear(); // OLED清屏
}

5.oledfont.h(里面是字库)

#ifndef __OLED_FONT_H
#define __OLED_FONT_H

#include <stdint.h>

static unsigned char Love_Heart0[8]={0x1C,0x22,0x42,0x84,0x84,0x42,0x22,0x1C};/*"空心图形",0*/
static unsigned char Love_Heart1[8]={0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C};/*"实心图形",1*/

const uint8_t OLED_F8x16_light[][32]=
{
	
		0x00,0x40,0x42,0x44,0x58,0x40,0x40,0x7F,0x40,0x40,0x50,0x48,0xC6,0x00,0x00,0x00,
		0x00,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFF,0x00,0x00,0x00,/*"当",0*/

		0x08,0x08,0xE8,0x29,0x2E,0x28,0xE8,0x08,0x08,0xC8,0x0C,0x0B,0xE8,0x08,0x08,0x00,
		0x00,0x00,0xFF,0x09,0x49,0x89,0x7F,0x00,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00,0x00,/*"前",1*/

		0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x40,0x40,0x00,
		0x80,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78,0x00,/*"光",2*/

		0x00,0xFE,0x42,0x42,0x42,0xFE,0x00,0x42,0xA2,0x9E,0x82,0xA2,0xC2,0xBE,0x00,0x00,
		0x80,0x6F,0x08,0x08,0x28,0xCF,0x00,0x00,0x2F,0xC8,0x08,0x08,0x28,0xCF,0x00,0x00,/*"照",3*/

		0x02,0xE2,0x22,0x22,0x3E,0x00,0x80,0x9E,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,
		0x00,0x43,0x82,0x42,0x3E,0x40,0x47,0x44,0x44,0x44,0x7F,0x44,0x44,0x54,0xE7,0x00,/*"强",4*/

		0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
		0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",5*/
};

/*OLED字模库,宽8像素,高16像素*/
const uint8_t OLED_F8x16[][16]=
{
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//  0
	
	0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
	
	0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
	
	0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,
	0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
	
	0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,
	0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
	
	0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,
	0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
	
	0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,
	0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
	
	0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
	
	0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,
	0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
	
	0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,
	0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
	
	0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,
	0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
	
	0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,
	0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
	
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
	
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
	
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
	
	0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,
	0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
	
	0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
	0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
	
	0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,
	0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
	
	0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,
	0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
	
	0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,
	0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
	
	0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,
	0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
	
	0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,
	0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
	
	0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,
	0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
	
	0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,
	0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
	
	0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,
	0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
	
	0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
	0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
	
	0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,
	0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
	
	0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,
	0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
	
	0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,
	0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
	
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
	0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
	
	0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
	0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
	
	0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,
	0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
	
	0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,
	0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
	
	0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,
	0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
	
	0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,
	0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
	
	0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,
	0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
	
	0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,
	0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
	
	0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
	0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
	
	0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
	0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
	
	0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,
	0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
	
	0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
	0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
	
	0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,
	0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
	
	0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,
	0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
	
	0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,
	0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
	
	0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,
	0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
	
	0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,
	0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
	
	0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,
	0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
	
	0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
	0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
	
	0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,
	0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
	
	0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
	0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
	
	0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,
	0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
	
	0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,
	0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
	
	0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,
	0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
	
	0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
	0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
	
	0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,
	0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
	
	0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,
	0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
	
	0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,
	0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
	
	0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,
	0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
	
	0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,
	0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
	
	0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,
	0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
	
	0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
	
	0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,
	0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
	
	0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
	
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
	
	0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
	
	0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
	0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
	
	0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,
	0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
	
	0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,
	0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
	
	0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,
	0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
	
	0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
	0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
	
	0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,
	0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
	
	0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
	0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
	
	0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,
	0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
	
	0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,
	0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
	
	0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,
	0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
	
	0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,
	0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
	
	0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,
	0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
	
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
	0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
	
	0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,
	0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
	
	0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
	0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
	
	0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,
	0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
	
	0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,
	0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
	
	0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
	0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
	
	0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
	0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
	
	0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,
	0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
	
	0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,
	0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
	
	0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
	0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
	
	0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,
	0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
	
	0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
	0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
	
	0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
	0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
	
	0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
	0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
	
	0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,
	0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
	
	0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
	
	0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,
	0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
	
	0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};

const uint8_t OLED_F10x16[][40]=
{
     0x00,0x00,0x10,0x10,0x12,0xFE,0x90,0x10,0x10,0x7E,0x50,0x50,0x50,0x48,0x48,0x44,
     0x44,0x70,0x40,0x00,0x00,0x02,0x02,0x42,0x41,0x3F,0x00,0x00,0x00,0x41,0x7E,0x2A,
     0x2A,0x2A,0x2A,0x2A,0x7F,0x00,0x00,0x00,/*"指",0*/
     	
     0x00,0x40,0x60,0x50,0x48,0xC6,0x60,0x20,0x10,0x10,0xF0,0x12,0x1C,0x10,0x90,0x70,
     0x10,0x18,0x10,0x00,0x00,0x20,0x24,0x26,0x15,0x94,0x52,0x52,0x40,0x20,0x20,0x13,
     0x0C,0x1C,0x33,0x20,0x60,0x40,0x00,0x00,/*"纹",1*/
     	
     0x00,0x40,0x40,0x40,0x44,0x54,0x54,0x54,0x54,0xD4,0xD4,0x54,0x54,0x54,0x7C,0xC0,
     0x40,0x40,0x40,0x00,0x00,0x20,0x20,0x10,0x10,0x13,0x0E,0x48,0x44,0x7F,0x3F,0x02,
     0x04,0x0A,0x12,0x31,0x21,0x20,0x20,0x00,/*"录",2*/
     	
     0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0xC4,0x78,0x70,0x80,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x20,0x10,0x08,0x04,0x03,0x01,0x00,0x00,0x01,
     0x03,0x0C,0x18,0x10,0x30,0x20,0x20,0x00,/*"入",3*/
     
     0x00,0x80,0x80,0xFC,0x84,0xFC,0x84,0x80,0xFC,0x84,0x84,0xFC,0x80,0x80,0xF8,0x08,
     0x00,0xFE,0x02,0x00,0x00,0x40,0x38,0x27,0x20,0x3F,0x40,0x38,0x47,0x40,0x40,0x3F,
     0x00,0x00,0x0F,0x40,0x40,0x7F,0x00,0x00,/*"删",4*/
	
     0x00,0x00,0xFC,0x04,0x64,0x94,0x8C,0x44,0x20,0x60,0x58,0x4C,0xC2,0x4C,0x50,0x70,
     0x20,0x60,0x00,0x00,0x00,0x00,0x7F,0x04,0x08,0x08,0x47,0x20,0x12,0x0E,0x42,0xC2,
     0x7F,0x02,0x02,0x0A,0x12,0x22,0x00,0x00,/*"除",5*/	
     	  
 };

#endif

6.BH1750.c (SCL接PB6、SDA接PB7、ADDR接高电平3.3v)

#include "public.h"

#define BH1750_ADDR_H 0x5C
#define BH1750_ADDR_L 0x23

#define BH1750_POWER_ON 0x01
#define BH1750_POWER_OFF 0x00
#define BH1750_RESET 0x07

//PB6 PB7初始化
static void IIC_hardware_init(void)
{
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	I2C_InitTypeDef  I2C_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;//速度
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//高低电平
	
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_I2C1);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_I2C1);		//复用为IIC
	
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_ClockSpeed = 100000;
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;			//主机地址
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	I2C_Init(I2C1,&I2C_InitStructure);
	
	I2C_Cmd(I2C1,ENABLE);
}



static void IIC_hardward_write(uint8_t data)
{
	
	//1.判断硬件总线状态,是否繁忙
	while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
	
	//2.发送起始信号
	I2C_GenerateSTART(I2C1,ENABLE);
	
	//3.等待EV5,确保IIC开始信号已经发出
	while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)));

	//4.发送设备地址和方向
	I2C_Send7bitAddress(I2C1,BH1750_ADDR_L<<1 | 0,I2C_Direction_Transmitter);

	//5.等待EV6,确保地址和方向位已经发出
	
	while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)));
	
	//6.发送数据
   I2C_SendData(I2C1,data);
    
	//7.等待EV8,确保数据寄存器DR为空,数据已经发送
   while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    
	//8.应答信号使能
   //I2C_AcknowledgeConfig(I2C1,ENABLE);

	//9.结束信号
   I2C_GenerateSTOP(I2C1,ENABLE);
}

uint16_t IIC_hardware_read(void)
{
    uint8_t H_rev;
    uint8_t L_rev;
		uint16_t rev_data;
		//1.判断硬件总线状态,是否繁忙
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));

		//2.发送起始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    
		//3.等待EV5,确保IIC开始信号已经发出
		//逻辑是函数若检测到EV5发生会返回布尔值1,不断循环直到检测到EV5发生然后取反为0跳出循环
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
		//4.发送设备地址和方向
    I2C_Send7bitAddress(I2C1,BH1750_ADDR_L<<1|1,I2C_Direction_Receiver);
    
		//5.等待EV6,确保地址和方向位已经发出
		while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)));
	
		//6.产生应答信号
    I2C_AcknowledgeConfig(I2C1,ENABLE);
    
		//7.等待EV7,确保可以接收数据
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED));

		//接收数据高8位
		H_rev= I2C_ReceiveData(I2C1);
		
		//应答信号使能
		I2C_AcknowledgeConfig(I2C1,ENABLE);

		//8.等待EV7,确保可以接收数据
		while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));
		//接收数据低8位
		L_rev= I2C_ReceiveData(I2C1);
		//非应答信号使能
		I2C_AcknowledgeConfig(I2C1,DISABLE);
		
		//9.停止信号
		I2C_GenerateSTOP(I2C1, ENABLE);
		
		rev_data = ((uint16_t)H_rev<<8) + L_rev;
		
		return rev_data;

}

//bh1750驱动
void bh1750_init()
{
	IIC_hardware_init();
	Delay_ms(500);
	
	IIC_hardward_write(BH1750_POWER_OFF); //断电
	IIC_hardward_write(BH1750_POWER_ON);	//通电
	IIC_hardward_write(BH1750_RESET);			//重置
	IIC_hardward_write(0x11);	//分辨率H2
	
}

float get_light_value(void)
{
	return (float)(IIC_hardware_read() / 1.2);
}

7.main.c

#include "public.h"
/*
1. GPIO口软件模拟IIC时序,实现IIC通讯
2. 跟OLED屏幕通讯
3. 跟BH1750光照模块通讯,获取光照信息并打印输出
4. 调用PWM函数接口,调整小灯的占空比,实现路灯效果
*/

int main(void)
{
	SysTick_Init();
	USART_Init_Config();
	IICx_GPIO_Init();
	OLED_Init();
	bh1750_init();
	tim14_pwm_led0(84, 1000);
	int i;
	
	for(i = 0;i < 6; i++)
	{
		OLED_ShowLight(1,i+1,i);
	}
	OLED_ShowString(1,13,":");

	float data;
	while(1)
	{
		data = get_light_value();
		//printf("%f  ",data);
		OLED_ShowNum(2,1,data,4);
		
		if(data>300)//环境光亮,让灯灭
		{
				PWM_SetCompare1(0);
				Delay_ms(1);
				continue;
		}
		else if(data < 300)//环境光暗,让灯亮
		{
			PWM_SetCompare1(1000 - data);
		}
		Delay_ms(1);
	}
}

正确编译并烧录到板子上

8.效果如下

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="R1DzeRI2-1724938069119" src="https://live.csdn.net/v/embed/420934"></iframe>

video_20240829_205715_edit

标签:BH1750,0x08,STM32F407ZGT6,光照强度,0x20,0x00,0x80,IIC,GPIO
From: https://blog.csdn.net/luckyluckypolar/article/details/141687548

相关文章

  • 基于STM32F407ZGT6芯片的GPIO工作模式
    目录4种输入模式4种输出模式输入模式模拟输入浮空输入上拉输入下拉输入输出模式推挽输出开漏输出复用推挽输出复用开漏输出4种输入模式(1)GPIO_Mode_IN_FLOATING浮空输入(2)GPIO_Mode_IPU上拉输入(3)GPIO_Mode_IPD下拉输入(4)GPIO_Mode_AIN模拟输入4种输出模......
  • 基于51单片机的光照强度检测系统设计与实现
    基于51单片机的光照强度检测系统设计与实现摘要本文设计并实现了一个基于51单片机的光照强度检测系统,该系统利用光敏电阻作为光照强度检测元件,通过ADC转换器将模拟信号转换为数字信号,并由51单片机进行处理和显示。系统具备实时检测、数据转换、存储及显示功能,适用于各种需要......
  • 2_STM32F407ZGT6系列芯片学习2
    1linuxc语言基础 linux:相关命令 c:数据类型常量变量运算符输入输出控制语句数组和字符串指针函数 结构体内存管理makefile 数据结构:顺序表(线性表)链表栈队列二叉树排序查找 ARM初级开发:GPIO USART 中断 时钟 定时......
  • STM32F407ZGT6芯片及部分外设学习
    STM32:ST:意法半导体,是一个公司的名字32:32bit的意思,表示这是一个32bit的微控制器ARM:ARM是英国的芯片设计公司,其最成功的莫过于32位嵌入式CPU核--ARM系列,最常用的是ARM7和ARM9,    ARM公司主要提供IP(IntellectualPropertycore知识产权的......
  • 舵机驱动——STM32F407ZGT6探索者——HAL库
    舵机驱动——STM32F407ZGT6探索者——HAL库1、材料准备开发板:正点原子STM32F407ZGT6探索者舵机:SG90舵机线材分辨:褐色/红色/橘黄色——GND/VCC/PWM_signal与开发板接线:褐色/红色/橘黄色——GND/+5V/PF6(任选的PF6)2、知识准备2.1、舵......
  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能
    开发板:STM32F407ZGT6;目标:想使用软件“串口调试助手”情况:开发板上的USB_UART口所在器件损坏或者直接没有;解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作:1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,将串口1的TX接USB转TTL模块的R......
  • 国产MCU-CW32F030开发学习-BH1750模块
    国产MCU-CW32F030开发学习-BH1750模块硬件平台CW32_48F大学计划板CW32_IOT_EVA物联网开发评估套件BH1750数字型光照强度传感器BH1750BH1750是一款数字型光照强度传感器,能够获取周围环境的光照强度。其测量范围在0~65535lx。lx勒克斯,是光照强度的单位。BH1750可用于调节......
  • 基于蒙特卡洛概率潮流计算 在IEEE33节点系统中,由于风光出力的不确定性,利用蒙特卡洛生
    基于蒙特卡洛概率潮流计算在IEEE33节点系统中,由于风光出力的不确定性,利用蒙特卡洛生成风速和光照强度得到出力,可得到每个节点的电压和支路功率变化,网损和光照强度。这段程序主要是进行电力系统潮流计算和蒙特卡洛仿真。下面我会对程序进行详细的分析和解释。原创文章,转载请说明......
  • STM32通过ADC1读取光敏电阻的值转换光照强度
    【1】光敏电阻的原理光敏电阻是一种半导体元件,它的电阻值会随着照射在其表面的光线强度的变化而发生改变。当光线越强,光敏电阻的电阻值就越小;当光线较弱或没有光照射时,电阻值就会增大。光敏电阻广泛应用于光电控制、光度计、自动调节亮度灯等领域。常见的光敏电阻有硫化镉(CdS)光敏电......
  • QT圆形进度条(桌面项目光照强度检测)
    (文章目录)前言本篇文章我们讲解QT实现圆形进度条,并实现动态的效果。一、编程思路实现QT圆形进度条其实是非常简单的,思路就是画两个圆弧。这里大家就会觉得很奇怪了为什么画两个圆弧就能实现圆形进度条了呢?那么下面我们一个个圆弧来画看看效果。代码:painter.translate(......