FastBond2阶段2-基于STM32G0的照度计
喜欢看书,但是又担心环境照度是否足够,所以就做了一个便携照度测量仪。
标签
FastBond2
STM32G0
照度计
冷月烟
更新2023-10-07
794

项目介绍

喜欢看书,但是又担心环境照度是否足够,所以就做了一个便携照度测量仪。

照度计又称照度仪(或称勒克斯计),是一种专门测量光度、亮度的仪器仪表,由主机和一个光传感器组成,常用于测量室内灯具的照度。它所测的光照强度就是物体被照明的程度,也即物体表面所得到的光通量与被照面积之比。照度计通常是由硒光电池或硅光电池,以及微安表组成。照度测量应采用不低于一级的照度计。照度计由光度头(又称受光探头,包括接收器、V(λ)对滤光器、余弦修正器)和读数显示器两部分组成。

Fp1j8gJRaz0mNY25qVI21-Ce88gB

 

市场应用介绍

家庭使用,可携带式体积小、重量轻。


项目设计思路

本次设计将采用STM32G0作为主控芯片,BH1750FVI进行亮度采集。


项目方案框图和原理图

FgKoGowfTePUvybjHEbDcHMUDKMZ

Fom3oFlMK7UH8E6uY9_b2R0mr2FT

 

设计中用到规定厂商的元器件介绍

1.STM32G031

en.obn_STM32G0x1_line_LN2048.jpg

STM32G031x4/x6/x8主流微控制器基于高性能Arm Cortex-M0+ 32位RISC内核,工作频率高达64 MHz。它们具有高集成度,适用于消费、工业和家电领域的广泛应用,并为物联网 (IoT) 解决方案做好准备。

这些器件集成了存储器保护单元 (MPU)、高速嵌入式存储器(8 KB SRAM 和高达 64 KB 的闪存程序存储器,具有读保护、写保护、专有代码保护和安全区域)、DMA、广泛的系统功能、增强型 I/O 和外设。这些器件提供标准通信接口(两个I2Cs,两个 SPI / 一个 I2S和两个USART)、一个12-bit ADC (2.5 MSps)、一个内部基准电压缓冲器、一个低功耗RTC、一个以高达两倍CPU频率运行的高级控制PWM定时器、四个通用16位定时器、一个32位通用定时器、两个低功耗16位定时器、两个看门狗定时器和一个SysTick定时器。

这些器件可在 -40 至 125°C 的环境温度和 1.7 V 至 3.6 V 的电源电压下工作。 优化的动态功耗与一套全面的节能模式、低功耗定时器和低功耗UART相结合,允许设计低功耗应用。

VBAT直接电池输入允许保持RTC和备份寄存器供电。

这些器件采用 8 至 48 引脚封装。

 

2.BH1750FVI

BH1750FVI数字光照传感器是测量环境的光照强度的数字传感器,它能够通过I2C接口与MCU连接,输出数字信号。该传感器采用亮度校准和温度校准的先进技术,能够在各种光线条件下提供准确的光照测量结果。其超小的封装和低功耗特性,使得它成为了广泛应用于各种便携式智能设备、LED照明以及室内智能家居与办公环境的理想选择。

BH1750FVI传感器特性如下:

1.补偿功能:传感器采用了先进亮度校准和温度校准技术,能够提供高精度的光照测量结果。

2.数字接口:传感器具有I2C数字接口,可与微控制器(MCU)直接连接。

3.全面量程:传感器测量范围为0到65535(等于0.11到100000lx)。

4.低功耗特性:传感器在低功耗模式下只需消耗1uA的电流。

5.小型封装:BH1750FVI使用极小的封装,可在小型的智能设备中使用。

 

3.XC6206

 XC6206 系列是一款高精度低功耗的 LDO 线性稳压芯片,即使在输出电流较大的情况下,其输入与输出之间的压差依然较小。其常见的 SOT-23-3 封装通常拥有 输入、输出、接地 三个引脚,内部包含了限流电路、驱动三极管、高精度参考电压源、误差校正电路:XC6206 系列的性能参数如下:

  • 最大输出电流    200mA (3.0V type)
  • 输入输出压差    250mV @ 100mA (3.0V type)
  • 最大工作电压    6.0V
  • 输出电压范围    1.2V ~ 5.0V (0.1V 递进)
  • 输出精度    $$、$\pm30mV@V_{OUT}<1.5V$、$\pm1\% @V_{OUT}\ge2.0V$
  • 低功耗    典型值为 1.0 μA
  • 输出电容类型    可以兼容低 ESR 的陶瓷电容
  • 保护措施    内置限流电路
  • 工作环境温度    -40℃ ~ 85℃

XC6206 系列可以选用较低等效串联电阻(ESR,Equivalent Series Resistance)的陶瓷电容,并且可以由内部的限流电路提供输出引脚的短路保护。


PCB绘制打板介绍及遇到的问题和解决方法

绘制的时候,主芯片不小心镜像了,焊接的时候,芯片只能反过来焊接。

 

关键代码及说明

主要代码

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_I2C2_Init();
  MX_TIM1_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  OLED_Init();
  BH1750_Init();
  while(1)
  {
      HAL_Delay(200);
      OLED_ShowNum(0,0,BH1750_Read(),5,32);
      OLED_ShowString(80,0,"Lux",32);
  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  /* USER CODE END 3 */
}

 

OLED驱动

#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"  	
#include "i2c.h"

/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
    uint8_t data[1] = {IIC_Command};
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, data, 1, 0xff);
}
/**********************************************
 IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
    uint8_t data[1] = {IIC_Data};
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, data, 1, 0xff);
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
    if(cmd)
    {
        Write_IIC_Data(dat);
    }
    else
    {
        Write_IIC_Command(dat);
    }
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
	unsigned char m,n;
	for(m=0;m<8;m++)
	{
		OLED_WR_Byte(0xb0+m,0);		//page0-page1
		OLED_WR_Byte(0x00,0);		//low column start address
		OLED_WR_Byte(0x10,0);		//high column start address
		for(n=0;n<128;n++)
			{
				OLED_WR_Byte(fill_Data,1);
			}
	}
}

//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 	OLED_WR_Byte(0xb0+y,OLED_CMD);
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
	OLED_WR_Byte((x&0x0f),OLED_CMD); 
}   	  
   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
	uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
	} //更新显示
}
void OLED_On(void)  
{  
	uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); 
	} //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{      	
	unsigned char c=0,i=0;	
    c=chr-' ';//得到偏移后的值			
    if(x>Max_Column-1)
    {
        x=0;
        y=y+2;
    }
    if(Char_Size ==16)
    {
        OLED_Set_Pos(x,y);	
        for(i=0;i<8;i++)
            OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<8;i++)
            OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
    }
    else if(Char_Size ==32)
    {
        OLED_Set_Pos(x,y);	
        for(i=0;i<16;i++)
            OLED_WR_Byte(F16X32[c*64+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<16;i++)
            OLED_WR_Byte(F16X32[c*64+i+16],OLED_DATA);
        OLED_Set_Pos(x,y+2);
        for(i=0;i<16;i++)
            OLED_WR_Byte(F16X32[c*64+i+16*2],OLED_DATA);
        OLED_Set_Pos(x,y+3);
        for(i=0;i<16;i++)
            OLED_WR_Byte(F16X32[c*64+i+16*3],OLED_DATA);
    }
    else 
    {	
        OLED_Set_Pos(x,y);
        for(i=0;i<6;i++)
            OLED_WR_Byte(F6x8[c][i],OLED_DATA);
    }
}
//m^n函数
uint32_t oled_pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;	 
	while(n--)result*=m;    
	return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{         	
	uint8_t t,temp;
	uint8_t enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
	}
} 
//显示一个字符号串
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		
        if(Char_Size == 16)
        {
            OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=8;
            if(x>120)
            {
                x=0;
                y+=2;
            }
            j++;
        }
        else if(Char_Size == 32)
        {
            OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=16;
            j++;
        }
	}
}
//显示汉字
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{      			    
    uint8_t t,adder=0;
    OLED_Set_Pos(x,y);	
    for(t=0;t<16;t++)
    {
        OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
        adder+=1;
    }	
    OLED_Set_Pos(x,y+1);	
    for(t=0;t<16;t++)
    {	
        OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
        adder+=1;
    }					
}

//初始化SSD1306					    
void OLED_Init(void)
{ 	
    HAL_Delay(200);
    OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示	
	OLED_WR_Byte(0x40,OLED_CMD);//---set low column address
	OLED_WR_Byte(0xB0,OLED_CMD);//---set high column address
	OLED_WR_Byte(0xC8,OLED_CMD);//-not offset
	OLED_WR_Byte(0x81,OLED_CMD);//设置对比度
	OLED_WR_Byte(0xff,OLED_CMD);
	OLED_WR_Byte(0xa1,OLED_CMD);//段重定向设置
	OLED_WR_Byte(0xa6,OLED_CMD);//
	OLED_WR_Byte(0xa8,OLED_CMD);//设置驱动路数
	OLED_WR_Byte(0x1f,OLED_CMD);
	OLED_WR_Byte(0xd3,OLED_CMD);
	OLED_WR_Byte(0x00,OLED_CMD);
	OLED_WR_Byte(0xd5,OLED_CMD);
	OLED_WR_Byte(0xf0,OLED_CMD);
	OLED_WR_Byte(0xd9,OLED_CMD);
	OLED_WR_Byte(0x22,OLED_CMD);
	OLED_WR_Byte(0xda,OLED_CMD);
	OLED_WR_Byte(0x02,OLED_CMD);
	OLED_WR_Byte(0xdb,OLED_CMD);
	OLED_WR_Byte(0x49,OLED_CMD);
	OLED_WR_Byte(0x8d,OLED_CMD);
	OLED_WR_Byte(0x14,OLED_CMD);
	OLED_WR_Byte(0xaf,OLED_CMD);
	OLED_Clear();
}  

 

BH1750驱动

#include  "BH1750.h"
#include "i2c.h"

uint16_t BH1750_Read(void)
{   
    uint8_t data[2];
    HAL_I2C_Master_Receive(&hi2c2, 0x46, data, 2, 0xff);
    return (uint16_t)((float)(((uint16_t)data[0]<<8) | data[1])/1.2);
}

//初始化BH1750,根据需要请参考pdf进行修改****
void BH1750_Init()
{
    uint8_t data[1] = {0x01};
    HAL_I2C_Master_Transmit(&hi2c2, 0x46, data, 1, 0xff);
    data[0] = 0x10;
    HAL_I2C_Master_Transmit(&hi2c2, 0x46, data, 1, 0xff); 
}

 

功能展示及说明

设备裸机样式

FpL4F0zYsvlyoa15VbolDnVotkvc

卧室灯下测量效果

FmH8BnQjb14scWdB6d2Oknvm6pDV

手机闪光灯照射效果

Fmuv0W86HC5E82_ezkFHGc4qx3zU


对本大赛的心得体会

无,活动挺好

软硬件
电路图
附件下载
PCB.zip
代码.zip
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号