【模块系列】STM32TCS3472

news2025/1/10 10:39:28

前言

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

环境

  • 开发板:STM32C6T6最小系统板

  • 案例的代码环境:Keil5+STM32CubeMX生成的HAL库,OLED(4P)+TCS3472

  • 案例接线:TCS3472模块的VIN接到ST-LINK的5V,OLED模块VCC接3.3V。TCS3472和OLED的SDA接到PB9,SCL接到PB8。TCS3472模块的LED引脚接PA3(闪烁)或GND都行,不接的话LED的会一直亮,导致RGB值与透明度计算后大于256的。

    注意:假如TCS3472模块的VIN接到板载的3.3V的话,可能会发生供电不足的情况。

特点

下述介绍参考数据手册

  • 支持I2C协议快速模式,接口数据传输速率高达 400 kbit/s

  • TCS3472提供红、绿、蓝(RGB)和透明光©感应值的16位数字量的返回。

  • 红、绿、蓝(RGB)和透明光。带红外屏蔽滤光片的感应器。可编程模拟增益和积分时间。3,800,000:1。动态范围灵敏度极高-非常适合在暗玻璃后操作。

  • 外置可编程中断引脚,启用可屏蔽中断当超出预设值时,系统会发出电平式中断可编程上下限阈值,带持久性过滤器,从而减少MCU的开销

  • 有着电源管理,低功耗-2.5μA 休眠状态65μA等待状态,可编程等待状态时间从2.4ms 至>7 秒

代码

  代码方面除了CubeMX生成的工程框架外,还导入了OLED(4P),自制了MyI2C,TCS34725库,假如其它项目要用到的话注意也要导入这几个库。下面仅展示TCS34725库,完整工程文件会放在文章末尾的

TCS34725.H

#ifndef __TCS34725_H__
#define __TCS34725_H__

#define TCS34725_ADDRESS          (0x52)		// 八位地址
#define TCS34725_ADDRESS_7bit     (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)

typedef enum
{
  TCS34725_INTEGRATIONTIME_2_4MS  = 0xFF,   ///<  2.4ms - 1 cycle    - Max Count: 1024  
  TCS34725_INTEGRATIONTIME_24MS   = 0xF6,   ///<  24ms  - 10 cycles  - Max Count: 10240 
  TCS34725_INTEGRATIONTIME_50MS   = 0xEB,   ///<  50ms  - 20 cycles  - Max Count: 20480 
  TCS34725_INTEGRATIONTIME_101MS  = 0xD5,   ///<  101ms - 42 cycles  - Max Count: 43008 
  TCS34725_INTEGRATIONTIME_154MS  = 0xC0,   ///<  154ms - 64 cycles  - Max Count: 65535 
  TCS34725_INTEGRATIONTIME_700MS  = 0x00    ///<  700ms - 256 cycles - Max Count: 65535 
}
tcs34725IntegrationTime_t;

typedef enum
{
  TCS34725_GAIN_1X                = 0x00,   ///<  No gain  
  TCS34725_GAIN_4X                = 0x01,   ///<  4x gain  
  TCS34725_GAIN_16X               = 0x02,   ///<  16x gain 
  TCS34725_GAIN_60X               = 0x03    ///<  60x gain 
}
tcs34725Gain_t;

typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;


/*****	底层函数	 *****/
void TCS34725_WriteReg(uint8_t reg,uint8_t data);
uint8_t TCS34725_ReadReg(uint8_t reg);

/*****	功能函数	 *****/
void TCS34725_Init(void);						// 初始化TCS34725配置
void TCS34725_enable(void);					// 使能器件
void TCS34725_lock(void);						// 使能TCS34725内部中断
uint8_t TCS34725_getID(void);			// 获取器件ID
uint8_t TCS34725_getStatus(void);	// 获取TCS34725状态
void TCS34725_setGain(tcs34725Gain_t gain);		// 设置增益
void TCS34725_setIntegrationTime(tcs34725IntegrationTime_t time);		// 设置时间增益
void TCS34725_getRGBC(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);		// 获取TCS34725的颜色反馈


#endif

TCS34725.C

#include "TCS34725.h"
#include "MyI2C.h"

/**
 * @描述:基于TCS34725 写寄存器 ID-地址-数据
 */
void TCS34725_WriteReg(uint8_t reg,uint8_t data)
{
	MyI2C_Start();					
	MyI2C_SendByte(TCS34725_ADDRESS);			
  MyI2C_ReceiveAck();	
	MyI2C_SendByte(TCS34725_COMMAND_BIT | reg);		
  MyI2C_ReceiveAck();			
	MyI2C_SendByte(data);
	MyI2C_ReceiveAck();
  MyI2C_Stop();						
}

/**
 * @描述:基于TCS34725 读寄存器 ID-地址-数据
 */
uint8_t TCS34725_ReadReg(uint8_t reg)
{
	uint8_t reData = 0;
	MyI2C_Start();					
	MyI2C_SendByte(TCS34725_ADDRESS);		
	MyI2C_ReceiveAck();	
	MyI2C_SendByte(TCS34725_COMMAND_BIT | reg);			
  MyI2C_ReceiveAck();
	
	MyI2C_Start();	// 666
	MyI2C_SendByte(TCS34725_ADDRESS | 0x01);		
	MyI2C_ReceiveAck();	
	reData = MyI2C_ReceiveByte();
	MyI2C_SendAck(1);
	
	MyI2C_Stop();		
  return reData;
}


/**
* @描述:初始化TCS34725配置
*/
void TCS34725_Init()
{
	TCS34725_setIntegrationTime(TCS34725_INTEGRATIONTIME_101MS);
	TCS34725_setGain(TCS34725_GAIN_1X);
	TCS34725_enable();
}

/**
* @描述:TCS34725毫秒级延时
*/
void TCS34725_DelayMs(uint16_t ms)
{
	char i;
	for(i = 0;i < ms;i++)
	{
		MyI2C_DelayUs(1000);
	}
	
}

/**
* @描述:设置时间增益
*/
void TCS34725_setIntegrationTime(tcs34725IntegrationTime_t time)
{
  // 更新时序寄存器
	TCS34725_WriteReg(TCS34725_ATIME,time);
}

/**
* @描述:设置增益
*/
void TCS34725_setGain(tcs34725Gain_t gain)
{
	// 设置增益
	TCS34725_WriteReg(TCS34725_CONTROL,gain);

}

/**
* @描述:使能器件
*/
void TCS34725_enable(void)
{
	// 开启内部振荡器--启动
	TCS34725_WriteReg(TCS34725_ENABLE,TCS34725_ENABLE_PON);
  TCS34725_DelayMs(3);
	// 启动ADC
	TCS34725_WriteReg(TCS34725_ENABLE,TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
}

/**
* @描述:读取TCS34725指定寄存器
*/
uint16_t TCS34725_readRegWord(uint8_t reg)
{
  uint16_t h = 0x0000;		// 高八位
	uint16_t l = 0x0000;		// 低八位
	
	MyI2C_Start();															// I2C开始条件
	MyI2C_SendByte(TCS34725_ADDRESS);						// I2C发送字节
  MyI2C_ReceiveAck();													// I2C接收应答
	MyI2C_SendByte(TCS34725_COMMAND_BIT | reg | 0x20);	// I2C发送字节
	MyI2C_ReceiveAck();													// I2C接收应答
	
  MyI2C_Start();	// 666
	MyI2C_SendByte(TCS34725_ADDRESS | 0x01);		
	MyI2C_ReceiveAck();	

  h = MyI2C_ReceiveByte();			// I2C接收字节
	MyI2C_SendAck(0);							// I2C发送应答
	l = MyI2C_ReceiveByte();			// I2C接收字节
	MyI2C_SendAck(1);							// I2C发送应答
	MyI2C_Stop();									// I2C结束条件
	
  h <<= 8;
  h |= l;
  return h;
}

/**
* @描述:获取TCS34725的颜色反馈
*/
void TCS34725_getRGBC(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
{

  *c = TCS34725_readRegWord(TCS34725_CDATAL);
  *r = TCS34725_readRegWord(TCS34725_RDATAL);
  *g = TCS34725_readRegWord(TCS34725_GDATAL);
  *b = TCS34725_readRegWord(TCS34725_BDATAL);
  
  // 给定一定的采集后延时
	TCS34725_DelayMs(100);
}

/**
* @描述:使能TCS34725内部中断
*/
void TCS34725_lock()
{
	uint8_t r = TCS34725_ReadReg(TCS34725_ENABLE);
	r |= TCS34725_ENABLE_AIEN;
	TCS34725_WriteReg(TCS34725_ENABLE, r);
}

/**
* @描述:获取器件ID
* @返回:0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 
*/
uint8_t TCS34725_getID()
{
	return TCS34725_ReadReg(TCS34725_ID);
}

/**
* @描述:获取TCS34725状态
* @返回:返回该寄存器数值
*/
uint8_t TCS34725_getStatus()
{
	return TCS34725_ReadReg(TCS34725_STATUS);
}

现象

  下面为代码现象。OLED上显示的分别是,ID,8位R,8位G,8位B,16位C的值,可以看出来,测出的结果跟我设定的结果还差一点,不过能测量出个大概,比如偏红色啊,偏蓝色啊。当然可能也是我的参数没配置好,大家想要更高精度的话,就要关注TCS34725_Init()里面的时间增益,和数值增益了。

在这里插入图片描述

在这里插入图片描述

工程

链接包含资料:Keil5工程代码*1,TCS34727资料手册(英文)*1

链接:https://pan.baidu.com/s/1AapcmqJjpgtlvu-eMr3Bpg  提取码:wq6k

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

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

相关文章

Spark---RDD依赖关系

文章目录 1.1 RDD依赖关系1.2 血缘关系1.3 依赖关系分类1.3.1 窄依赖1.3.2 宽依赖 1.4 RDD阶段划分和任务划分1.4.1 RDD阶段划分 1.1 RDD依赖关系 在Spark中&#xff0c;一个RDD的形成依赖于另一个RDD&#xff0c;则称这两个RDD具有依赖关系(一般指相邻的两个RDD之间的关系) ,R…

数据结构排序——详解快排及其优化和冒泡排序(c语言实现、附有图片与动图示意)

上次讲了选择排序和堆排序&#xff1a;数据结构排序——选择排序与堆排序 今天就来快排和冒泡 文章目录 1.快排1.1基本介绍1.2不同的分区方法及代码实现1.2.1Hoare版1.2.2挖坑版1.2.3 前后指针版 1.3快排的优化1.3.1三数取中选key1.3.2递归到小的子区间时&#xff0c;可以考虑…

python查看安装包所依赖的包版本

python查看安装包所依赖的包版本 1. 找到包的位置 site-packages 文件夹的位置import gevent # ctrl 点进去就行了2. 返回包环境文件夹的上一层&#xff0c;会看到下面有一个 gevent-{版本号}.dist-info的文件夹3. 查看 METADATA 文件Requires-Dist: greenlet >2.0.0 ...#…

Vue-13、Vue深度监视

1、监视多级结构中某个属性的变化 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>watch深度监视</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm…

鸿蒙APP适配的设备类型

鸿蒙OS&#xff08;HarmonyOS&#xff09;是一款面向多设备的分布式操作系统&#xff0c;因此鸿蒙APP可以适配多种设备类型。以下是一些鸿蒙APP可能需要适配的设备类型&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c…

通过WebSocket实现异步导出

前言 本篇文章记录大批量数据导出时间过长,导致接口请求超时问题。 解决思路与流程 前端点击导出按钮时开启websocket连接逻辑处理异步执行文件处理好后&#xff0c;得到文件的绝对路径后台socket通知前端绝对路径的地址前端下载文件到浏览器 文章目录 本地环境 一、WebSock…

树形table 10w+数据每次点击要十几秒 懒加载解决点击卡顿

el-table 树形table 10w数据每次点击要十几秒 懒加载解决点击卡顿 //vue 表头要增加lazy :load"load" <el-tablelazystripeborderref"table"row-key"id":load"load":data"tableData":tree-props"{ children: child…

MySQL之数据的导入、导出远程备份

目录 一. navicat的导入、导出 1.1 导入 1.2 导出 二. mysqldump命令导入、导出 2.1 导出 2.2 导入 三. LOAD DATA INFILE 命令导入、导出 3.1 设置 3.2 导出 3.3 导入 3.4 查看secure_file_priv设置 四. 远程备份 4.1 导出 4.2 导入 五. 思维导图 一. navicat的导入、导…

ChatGPT4 助力 Python 数据分析与可视化、人工智能建模及论文高效撰写

2022年11月30日&#xff0c;可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT3.5&#xff0c;将人工智能的发展推向了一个新的高度。2023年4月&#xff0c;更强版本的ChatGPT4.0上线&#xff0c;文本、语音、图像等多模态交互方式使其在…

如何用GPT写代码?

详情点击链接&#xff1a;如何用GPT写代码&#xff1f; 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#xff0c;AI画图&#xff0c;图像识别&#xff0c;文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Claude2二定制自己的GPTs…

12、JVM高频面试题

1、JVM的主要组成部分有哪些 JVM主要分为下面几部分 类加载器&#xff1a;负责将字节码文件加载到内存中 运行时数据区&#xff1a;用于保存java程序运行过程中需要用到的数据和相关信息 执行引擎&#xff1a;字节码文件并不能直接交给底层操作系统去执行&#xff0c;因此需要…

24年教资报名千万不要卡在照片上,看看照片有啥要求?

每年都有很多人教资报名卡在照片上&#xff0c;总是审核不通过&#xff0c;24年教资报名千万不要卡在照片上&#xff0c;快来看看照片有啥要求吧&#xff1f;如果还没有准备&#xff0c;可以支付宝搜索【亿鸣证件照】或者微信搜索【随时照】小程序&#xff0c;然后进入小程序的…

麒麟Linux安装新版微信的方法

麒麟Linux系统目前有v10和v10sp1&#xff0c;注意&#xff0c;恶趣味的是v10和v10sp1竟然不通用&#xff0c;这导致了一些国产程序出现运行bug,通过系统自带的麒麟商店无法图形界面安装&#xff0c;甚至搜索不到微信等等一系列问题&#xff0c;易用度确实很差。 解决办法也很简…

七人拼团模式:社交电商的新面目

随着社交电商的快速发展&#xff0c;七人拼团模式作为一种创新的商业模式&#xff0c;正在引领着一场消费革命。它不仅改变了消费者的购物习惯&#xff0c;还为电商平台带来了巨大的流量和收入。本文将深入探讨七人拼团模式的玩法、优势、发展趋势以及如何为电商平台带来可观收…

Netty-Netty基础应用与了解

前言 Netty 的优势 1、 API 使用简单&#xff0c;开发门槛低&#xff1b; 2、功能强大&#xff0c;预置了多种编解码功能&#xff0c;支持多种主流协议&#xff1b; 3、定制能力强&#xff0c;可以通过 ChannelHandler 对通信框架进行灵活地扩展&#xff1b; 4、性能高…

BGP协议概念与配置(HCIP完整版)

目录 一、BGP协议基础 1、路由的分类 2、为什么要使用BGP协议 3、BGP概述 4、AS号 二、BGP协议概述 1、场景 2、作用 3、优势 4、BGP邻居类型 5、BGP特征 6、BGP报文类型 7、BGP工作过程 8、BGP状态 9、BGP路由默认优先级为255 10、BGP邻居关系建立的完整流程 …

【深度学习:视觉基础模型】视觉基础模型 (VFM) 解释

【深度学习&#xff1a;视觉基础模型】视觉基础模型 VFM 解释 了解视觉基础模型从 CNN 到 Transformer 的演变自我监督和适应能力 流行的视觉基础模型DINO&#xff08;自蒸馏&#xff0c;无标签&#xff09;SAM&#xff08;分段任意模型&#xff09;SegGPTMicrosofts Visual Ch…

【uview2.0】Keyboard 键盘 与 CodeInput 验证码输入 结合使用 uview

https://www.uviewui.com/components/codeInput.html &#xff08;CodeInput 验证码输入&#xff09; https://www.uviewui.com/components/keyboard.html &#xff08;Keyboard 键盘&#xff09; <u-keyboard mode"number" :dotDisabled"true" :show&q…

分割、合并、转换、重组:强大的自部署 PDF 处理工具 | 开源日报 No.143

Stirling-Tools/Stirling-PDF Stars: 13.2k License: GPL-3.0 这个项目是 Stirling-PDF&#xff0c;它是一个功能强大的基于本地主机的 Web PDF 操作工具&#xff0c;使用 Docker 进行部署。其主要功能包括分割、合并、转换、重新组织 PDF 文件以及添加图片、旋转和压缩等多种…

供应链+低代码,实现数字化【共赢链】转型新策略

在深入探讨之前&#xff0c;让我们首先明确供应链的基本定义。供应链可以被理解为一个由采购、生产、物流配送等环节组成的网状系统&#xff0c;它始于原材料的采购&#xff0c;经过生产加工&#xff0c;最终通过分销和零售环节到达消费者手中。 而数字化供应链&#xff0c;则是…