STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux

这篇具有很好参考价值的文章主要介绍了STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.3472能提供红,绿,蓝色(RGB)和清晰光感应值的数字输出

2.它通过 I2C协议通讯。

3.最好选择带led灯的版本,自带的led低电平能关闭。

4.这边VIN接5V电压输入,GND接GND,SCL接SCL(PF1)SDA接SDA(PF0),这边根据自己启动的IO口进行变换

STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 5.我这边采用STM32Cube生成使用硬件I2C的方式进行通信,注意这边有7bit和10bit,默认7bit

STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 6.这边注意最好设置成上拉模式,防止某些设备没有上拉STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 7.点击生成后打开Keil5开始编辑代码;先了解一下HAL库如何写入和读取I2C 设备的吧

可以看到Hal_i2c库里面提供了轮询,中断,DMA的方式进行读写I2C,这边我们使用轮询的方式进行读取TCS3472

STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 8.首先新建一个.H文件,把TCS3472的一写配置文件编写进行,我这边也是拷贝别人的,代码如下:

介绍一下函数:

1.void SwicthI2c(char sw);  //这个我是用来切换不同I2C 接口的,跟实际使用没有影响

2.unsigned char TCS34725_Init(void); //这是用来初始化TCS34725芯片的

3.char TCS34725_GetRawData(COLOR_RGBC *rgbc);//这个是用来读取RGBC的参数值

4.void RGBtoHSL(COLOR_RGBC *Rgb, COLOR_HSL *Hsl);//这个是将读取到的RGBC值转换为HSL色盘

5.void RGBto255RGB(COLOR_RGBC *Rgb,Sepan_RGBC *RGB255);//这部分计算RGB的占比以255:255:255呈现和Lux值

6.double calculateColorTemperature(COLOR_RGBC *Rgb);//这部分是计算色温

#ifndef __TCS3472ColourSensor_H
#define __TCS3472ColourSensor_H

#include "usart.h"
#include "stdio.h"
#include "cmsis_os.h"
#include "i2c.h"


/******************************************************************************/
#define TCS34725_ADDRESS          (0x29)

#define TCS34725_COMMAND_BIT      (0x80)

#define TCS34725_ENABLE           (0x00)
#define TCS34725_ENABLE_AIEN      (0x10)    /* RGBC Interrupt Enable */
#define TCS34725_ENABLE_WEN       (0x08)    /* Wait enable - Writing 1 activates the wait timer */
#define TCS34725_ENABLE_AEN       (0x02)    /* RGBC Enable - Writing 1 actives the ADC, 0 disables it */
#define TCS34725_ENABLE_PON       (0x01)    /* Power on - Writing 1 activates the internal oscillator, 0 disables it */
#define TCS34725_ATIME            (0x01)    /* Integration time */
#define TCS34725_WTIME            (0x03)    /* Wait time (if TCS34725_ENABLE_WEN is asserted) */
#define TCS34725_WTIME_2_4MS      (0xFF)    /* WLONG0 = 2.4ms   WLONG1 = 0.029s */
#define TCS34725_WTIME_204MS      (0xAB)    /* WLONG0 = 204ms   WLONG1 = 2.45s  */
#define TCS34725_WTIME_614MS      (0x00)    /* WLONG0 = 614ms   WLONG1 = 7.4s   */
#define TCS34725_AILTL            (0x04)    /* Clear channel lower interrupt threshold */
#define TCS34725_AILTH            (0x05)
#define TCS34725_AIHTL            (0x06)    /* Clear channel upper interrupt threshold */
#define TCS34725_AIHTH            (0x07)
#define TCS34725_PERS             (0x0C)    /* Persistence register - basic SW filtering mechanism for interrupts */
#define TCS34725_PERS_NONE        (0b0000)  /* Every RGBC cycle generates an interrupt                                */
#define TCS34725_PERS_1_CYCLE     (0b0001)  /* 1 clean channel value outside threshold range generates an interrupt   */
#define TCS34725_PERS_2_CYCLE     (0b0010)  /* 2 clean channel values outside threshold range generates an interrupt  */
#define TCS34725_PERS_3_CYCLE     (0b0011)  /* 3 clean channel values outside threshold range generates an interrupt  */
#define TCS34725_PERS_5_CYCLE     (0b0100)  /* 5 clean channel values outside threshold range generates an interrupt  */
#define TCS34725_PERS_10_CYCLE    (0b0101)  /* 10 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_15_CYCLE    (0b0110)  /* 15 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_20_CYCLE    (0b0111)  /* 20 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_25_CYCLE    (0b1000)  /* 25 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_30_CYCLE    (0b1001)  /* 30 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_35_CYCLE    (0b1010)  /* 35 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_40_CYCLE    (0b1011)  /* 40 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_45_CYCLE    (0b1100)  /* 45 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_50_CYCLE    (0b1101)  /* 50 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_55_CYCLE    (0b1110)  /* 55 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_60_CYCLE    (0b1111)  /* 60 clean channel values outside threshold range generates an interrupt */
#define TCS34725_CONFIG           (0x0D)
#define TCS34725_CONFIG_WLONG     (0x02)    /* Choose between short and long (12x) wait times via TCS34725_WTIME */
#define TCS34725_CONTROL          (0x0F)    /* Set the gain level for the sensor */
#define TCS34725_ID               (0x12)    /* 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
#define TCS34725_STATUS           (0x13)
#define TCS34725_STATUS_AINT      (0x10)    /* RGBC Clean channel interrupt */
#define TCS34725_STATUS_AVALID    (0x01)    /* Indicates that the RGBC channels have completed an integration cycle */
#define TCS34725_CDATAL           (0x14)    /* Clear channel data */
#define TCS34725_CDATAH           (0x15)
#define TCS34725_RDATAL           (0x16)    /* Red channel data */
#define TCS34725_RDATAH           (0x17)
#define TCS34725_GDATAL           (0x18)    /* Green channel data */
#define TCS34725_GDATAH           (0x19)
#define TCS34725_BDATAL           (0x1A)    /* Blue channel data */
#define TCS34725_BDATAH           (0x1B)

#define TCS34725_INTEGRATIONTIME_2_4MS   0xFF   /**<  2.4ms - 1 cycle    - Max Count: 1024  */
#define TCS34725_INTEGRATIONTIME_24MS    0xF6   /**<  24ms  - 10 cycles  - Max Count: 10240 */
#define TCS34725_INTEGRATIONTIME_50MS    0xEB   /**<  50ms  - 20 cycles  - Max Count: 20480 */
#define TCS34725_INTEGRATIONTIME_101MS   0xD5   /**<  101ms - 42 cycles  - Max Count: 43008 */
#define TCS34725_INTEGRATIONTIME_154MS   0xC0   /**<  154ms - 64 cycles  - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_240MS   0x9C   /**<  240ms - 100 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_700MS   0x00   /**<  700ms - 256 cycles - Max Count: 65535 */

#define TCS34725_GAIN_1X                 0x00   /**<  No gain  */
#define TCS34725_GAIN_4X                 0x01   /**<  4x gain  */
#define TCS34725_GAIN_16X                0x02   /**<  16x gain */
#define TCS34725_GAIN_60X                0x03   /**<  60x gain */
/******************************************************************************/
typedef struct{
	unsigned short  c;      //[0-65536]
	unsigned short  r;
	unsigned short  g;
	unsigned short  b;
}COLOR_RGBC;//RGBC

typedef struct{
	unsigned char  r;     //[0-255]
	unsigned char  g;
	unsigned char  b;
	unsigned short Lux;
}Sepan_RGBC;//RGBC


typedef struct{
	unsigned short h;       //[0,360]
	unsigned char  s;       //[0,100]
	unsigned char  l;       //[0,100]
}COLOR_HSL;//HSL


#define max3v(v1, v2, v3)   ((v1)<(v2)? ((v2)<(v3)?(v3):(v2)):((v1)<(v3)?(v3):(v1)))
#define min3v(v1, v2, v3)   ((v1)>(v2)? ((v2)>(v3)?(v3):(v2)):((v1)>(v3)?(v3):(v1)))

void SwicthI2c(char sw);
unsigned char TCS34725_Init(void);
char TCS34725_GetRawData(COLOR_RGBC *rgbc);
void RGBtoHSL(COLOR_RGBC *Rgb, COLOR_HSL *Hsl);
void RGBto255RGB(COLOR_RGBC *Rgb,Sepan_RGBC *RGB255);
double calculateColorTemperature(COLOR_RGBC *Rgb);
#endif

9.好的,接下来我们来介绍.C文件和各个函数如何实现的

#include "TCS3472ColourSensor.h"

COLOR_RGBC rgb;
COLOR_HSL  hsl;
/*
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    PF0     ------> I2C2_SDA
    PF1     ------> I2C2_SCL
*/
I2C_HandleTypeDef *I2cx;
void SwicthI2c(char sw)
{
	if(sw==2)I2cx=&hi2c2;
	else I2cx=&hi2c1;
}

char TCS34725_Read(uint8_t subAddr,unsigned char *dataBuffer, uint16_t bytesNumber)
{
	subAddr |= TCS34725_COMMAND_BIT;
	uint8_t sendadd = (TCS34725_ADDRESS << 1) | 0x00;
	if(HAL_I2C_Master_Transmit(I2cx,sendadd,&subAddr,1,1000)==0x00)
	{
		sendadd = (TCS34725_ADDRESS << 1) | 0x01;
		if(HAL_I2C_Master_Receive(I2cx,sendadd,dataBuffer,bytesNumber,1000)==0x00)
		{
			return 1;
		}
		
	}
	return 0;
}

char TCS34725_Write(uint8_t subAddr,uint8_t *dataBuffer,uint16_t bytesNumber)
{
	uint8_t sendadd = (TCS34725_ADDRESS << 1) | 0x00;
	uint8_t sendBuffer[10]={0,};
	sendBuffer[0]=subAddr|TCS34725_COMMAND_BIT;
	for(uint8_t i=1;i<=bytesNumber;i++)
	{
		sendBuffer[i]=dataBuffer[i-1];
	}
	if(HAL_I2C_Master_Transmit(I2cx,sendadd,sendBuffer,bytesNumber+1,1000)==0)
	{
		return 1;
	}

	return 0;
}


void TCS34725_SetIntegrationTime(uint8_t time)
{
	TCS34725_Write(TCS34725_ATIME,&time,1);
}
void TCS34725_SetGain(uint8_t gain)
{
	TCS34725_Write(TCS34725_CONTROL, &gain, 1);
}
void TCS34725_Enable(void)
{
	uint8_t cmd = TCS34725_ENABLE_PON;
	
	TCS34725_Write(TCS34725_ENABLE, &cmd, 1);
	cmd = TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN;
	TCS34725_Write(TCS34725_ENABLE, &cmd, 1);
}

unsigned char TCS34725_Init(void)
{
	unsigned char id=0;
	uint16_t number=0;
	uint8_t status = TCS34725_STATUS_AVALID;
	TCS34725_Read(TCS34725_ID,&id,1);
	printf("Read I2C ID:%02X\r\n",id);
	if(id==0x4D || id ==0x44)
	{
		TCS34725_SetIntegrationTime(TCS34725_INTEGRATIONTIME_154MS);//转换时间
//		TCS34725_SetIntegrationTime(TCS34725_INTEGRATIONTIME_50MS);
		TCS34725_SetGain(TCS34725_GAIN_16X);
		TCS34725_Enable();
		return 1;
	}
	return 0;
}


/*******************************************************************************
 * @brief TCS34725获取单个通道数据
 *
 * @return data - 该通道的转换值
*******************************************************************************/
uint16_t TCS34725_GetChannelData(uint8_t reg)
{
	uint8_t tmp[2] = {0,0};
	uint16_t data;
	
	TCS34725_Read(reg, tmp, 2);
	data = (tmp[1] << 8) | tmp[0];
	return data;
}
/*******************************************************************************
 * @brief TCS34725获取各个通道数据
 *
 * @return 1 - 转换完成,数据可用
 *   	   0 - 转换未完成,数据不可用
*******************************************************************************/
char TCS34725_GetRawData(COLOR_RGBC *rgbc)
{
	uint8_t status = TCS34725_STATUS_AVALID;
	
	TCS34725_Read(TCS34725_STATUS, &status, 1);
	
	if(status & TCS34725_STATUS_AVALID)
	{
		rgbc->c = TCS34725_GetChannelData(TCS34725_CDATAL);	
		rgbc->r = TCS34725_GetChannelData(TCS34725_RDATAL);	
		rgbc->g = TCS34725_GetChannelData(TCS34725_GDATAL);	
		rgbc->b = TCS34725_GetChannelData(TCS34725_BDATAL);
		return 1;
	}
	return 0;
}
/******************************************************************************/
//RGB转HSL
void RGBtoHSL(COLOR_RGBC *Rgb, COLOR_HSL *Hsl)
{
	uint8_t maxVal,minVal,difVal;
	uint8_t r = Rgb->r*100/Rgb->c;   //[0-100]
	uint8_t g = Rgb->g*100/Rgb->c;
	uint8_t b = Rgb->b*100/Rgb->c;
	
	maxVal = max3v(r,g,b);
	minVal = min3v(r,g,b);
	difVal = maxVal-minVal;
	
	//计算亮度
	Hsl->l = (maxVal+minVal)/2;   //[0-100]
	
	if(maxVal == minVal)//若r=g=b,灰度
	{
		Hsl->h = 0; 
		Hsl->s = 0;
	}
	else
	{
		//计算色调
		if(maxVal==r)
		{
			if(g>=b)
				Hsl->h = 60*(g-b)/difVal;
			else
				Hsl->h = 60*(g-b)/difVal+360;
		}
		else
			{
				if(maxVal==g)Hsl->h = 60*(b-r)/difVal+120;
				else
					if(maxVal==b)Hsl->h = 60*(r-g)/difVal+240;
			}
		
		//计算饱和度
		if(Hsl->l<=50)Hsl->s=difVal*100/(maxVal+minVal);  //[0-100]
		else
			Hsl->s=difVal*100/(200-(maxVal+minVal));
	}
}
/******************************************************************************/
//计算RGB的比例和Lux
void RGBto255RGB(COLOR_RGBC *Rgb,Sepan_RGBC *RGB255)
{
	double maxVal,minVal,difVal;
	double r_255=0.0,g_255=0.0,b_255=0.0;

	r_255 = (double)Rgb->r/Rgb->c*255;
	g_255 = (double)Rgb->g/Rgb->c*255;
	b_255 = (double)Rgb->b/Rgb->c*255;
	
	maxVal = max3v(r_255,g_255,b_255);
	r_255 = r_255/maxVal*255;
	g_255 = g_255/maxVal*255;
	b_255 = b_255/maxVal*255;
	
//	maxVal = max3v(Rgb->r,Rgb->g,Rgb->b);	
//	r_255 = (double)Rgb->r/maxVal*255;
//	g_255 = (double)Rgb->g/maxVal*255;
//	b_255 = (double)Rgb->b/maxVal*255;
	
	RGB255->r = (unsigned char)r_255;
	RGB255->g = (unsigned char)g_255;
	RGB255->b = (unsigned char)b_255;
	double lux=(0.299*Rgb->r)+(0.587*Rgb->g)+(0.114*Rgb->b);
	RGB255->Lux = (unsigned short)lux;
	
	if(RGB255->r==255&&RGB255->g==255&&RGB255->b==255)
	{
		if(Rgb->c<255)
		{
			RGB255->r = 0;
			RGB255->g = 0;
			RGB255->b = 0;
		}
	}
}
//
//计算CCT色温
double calculateColorTemperature(COLOR_RGBC *Rgb)
{
	double trimX = 0;
  double trimY = 0;
  double trimZ = 0;
  double coorX = 0, coorY = 0;
  double CCT = 0;
  double n = 0;
  int R = Rgb->r;//255;
  int G = Rgb->g;//231;
  int B = Rgb->b;//131;

	//以下公式实现RGB转三刺激值
	trimX = 2.789 * R + 1.7517 * G + 1.1302 * B;
	trimY = 1 * R + 4.5907 * G + 0.0601 * B;
	trimZ = 0 * R + 0.0565 * G + 5.5943 * B;
	//以下公式实现三刺激值转色坐标
	coorX = trimX / (trimX + trimY + trimZ);
	coorY = trimY / (trimX + trimY + trimZ);
	n = (coorX - 0.3320) / (0.1858 - coorY);
	//以下公式实现色坐标转色温
	CCT = 437 * n * n * n + 3601 * n * n + 6831 * n + 5517;
	return CCT;
}

10.main函数调用应该不用多讲了吧

printf("I2C2 PF0->I2C2_SDA;PF1-> I2C2_SCL \r\n");
SwicthI2c(2);
TCS34725_Init();
osDelay(500);//这边是需要等待传感器自己转换完成的
TCS34725_GetRawData(&rgb);  
RGBtoHSL(&rgb,&hsl);
RGBto255RGB(&rgb,&rgb_255A);
printf("R=%d G=%d B=%d C=%d\r\n",rgb.r,rgb.g,rgb.b,rgb.c);
printf("H=%d S=%d L=%d\r\n",hsl.h,hsl.s,hsl.l);
printf("R255=%d G255=%d B255=%d Lux=%dCCT:%f\r\n",rgb_255A.r,rgb_255A.g,rgb_255A.b,rgb_255A.Lux,calculateColorTemperature(&rgb));
printf("---------------------------------------------\r\n");

11.测试结果如下:

STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux,stm32,单片机,嵌入式硬件

 文章来源地址https://www.toymoban.com/news/detail-545992.html

到了这里,关于STM32读取TCS3472颜色传感器读取RGB颜色和色温值和Lux的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32配置读取BMP280气压传感器数据

    BMP280是在BMP180基础上增强的绝对气压传感器,在飞控领域的高度识别方面应用也比较多。 BMP280和BMP180的区别: 市面上也有一些模块: 这里介绍STM32芯片和BMP280的连接和数据读取。 BMP280和STM32的供电范围一致,可以在1.8V, 2.5V和3.3V多个供电电压点直接连接。 BMP280和STM32可以通

    2024年02月13日
    浏览(32)
  • STM32读取HX711压力传感器芯片数据

    目录 一、HX711压力传感器芯片介绍 1.1 HX711芯片介绍 1.2 芯片管脚与描述 1.3 芯片特点 二、测量原理 2.1 芯片原理图 2.2 压力传感器输出电压值 2.3 芯片原理概述 2.4 数据输出,输入通道和增益选择时序图 2.5 程序计算原理 2.5.1 如何计算传感器供电电压?  2.5.2 如何将 AD 值反向转

    2024年04月16日
    浏览(37)
  • STM32学习笔记———几种简单传感器的数据读取

    传感器正如计算机的眼睛。从广义上讲,传感器就是一种能感知外界信息,并将这些信息按照一定规律转换成可用的电信号或其他形式的输出信号的装置,达到对信息的存储,传输,控制的目的。本文着重分析如何通过单片机分析电信号时序图实现对传感器的控制与传感器采

    2023年04月23日
    浏览(32)
  • 71、基于STM32单片机的颜色识别感应传感器检测系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、硬件框图 七、程序源码 八、资料包括 随着现代工业生产向高速化、自动化方向的发展,色彩识别广泛应用于各种工业检测和自动控制领域,而生

    2024年02月16日
    浏览(45)
  • STM32—ADC详解入门(ADC读取烟雾传感器的值)

    目录 一、ADC是什么 二、ADC的性能指标 三、ADC特性 四、ADC通道 五、ADC转换顺序 六、ADC触发方式 七、ADC转化时间 八、ADC转化模式 九、实验(使用ADC读取烟雾传感器的值) 1、配置 2、代码         ADC是Analog-to-DigitalConverter的缩写。指模/数转换器或者模拟/数字转换器。是指

    2024年02月11日
    浏览(32)
  • STM32——ADC读取光敏传感器控制LED灯,看门狗中断

    一、编写读取AD值的函数,之后判断AD值,进行相应操作,比如点灯。 二、用ADC读取光敏传感器AO口输出,并配置ADC通道看门狗监控这条通道,当光线太暗时打开LED灯。 之后会再介绍可编程RGB灯带WS2812B。 光敏传感器有两个输出口,一个是DO(Digital Output),一个是AO(Analog O

    2023年04月18日
    浏览(37)
  • STM32CubeMX 读取DS18B20温度传感器数据串口打印显示

    本文要做的所有工作标题基本都包括了,读取温度传感器的温度数值,再通过串口打印到串口助手; 好多博主大神的教程我按步骤做了之后总是出现程序不报错并且检测不到传感器的情况,后来找到原因并且修改后调试正常。 我用的是普中科技的实验板,主控芯片为STM3210

    2024年02月05日
    浏览(72)
  • 【模块系列】STM32&TCS3472

    前言   手上正好有TCS3472模块,也正好想在加深一下自己对I2C协议的理解和应用,所以就写了这个代码库出来。参考的资料主要来源于TCS3472的数据手册,和arduino中MH_TCS3472库的宏定义,和函数名称,我就没有重新命名,方便大家理解和使用修改之类的。 环境 开发板:STM32

    2024年01月20日
    浏览(22)
  • 新手小白必看——基于STM32+ESP8266模块连接阿里云平台读取传感器数据(从0到1,包教包会)

    目录 前言             本次我们学习一下STM32F103驱动ESP8266去连接阿里云的实操过程,在次过程中我会详细讲解开发过程中遇到的问题以及面对问题的解决,希望大家在这篇博客里面也有所收获。 一、ESP8266WIFI模块的固件库刷新(MQTT) 1.固件库刷新 1.1 固件库烧录下载 1.2 固

    2024年04月26日
    浏览(34)
  • STM32-雨滴传感器

    目录 0 说明:  1 传感器介绍  2 代码说明    2.1 ADC初始化函数(adc.c)   2.2 GPIO初始化函数 2.3 主函数         本篇文章主要是说明怎么使用STM32单片机读取雨滴传感器采集到的数据,并且附带着STM32所需要的全部代码,所使用的雨滴传感器如下图所示。 附: 使用单片机

    2024年01月17日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包