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

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 –

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nuget更新全局包、缓存和临时文件夹路径位置

Nuget更新缓存 1、查看默认的Nuget路径2、更改全局包路径2.1 通过环境变量来进行修改2.2通过Nuget.Config配置文件来进行修改 3、更改http-cache路径4、更改temp文件路径5、更改plugins-cache文件路径 NuGet是一个流行的软件包管理器&#xff0c;可以帮助.NET开发人员轻松地添加…

内嵌 iframe 实现PDF预览

效果图如下&#xff1a; 代码如下&#xff1a; <template><div><!-- 控制浮层显示隐藏 --><el-button type"primary" size"small" class"btn" click"dialogVisible true">PDF 预览 (内嵌 iframe)</el-but…

2021 RoboCom 世界机器人开发者大赛-高职组(初赛)

编程题得分&#xff1a;100 总分&#xff1a;100 目录 7-1 机器人打招呼 (5分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 7-2 人脸识别 (10分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例 1&#xff1a; 输…

yolov5增加AFPN-全新特征融合模块AFPN,效果完胜PAFPN

论文学习&#xff1a;AFPN: Asymptotic Feature Pyramid Network for Object Detection-全新特征融合模块AFPN&#xff0c;完胜PAFPN_athrunsunny的博客-CSDN博客 先上配置文件yolov5s-AFPN.yaml # YOLOv5 &#x1f680; by Ultralytics, AGPL-3.0 license# Parameters nc: 80…

OpenCV:深入Feature2D组件——角点检测

角点检测 1 Harris角点检测1.1 兴趣点与角点1.2 角点检测1.3 harris角点检测1.4 实现harris角点检测&#xff1a;cornerHarris()函数1.5 综合案例&#xff1a;harris角点检测与测绘 2. Shi—Tomasi角点检测2.1Shi—Tomasi角点检测概述2.2 确定图像强角点&#xff1a;goodFeatur…

实时包裹信息同步:WebSocket 在 Mendix 中的应用

场景介绍 在现代物流中&#xff0c;能够实时跟踪包裹信息&#xff0c;尤其是包裹重量&#xff0c;是非常重要的。在这种场景中&#xff0c;我们可以使用称重设备获取包裹的信息&#xff0c;然后实时将这些信息同步给 Mendix 开发的 App&#xff0c;并在 App 的页面上实时显示包…

用git下载gitee上的项目资源

目录 用git下载gitee上的项目资源 用git 的clone 命令 然后到gitee上复制相关的下载地址&#xff1a; 粘贴到clone后面即可&#xff08;注意地址与clone之间有空格&#xff01;&#xff01;&#xff01;&#xff09; 运行结果&#xff1a; 用git下载gitee上的项目资源 用git…

MySQL安装与部署

第一种方法&#xff1a;在线安装 配置一个安装yum源 Adding the MySQL Yum Repository 可以手动配置yum源&#xff0c;baseurl指向国内镜像源地址&#xff0c;比如清华、中科大。 Installing MySQL Starting the MySQL Server&#xff1a; 查询临时登录密码 修改数据库密码…

golang 结构体struct转map实践

1、反射 type sign struct { Name string json:"name,omitempty" Age int json:"age,omitempty" } var s sign s.Name "csdn" s.Age 18 //方式1 反射 var data make(map[string]interface{}) t : reflect.TypeOf(s) v : …

Spring Bean的实例化过程

一、前言 对于写Java的程序员来说&#xff0c;Spring已经成为了目前最流行的第三方开源框架之一&#xff0c;在我们充分享受Spring IOC容器带来的红利的同时&#xff0c;我们也应该考虑一下Spring这个大工厂是如何将一个个的Bean生产出来的&#xff0c;本期我们就一起来讨论一…

2023年第三届工业自动化、机器人与控制工程国际会议

会议简介 Brief Introduction 2023年第三届工业自动化、机器人与控制工程国际会议&#xff08;IARCE 2023&#xff09; 会议时间&#xff1a;2023年10月27 -30日 召开地点&#xff1a;中国成都 大会官网&#xff1a;www.iarce.org 2023年第三届工业自动化、机器人与控制工程国际…

Redis通信协议

RESP协议 Redis是一个CS架构的软件&#xff0c;通信一般分两步&#xff08;不包括pipeline和PubSub&#xff09;&#xff1a; ① 客户端&#xff08;client&#xff09;向服务端&#xff08;server&#xff09;发送一条命令 ② 服务端解析并执行命令&#xff0c;返回响应结果…

Spring MVC各种参数进行封装

目录 一、简单数据类型 1.1 控制器方法 1.2 测试结果 二、对象类型 2.1 单个对象 2.1.1 控制器方法 2.1.2 测试结果 2.2 关联对象 2.2.1 控制器方法 2.2.2 测试结果 三、集合类型 3.1 简单数据类型集合 3.1.1 控制方法 3.1.2 测试结果 3.2 对象数据类型集合 3.…

使用MQL4编写自己的交易策略:技巧与经验分享

随着技术的发展&#xff0c;越来越多的投资者开始使用程序化交易系统进行交易&#xff0c;其中MQL4语言是广泛应用于MetaTrader 4平台上编写交易策略的一种语言。本文将分享一些技巧和经验&#xff0c;帮助读者利用MQL4编写自己的交易策略。 策略开发流程 首先&#xff0c;我…

传输控制协议 TCP

文章目录 一、TCP报文格式1.报头格式2.TCP最大段长度 MSS 二、TCP连接建立与释放1.连接建立&#xff1a;三次握手2.报文传输3.连接释放&#xff1a;四次挥手4.保持定时器与时间等待定时器 三、TCP差错重传1.字节流状态分类与滑动窗口&#xff08;发送&#xff09;① 滑动窗口两…

Android Studio实现内容丰富的安卓博客发布平台

如需源码可以添加q-------3290510686&#xff0c;也有演示视频演示具体功能&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号078 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看博客列表…

[AJAX]原生AJAX——自定义请求头

客户端 <script>// 1、创建对象const xhr new XMLHttpRequest();// 2、初始化&#xff1a;设置请求类型和urlxhr.open(POST, http://127.0.0.1:8000/server);// 设置请求头// Content-Type&#xff1a;设置请求体内容类型// application/x-www-form-urlencoded&#xf…

2022(二等奖)C2464植物保护管理系统

作品介绍 一、需求分析 1. 应用背景 森林是陆地生态系统的主体&#xff0c;是人类生存与发展的物质基础。以森林为主要经营对象的林业&#xff0c;不仅承担着生态建设的主要任务&#xff0c;而且承担着提供多种林产品的重大使命。进入21世纪&#xff0c;人类正在继农业文明和…

二进制、十进制相互转换

二进制转十进制&#xff1a; 1100 0000转为十进制的数值为&#xff1a;12864192 十进制转二进制&#xff1a; 列如&#xff1a;十进制数为202 1286432168421二进制11001010 解析&#xff1a; 202>128&#xff0c;第一个二进制数为&#xff1a;1 202-128>64&#xf…

Spring 事务管理方案和事务管理器及事务控制的API

目录 一、事务管理方案 1. 修改业务层代码 2. 测试 二、事务管理器 1. 简介 2. 在配置文件中引入约束 3. 进行事务配置 三、事务控制的API 1. PlatformTransactionManager接口 2. TransactionDefinition接口 3. TransactionStatus接口 往期专栏&文章相关导读 …