本帖最后由 jinglixixi 于 2025-6-2 12:22 编辑
#申请原创#
BH1750是一款基于 I2C 接口的数字式环境光传感器,它适于获得环境光照强度的检测,受光学窗口的影响其检测最小为 0.11 lx,最大为 100000 lx。
该传感器的引脚定义如图1所示,它与开发板的连接关系为:
SCL ---PB8
SDA---PB9
为便于直观观察检测结果,由OLED进行显示,它与开发板的连接关系为:
SCL ---PA5
SDA---PA6
图1 引脚定义
图2 所用接口
为便于引脚的分配和使用,这里采用模拟I2C的方式来实现光照强度的检测。
配置所用引脚的函数为:
- void BH1750_Init(void)
- {
- gpio_init_type gpio_init_struct;
- crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
- gpio_default_para_init(&gpio_init_struct);
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_8|GPIO_PINS_9;
- gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
- gpio_init(GPIOB, &gpio_init_struct);
- }
有别于OLED屏的显示驱动,在进行光照检测时,数据引脚既要工作在输出模式,也要工作在输入模式。
为此,需要配置相应的工作模式函数,以便进行工作模式切换。
设置为输入模式的函数为:
- void IIC_INPUT_MODE_SET()
- {
- gpio_init_type gpio_init_struct;
- gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_9;
- gpio_init(GPIOB, &gpio_init_struct);
- }
设置为输出模式的函数为:- void IIC_OUTPUT_MODE_SET()
- {
- gpio_init_type gpio_init_struct;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_9;
- gpio_init(GPIOB, &gpio_init_struct);
- }
设置引脚输出高低电平和检测引脚状态的语句定义为:
#define SCL_Set() GPIOB->scr = GPIO_PINS_8
#define SCL_Clr() GPIOB->clr = GPIO_PINS_8
#define SDA_Set() GPIOB->scr = GPIO_PINS_9
#define SDA_Clr() GPIOB->clr = GPIO_PINS_9
#define IIC_SDA_IN gpio_input_data_bit_read(GPIOB, GPIO_PINS_9)
模拟I2C处理的辅助辅助函数如下:
- void BH1750_Start()
- {
- IIC_OUTPUT_MODE_SET();
- SDA_Set();
- SCL_Set();
- delay_us(5);
- SDA_Clr();
- delay_us(5);
- SCL_Clr();
- }
- void BH1750_Stop()
- {
- IIC_OUTPUT_MODE_SET();
- SDA_Clr();
- SCL_Set();
- delay_us(5);
- SDA_Set();
- delay_us(5);
- }
- void BH1750_SendACK(char ack)
- {
- IIC_OUTPUT_MODE_SET();
- SCL_Clr();
- if(ack)
- {
- SDA_Set();
- }
- else
- {
- SDA_Clr();
- }
- delay_us(2);
- SCL_Set();
- delay_us(5);
- SCL_Clr();
- }
- char BH1750_RecvACK()
- {
- int cnt=0;
- IIC_OUTPUT_MODE_SET();
- SDA_Set();
- delay_us(1);
- SCL_Set();
- IIC_INPUT_MODE_SET();
- delay_us(1);
- while(IIC_SDA_IN)
- {
- cnt++;
- delay_us(1);
- if(cnt>=250)
- {
- BH1750_Stop();
- return 1;
- }
- }
- SCL_Clr();
- return 0;
- }
模拟I2C发送字节数据的函数为:
- void BH1750_SendByte(char data)
- {
- char i;
- IIC_OUTPUT_MODE_SET();
- SCL_Clr();
- delay_us(2);
- for (i=0;i<8;i++)
- {
- if(data&0x80)
- {
- SDA_Set();
- }
- else
- {
- SDA_Clr();
- }
- data <<= 1;
- SCL_Set();
- delay_us(2);
- SCL_Clr();
- delay_us(2);
- }
- }
模拟I2C读取字节数据的函数为:
- char BH1750_RecvByte()
- {
- char i;
- char data = 0;
- IIC_INPUT_MODE_SET();
- for (i=0;i<8;i++)
- {
- SCL_Clr();
- delay_us(2);
- SCL_Set();
- data <<= 1;
- SCL_Set();
- if(IIC_SDA_IN) data|=0x01;
- delay_us(2);
- }
- SCL_Clr();
- return data;
- }
写入寄存器地址的函数为:
- void Single_Write_BH1750(char REG_Address)
- {
- BH1750_Start();
- BH1750_SendByte(SlaveAddress);
- BH1750_RecvACK();
- BH1750_SendByte(REG_Address);
- BH1750_RecvACK();
- BH1750_Stop();
- }
读取BH1750多字节数据的函数为:
- void Multiple_Read_BH1750()
- {
- BH1750_Start();
- BH1750_SendByte(SlaveAddress+1);
- BH1750_RecvACK();
- BUF[0] = BH1750_RecvByte();
- BH1750_SendACK(0);
- BUF[1] = BH1750_RecvByte();
- BH1750_SendACK(1);
- BH1750_Stop();
- delay_ms(5);
- }
实现光强检测与显示的函数为:
- void Get_Sunlight_Value()
- {
- int dis_data=0;
- float temp;
- char i=0;
- unsigned int sd;
- Single_Write_BH1750(0x01);
- Single_Write_BH1750(0x10);
- delay_ms(180);
- Multiple_Read_BH1750();
- for(i=0;i<3;i++)dis_data=BUF[0];
- dis_data=(dis_data<<8)+BUF[1];
- temp=(float)dis_data/1.2;
- sd=temp;
- OLED_ShowNum(20,2,sd,5,16);
- }
实现光强检测与显示的主程序为:
- int main(void)
- {
- system_clock_config();
- at32_board_init();
- oled_config();
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(0,0,"AT32M412",16);
- OLED_ShowString(0,2,"L=",16);
- BH1750_Init();
- while(1)
- {
- at32_led_toggle(LED2);
- delay_ms(200);
- at32_led_toggle(LED3);
- delay_ms(200);
- at32_led_toggle(LED4);
- delay_ms(200);
- Get_Sunlight_Value();
- }
- }
经程序的编译和下载,其检测结果如图4所示。
图3 连接形式
图4 检测结果
|