STM32模拟I2C获取TCS34725光学颜色传感器数据

news2024/9/21 15:31:06

STM32模拟I2C获取TCS34725光学颜色传感器数据

TCS34725是RGB三色颜色传感器,和TCS34727都属于TCS3472系列,在电气特性上略有差别,TCS34727相比TCS34725在I2C总线的访问电平上可以更低,而在I2C软件访问地址方面则一致。
在这里插入图片描述

在这里插入图片描述
TCS3472内部有4个PD(光电二极管),一个接收clear light(净光,未做任何处理),另外三个分别接收Red, Green, Blue的三色光,并且会滤除红外光。

TCS3472访问特征

  1. TCS34725和TCS34727软件方面在Device ID不同(非I2C访问地址),其它方面则相同。
    在这里插入图片描述
  2. TCS3472在做寄存器访问时,5位寄存器地址在命令字节里发布:
    在这里插入图片描述
    而在进行有效的命令字节发布时,这个字节最高位要求为1。而命令字节的TYPE则是访问过程的功能指定,为00时说明后面按byte直接访问寄存器,为01则说明后面按照byte连续操作方式操作寄存器(连读),这个时候有个影子寄存器的功能,保证对于两个字节的数据读取,前一个字节读的时候后一个字节被保护,避免前一个字节读完要读后一个字节前,后一个寄存器的数据被新的数据过来改写了,从而产生不一致。10为保留无功能。11则为特殊功能指定,在原本指定地址的位置,可以设置具体的特殊功能,当前只有00110一个功能。
    在这里插入图片描述

3 通过使能AEN位可以启动光学颜色检测,而WEN位用于控制运行模式,WEN设置为0,则光学检测是循环无间断进行,前一次检测出来马上进行下一次检测(每次检测占用一定的延时);当WEN设置为1,则两次检测之间可以插入等待时间,起到节省功耗的作用。AIEN位则是控制是否使用门限可设置的中断产生。
4. TCS3472的输出寄存器是16位,采用可控制积分时间和放大增益的方式,所以得到的结果可以大于255,更长的积分时间和放大增益用于距离较远或者弱光环境的测试。在这里插入图片描述
积分时间为2.4ms相当于进行了10次ADC采样值的求和。
在这里插入图片描述
有4级接收光强放大可选,分别为1倍,4倍,16倍和60倍。

STM32工程配置

这里以STM32F103C6T6芯片及STM32CUBEIDE开发环境,实现访问获取TCS34725传感器的数据。
首先建立工程并配置时钟:
在这里插入图片描述
配置PB12和PB13作为模拟I2C的管脚:
在这里插入图片描述
采用USB虚拟串口作为输出方式,配置USB虚拟串口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存并生成基础工程代码:
在这里插入图片描述

STM32模拟I2C协议代码

STM32模拟I2C协议代码需要用到微秒延时函数,这里采用 STM32 HAL us delay(微秒延时)的指令延时实现方式及优化 。

TCS3472访问部分的函数为:

#define us_num 50

#define SCL_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define SCL_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define SDA_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET)
#define SDA_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET)
#define SDA_IN HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)

void I2C_Init(void)
{
	SDA_OUT_H;
	SCL_OUT_H;
	PY_Delay_us_t(1000000) ;
}

void I2C_Start(void)
{
	PY_Delay_us_t(us_num) ;
	SDA_OUT_H;
	SCL_OUT_H;
	PY_Delay_us_t(us_num/2) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SCL_OUT_L;
}

void I2C_Stop(void)
{
	SCL_OUT_L;
	PY_Delay_us_t(us_num) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SDA_OUT_H;
	PY_Delay_us_t(us_num) ;
}

void I2C_Write_Ack(void)
{

    PY_Delay_us_t(us_num/2) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_L;
	SDA_OUT_H;

}

uint8_t I2C_Read_Ack(void)
{
	uint8_t status=0;

	SCL_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SDA_OUT_H;
	PY_Delay_us_t(us_num/2) ;
	status = SDA_IN;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_L;
	SDA_OUT_L;

	return status;

}


void I2C_Send_Byte(uint8_t txd)
{


    for(uint8_t i=0;i<8;i++)
    {
    	PY_Delay_us_t(us_num/2) ;
        if((txd&0x80)>>7) SDA_OUT_H;
        else SDA_OUT_L;
        txd<<=1;
        PY_Delay_us_t(us_num/2) ;
        SCL_OUT_H;
        PY_Delay_us_t(us_num) ;
		SCL_OUT_L;
    }

    SDA_OUT_L;
}

uint8_t I2C_Read_Byte(unsigned char rdack)
{
	uint8_t rxd=0;


    for(uint8_t i=0;i<8;i++ )
	{
    	SCL_OUT_L;
    	PY_Delay_us_t(us_num/2) ;
    	SDA_OUT_H;
    	PY_Delay_us_t(us_num/2) ;
    	SCL_OUT_H;
        rxd<<=1;
        if(SDA_IN) rxd++;
        PY_Delay_us_t(us_num) ;
    }

    SCL_OUT_L;
    SDA_OUT_H;

    if (rdack) I2C_Write_Ack();

    return rxd;
}

uint8_t TCS3472_Enable_Status = 0;
void TCS3472_WRITE( uint8_t WrAddr, uint8_t data)
{
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(WrAddr|0x80);
  	  I2C_Read_Ack();
  	  I2C_Send_Byte(data);
  	  I2C_Read_Ack();
  	  I2C_Stop();
}

uint8_t TCS3472_READ_1Byte( uint8_t RdAddr)
{

	  uint8_t RegValue = 0;
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(RdAddr|0x80); //Repeated byte protocol transaction
  	  I2C_Read_Ack();

  	  I2C_Start();
	  I2C_Send_Byte(daddr+1);
	  I2C_Read_Ack();
	  RegValue=I2C_Read_Byte(0);
  	  I2C_Stop();

	  return RegValue;
}

uint16_t TCS3472_READ_2Byte( uint8_t RdAddr)
{

	  uint8_t RegValueH = 0, RegValueL = 0;
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(RdAddr|0xa0); //Auto-increment protocol transaction
  	  I2C_Read_Ack();

  	  I2C_Start();
	  I2C_Send_Byte(daddr+1);
	  I2C_Read_Ack();
	  RegValueL=I2C_Read_Byte(1);
	  RegValueH=I2C_Read_Byte(0);
  	  I2C_Stop();

	  return (((uint16_t)RegValueH)<<8)|RegValueL;
}
void TCS3472_PON_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_PON;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_PON_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_PON);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}


void TCS3472_AEN_Enable(void)
{
	TCS3472_Enable_Status |=  TCS3472_ENABLE_AEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_AEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_AEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_WEN_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_WEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_WEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_AIEN_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_AIEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_AIEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

uint8_t TCS3472_ID_Verification(void)
{
	uint8_t id;
	id = TCS3472_READ_1Byte(TCS3472_ID);
	if((id==0x44)||(id==0x4d)) return 1;
	else return 0;
}

COLOR_RGBC rgb;
COLOR_HSL  hsl;

//Conversion of RGB to 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;

	//Lightness
	Hsl->l = (maxVal+minVal)/2;   //[0-100]

	if(maxVal == minVal)//if r=g=b, grey
	{
		Hsl->h = 0;
		Hsl->s = 0;
	}
	else
	{
		//Hue
		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;
			}

		//Saturation
		if(Hsl->l<=50)Hsl->s=difVal*100/(maxVal+minVal);  //[0-100]
		else
			Hsl->s=difVal*100/(200-(maxVal+minVal));
	}
}

STM32完整工程代码

完整工程代码先读取Device ID以判断基本访问是否正常,再进行积分时间24ms及增益1x的配置,再开始数据采样和读取,读取到的数据是积分后的数据,并进行HSL格式的转换。通过USB虚拟串口将数据打印输出。

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
//Written by Pegasus Yu in 2022
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <math.h>

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = HAL_GetTick()+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = HAL_GetTick();
  PY_Delay_us_t(1000000) ;
  secondms = HAL_GetTick();

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}

void PY_Delay_us(uint32_t Delay)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = Delay/1000;
  __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}


/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define us_num 50

#define SCL_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define SCL_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define SDA_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET)
#define SDA_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET)
#define SDA_IN HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)

void I2C_Init(void)
{
	SDA_OUT_H;
	SCL_OUT_H;
	PY_Delay_us_t(1000000) ;
}

void I2C_Start(void)
{
	PY_Delay_us_t(us_num) ;
	SDA_OUT_H;
	SCL_OUT_H;
	PY_Delay_us_t(us_num/2) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SCL_OUT_L;
}

void I2C_Stop(void)
{
	SCL_OUT_L;
	PY_Delay_us_t(us_num) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SDA_OUT_H;
	PY_Delay_us_t(us_num) ;
}

void I2C_Write_Ack(void)
{

    PY_Delay_us_t(us_num/2) ;
	SDA_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_L;
	SDA_OUT_H;

}

uint8_t I2C_Read_Ack(void)
{
	uint8_t status=0;

	SCL_OUT_L;
	PY_Delay_us_t(us_num/2) ;
	SDA_OUT_H;
	PY_Delay_us_t(us_num/2) ;
	status = SDA_IN;
	SCL_OUT_H;
	PY_Delay_us_t(us_num) ;
	SCL_OUT_L;
	SDA_OUT_L;

	return status;

}


void I2C_Send_Byte(uint8_t txd)
{


    for(uint8_t i=0;i<8;i++)
    {
    	PY_Delay_us_t(us_num/2) ;
        if((txd&0x80)>>7) SDA_OUT_H;
        else SDA_OUT_L;
        txd<<=1;
        PY_Delay_us_t(us_num/2) ;
        SCL_OUT_H;
        PY_Delay_us_t(us_num) ;
		SCL_OUT_L;
    }

    SDA_OUT_L;
}

uint8_t I2C_Read_Byte(unsigned char rdack)
{
	uint8_t rxd=0;


    for(uint8_t i=0;i<8;i++ )
	{
    	SCL_OUT_L;
    	PY_Delay_us_t(us_num/2) ;
    	SDA_OUT_H;
    	PY_Delay_us_t(us_num/2) ;
    	SCL_OUT_H;
        rxd<<=1;
        if(SDA_IN) rxd++;
        PY_Delay_us_t(us_num) ;
    }

    SCL_OUT_L;
    SDA_OUT_H;

    if (rdack) I2C_Write_Ack();

    return rxd;
}

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint8_t TCS3472_Enable_Status = 0;
void TCS3472_WRITE( uint8_t WrAddr, uint8_t data)
{
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(WrAddr|0x80);
  	  I2C_Read_Ack();
  	  I2C_Send_Byte(data);
  	  I2C_Read_Ack();
  	  I2C_Stop();
}

uint8_t TCS3472_READ_1Byte( uint8_t RdAddr)
{

	  uint8_t RegValue = 0;
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(RdAddr|0x80); //Repeated byte protocol transaction
  	  I2C_Read_Ack();

  	  I2C_Start();
	  I2C_Send_Byte(daddr+1);
	  I2C_Read_Ack();
	  RegValue=I2C_Read_Byte(0);
  	  I2C_Stop();

	  return RegValue;
}

uint16_t TCS3472_READ_2Byte( uint8_t RdAddr)
{

	  uint8_t RegValueH = 0, RegValueL = 0;
	  uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)

	  I2C_Start();
	  I2C_Send_Byte(daddr);
	  I2C_Read_Ack();
  	  I2C_Send_Byte(RdAddr|0xa0); //Auto-increment protocol transaction
  	  I2C_Read_Ack();

  	  I2C_Start();
	  I2C_Send_Byte(daddr+1);
	  I2C_Read_Ack();
	  RegValueL=I2C_Read_Byte(1);
	  RegValueH=I2C_Read_Byte(0);
  	  I2C_Stop();

	  return (((uint16_t)RegValueH)<<8)|RegValueL;
}
void TCS3472_PON_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_PON;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_PON_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_PON);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}


void TCS3472_AEN_Enable(void)
{
	TCS3472_Enable_Status |=  TCS3472_ENABLE_AEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_AEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_AEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_WEN_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_WEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_WEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

void TCS3472_AIEN_Enable(void)
{
	TCS3472_Enable_Status |= TCS3472_ENABLE_AIEN;

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Disable(void)
{
	TCS3472_Enable_Status &= (~TCS3472_ENABLE_AIEN);

	TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}

uint8_t TCS3472_ID_Verification(void)
{
	uint8_t id;
	id = TCS3472_READ_1Byte(TCS3472_ID);
	if((id==0x44)||(id==0x4d)) return 1;
	else return 0;
}

COLOR_RGBC rgb;
COLOR_HSL  hsl;

//Conversion of RGB to 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;

	//Lightness
	Hsl->l = (maxVal+minVal)/2;   //[0-100]

	if(maxVal == minVal)//if r=g=b, grey
	{
		Hsl->h = 0;
		Hsl->s = 0;
	}
	else
	{
		//Hue
		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;
			}

		//Saturation
		if(Hsl->l<=50)Hsl->s=difVal*100/(maxVal+minVal);  //[0-100]
		else
			Hsl->s=difVal*100/(200-(maxVal+minVal));
	}
}
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char PY_Str[512];

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
  PY_usDelayTest();
  PY_usDelayOptimize();

  if (!TCS3472_ID_Verification())  //For communication error verification
  {
	  while(1)
	  {
		  CDC_Transmit_FS("ID READ ERROR!\r\n", strlen("ID READ ERROR!\r\n"));
		  PY_Delay_us(2000000);
	  }
  }
  else  //Initial config
  {
	  TCS3472_PON_Enable(); //Other register config must be after TCS3472_PON_Enable().

	  TCS3472_WRITE(TCS3472_ATIME, TCS3472_INTEGRATIONTIME_24MS);
	  TCS3472_WRITE(TCS3472_CONTROL, TCS3472_GAIN_1X);

	  TCS3472_AEN_Enable();
  }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

      if(TCS3472_READ_1Byte(TCS3472_STATUS) & TCS3472_STATUS_AVALID)
      {
    	  (&rgb)->c = TCS3472_READ_2Byte(TCS3472_CDATAL);
    	  (&rgb)->r	= TCS3472_READ_2Byte(TCS3472_RDATAL);
    	  (&rgb)->g	= TCS3472_READ_2Byte(TCS3472_GDATAL);
		  (&rgb)->b = TCS3472_READ_2Byte(TCS3472_BDATAL);

    	  sprintf( PY_Str, "Clear light value: %d\r\nRed light value: %d\r\nGreen light value: %d\r\nBlue light value: %d\r\n\r\n", (&rgb)->c, (&rgb)->r, (&rgb)->g, (&rgb)->b );
    	  CDC_Transmit_FS(PY_Str, strlen(PY_Str));
    	  PY_Delay_us(1000000);

    	  RGBtoHSL(&rgb,&hsl);
    	  sprintf( PY_Str, "Hue value: %d\r\nSaturation value: %d\r\nLightness value: %d\r\n\r\n", (&hsl)->h, (&hsl)->s, (&hsl)->l );
    	  CDC_Transmit_FS(PY_Str, strlen(PY_Str));

    	  PY_Delay_us(1000000);
      }
      else PY_Delay_us(1);

    /* USER CODE END WHILE */

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

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_SET);

  /*Configure GPIO pins : PB12 PB13 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


代码执行输出效果

代码执行输出效果如下:

在这里插入图片描述

例程下载

STM32F103C6T6获取TCS34725光学颜色传感器数据范例下载(STM32CUBEIDE工程):

可以调整光照强度,颜色物体厚度及背景反光情况进行效果优化。也可以将数据通过全彩显示屏显示以对比颜色及做校准,参考 STM32驱动0.96寸TFT 彩色LCD模块显示 。

–End –

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/690750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode:1431. 拥有最多糖果的孩子(python3解法)

难度&#xff1a;简单 给你一个数组 candies 和一个整数 extraCandies &#xff0c;其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 对每一个孩子&#xff0c;检查是否存在一种方案&#xff0c;将额外的 extraCandies 个糖果分配给孩子们之后&#xff0c;此孩子有 最多 的糖…

Spring Boot中的@RequestMapping注解,如何使用

Spring Boot中的RequestMapping注解 介绍 Spring Boot是一个流行的Java框架&#xff0c;它提供了许多方便的注解和工具&#xff0c;使得Web应用程序的开发变得更加容易。其中&#xff0c;RequestMapping注解是Spring Boot中最常用的注解之一&#xff0c;它可以帮助开发者定义…

django旅游推荐系统-计算机毕设 附源码82884

django旅游推荐系统 摘 要 随着社会的快速发展和人们生活水平的不断提高&#xff0c;旅游已逐渐成为人们生活的重要组成部分&#xff0c;用户能够获取旅游信息的渠道也随信息技术的广泛应用而增加。大量未经过滤的信息在展示给用户的同时&#xff0c;也淹没了用户真正感兴趣的信…

10个图像处理的Python库

在这篇文章中&#xff0c;我们将整理计算机视觉项目中常用的Python库&#xff0c;如果你想进入计算机视觉领域&#xff0c;可以先了解下本文介绍的库&#xff0c;这会对你的工作很有帮助。 1、PIL/Pillow Pillow是一个通用且用户友好的Python库&#xff0c;提供了丰富的函数集…

【MOOC 测验】第5章 链路层

1、局域网的协议结构一般不包括&#xff08; &#xff09; A. 数据链路层B. 网络层C. 物理层D. 介质访问控制层 逻辑链路控制子层、介质访问控制子层、物理层 2、下列关于二维奇偶校验的说法&#xff0c;正确的是&#xff08; &#xff09; A. 可以检测和纠正双比特差错B…

OV Image Sensor PLL设置

本文讨论OV的Image Sensor PLL的配置。 1.PLL的组成和功能 如图为OS08A10的框图&#xff0c;由图可知&#xff0c;Image Sensor其实是一个模数混合的电路&#xff0c;PLL提供了诸如ADC,gain control,MIPI,I2C等电路所用的时钟。 既然 Image Sensor的PLL是Image Senor非常重要…

详解Vue组件系统

Vue渲染的两大基础方式 new 一个Vue的实例 这个我们一般会使用在挂载根节点这一初始化操作上&#xff1a; new Vue({el: #app }) 复制 注册组件并使用 通过Vue.component&#xff08;&#xff09;去注册一个组件&#xff0c;你就可以全局地使用它了&#xff0c;具体体现在…

什么是信号槽机制,如何实现,有什么用?(Qt面试题)

1. 什么是信号槽机制&#xff1f; 信号槽机制&#xff08;Signal-Slot mechanism&#xff09;是一种在软件开发中常用的设计模式&#xff0c;用于实现对象间的通信和事件处理。该机制最初由Qt框架引入并广泛应用&#xff0c;后来也被其他编程框架和库所采用。 信号槽机制通过定…

这样做,轻松拿捏阻焊桥!

PCB表面的一层漆&#xff0c;称为阻焊油墨&#xff0c;也就是PCB线路板阻焊油墨。阻焊油墨是PCB线路板中非常常见、也是主要使用的油墨&#xff0c;一般90%都是绿色&#xff0c;但也有杂色油墨&#xff1a;红色、蓝色、黑色、白色、黄色等。 阻焊油墨的作用就是绝缘&#xff0…

postman持续集成-Jenkins手动构建

Jenkins启动 在jenkins.war文件所在的目录输入cmd打开终端输入: java -jar jenkins.war启动服务,启动后终端的窗口不要关闭 在浏览器地址栏输入:localhost:8080 准备工作 打开已完成并测试无误的postman项目脚本,再次执行测试 导出测试用例集和测试环境两个文件,注意全部…

【换根DP】CF1324F

Maximum White Subtree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意&#xff1a; 思路&#xff1a; 先去树形DP求出DP值&#xff0c;这很好求 设dp[u]为以u为根的子树中白-黑的最大值 初始化就是&#xff1a;如果u本身是黑&#xff0c;那dp[u]-1&#xff0c;否则dp…

K8s(Kubernetes)学习(三):pod概念及相关操作

1 什么是 Pod 摘取官网: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/#working-with-pods 1.1 简介 Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod&#xff08;就像在鲸鱼荚或者豌豆荚中&#xff09;是一组&#xff08;一个或多个&…

【Java面试题】Java基础——面向对象

文章目录 重载和重写的区别★★★Java的三大特性请说明一下Super关键字的作用&#xff1f;static关键字的作用&#xff1f;final关键字的作用&#xff1f;super关键字和this关键字的作用&#xff1f;面向对象的三大特性★★★成员变量和局部变量的区别&#xff1f;Java能实现多…

JMeter请求头添加删除方法(解决请求头类型冲突)

JMeter请求头添加删除方法&#xff08;解决请求头类型冲突&#xff09; 1. 为什么会有冲突 请求头的Content-Type类型在做上传和请求图片地址是&#xff0c;请求头类型是不一样的 请求图片地址&#xff1a;Content-Type: image/jpeg 一般的Restful接口&#xff1a;Content-Ty…

Linux使用第三方库链接的使用方式——静态式

目录 二.第三方库为静态库时&#xff1a; 方法1&#xff1a; 两个窗口去分别模拟两个窗口公司A(客户端)&#xff0c;公司B(服务端)的视角案例实现&#xff1a; 方法2——优化&#xff1a;该方法在上述方法1的第10步后开始进行&#xff1a; 这里强调一个问题&#xff1a; 今天…

linux上虚拟机vmware-workstation离线安装详细教程

linux上虚拟机vmware-workstation详细教程 一、VMWare基本介绍二、VMWare下载2.1 查看本地系统信息2.2 选择及下载合适的版本 三、VMWare安装3.1 安装依赖库3.2 vmware安装3.3 验证安装3.4 异常及解决方案3.4.1 Failed to start SYSV3.4.2 GLib does not have GSettings suppor…

编程:“上学时如果遇到自己,我会更早的成为我?”

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 如果当年我遇到自己&#xff0c;我会更早的成为我&#xff1f; 你觉得一瞬间的技术能力提升&#xff0c;是必须经历过过吃苦或者…

Python安装教程(初学者很实用)

一、Python环境搭建 1、下载Python 进入Python官网下载安装包 https://www.python.org/ 2、选择合适的版本&#xff0c;点击下载 3、安装Python 双击安装软件 等待安装完成 出现【setup was successful】&#xff0c;表示安装成功 4、检验是否安装成功 通过【winr】调出…

llama.cpp LLM模型 windows cpu安装部署

参考&#xff1a; https://www.listera.top/ji-xu-zhe-teng-xia-chinese-llama-alpaca/ https://blog.csdn.net/qq_38238956/article/details/130113599 cmake windows安装参考&#xff1a;https://blog.csdn.net/weixin_42357472/article/details/131314105 llama.cpp下载编…

DAY30:回溯算法(五)分割回文串+复原IP地址(注意复盘,经典的分割子集问题)

文章目录 131.分割回文串思路伪代码重要问题1&#xff1a;如何通过startIndex判断已经切到结束了重要问题2&#xff1a;为什么[startIndex,i]能够表示当前遍历的子串substr的用法 std::string的成员函数std::string完整版debug测试**Line 4: Char 27: error: expected unqualif…