前言
手上正好有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 秒
代码
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);
}
现象
工程
链接包含资料:keil5工程代码*1,tcs34727资料手册(英文)*1
链接:https://pan.baidu.com/s/1bfynq78vgn_rhmdkys3_ka 提取码:1x08
发表评论