TCS3200的使用

**使用注意事项:**因每次使用颜色识别的时候外界的光源条件都不相同,因此如果达到较好的使用效果,每次使用之前需要用白纸进行白平衡校准,这样工作起来更加方便。
经过资料可知TCS3200的工作原理是输出方波的频率,来判断颜色信号的强弱,资料百度文库链接:
Arduino:https://wenku.baidu.com/view/0b4d2a4376eeaeaad0f33044.html?from=search(以上链接有怎么设置输出比例因子的图表,通过S0,S1两个引脚的电平设置可以进行输出比例因子调整,见以下图表)
在这里插入图片描述
不同颜色采集的频率的设置方式:
在这里插入图片描述
89C51:https://wenku.baidu.com/view/488d2fb180eb6294dc886c04.html
模块工作时,通过两个可编程的引脚来动态选择所需要的滤波器,该传感器的典型输出频率范围从2Hz-500kHz,用户还可以通过两个可编程引脚来选择100%、20%或2%的输出比例因子。
经过调试发现,此模块一开始启动的时候最好先检测一张白色A4纸张,确定白平衡,然后在进行颜色判断,这样比较准确。

Excel的使用方法:按 Alt + 回车(Enter)组合键,光标后面的文字自动分成了两行,即按一次键,光标后的所有文字就会自动换行,不需一行行的重复按键。

以下代码是tcs3200.c文件中的:
#include “main.h”
#include “delay.h”
#include “gpio.h”
#include “tim.h”

u16 Rgena,Ggena,Bgena;//定义红、绿、蓝,三色因子
u16 Ramount,Gamount,Bamount;//具体的计算值
u16 amount;//采集到的频率
/duty是占空比/
extern uint32_t duty;
/freq是频率/
extern uint32_t freq;
extern uint32_t tmp1, tmp2;
/*****************************************
获取频率的函数
在定时器tim.c文件中已经配置完毕频率采集函数
在这可以直接进行使用
*****************************************/
u16 Get_amount(void)
{
if (tmp1 == 0)
{
duty = 0;//占空比复位
freq = 0;//频率复位
}
else
{
/占空比的计算公式/
duty = tmp2 * 100.0f / tmp1 + 0.5f;
/tmp1前后需要各加1,及tmp+2,以下输出结果为频率/
freq = 720000.0f / (tmp1+2);
}
return freq;
}
void tcs3200_init(u8 s0,u8 s1)
{
/S3 S3 IO 口初始化/
GPIO_ResetBits(GPIOC,GPIO_PIN_8);
GPIO_ResetBits(GPIOC,GPIO_PIN_9);
/S0 S1用来决定TCS3200输出的频率上限/
S0=s0;
S1=s1;

/*定时器1频率输入捕获中断开始*/
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
/*如果不需要占空比和频率数据就只开通道2即可。
第一次的数据是不正确的,实际工作中要将第一次的数据丢弃*/

HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);
}
/*******************************************
*

  •     白平衡
    

*******************************************/
void whitebalance(void)
{
// EXTIX_Init(); //外部中断初始化
S2=0;S3=0;//红色通道
amount=0; //开始计数
delay_ms(10);
amount = Get_amount(); //求出频率
Rgena = amount; //求出红色因子
amount=0;
//----------------------------------
S2=1;S3=1;//绿色通道
amount=0;
delay_ms(10);
amount = Get_amount(); //求出频率
Ggena = amount; //求出绿色因子
amount=0;
//----------------------------------
S2=0;S3=1;//蓝色通道
amount=0;
delay_ms(10);
amount = Get_amount(); //求出频率
Bgena = amount;求出蓝色因子
amount=0;
S2=1;S3=0;//关闭通道
}

u16 tcs3200_RED(void)
{
S2=0;S3=0;//模式设定为红色
amount=0;
delay_ms(10);
amount = Get_amount(); //求此时的频率数值
Ramount=(u32)amount*255/Rgena; //取R值
if(Ramount>255) Ramount = 255;
return Ramount;
// amount=0;
}

u16 tcs3200_GREEN(void)
{
S2=1;S3=1;//模式设定为绿色
amount=0;
delay_ms(10);
amount = Get_amount(); //求出此时的频率数值
Gamount=(u32)amount*255/Ggena; //取G值
if(Gamount>255) Gamount = 255;
return Gamount;
// amount=0;
}

u16 tcs3200_BLUE(void)
{
S2=0;S3=1;//模式设定为蓝色
amount=0;
delay_ms(10);
amount = Get_amount();//求出此时的频率
Bamount=(u32)amount*255/Bgena;//取B值
if(Bamount>255) Bamount = 255;
return Bamount;
// amount=0;
}

以下代码是tcs3200.h文件中的
#ifndef __TCS3200_H
#define __TCS3200_H
#include “sys.h”

extern u16 amount;

extern u16 Rgena,Ggena,Bgena;
extern u16 Ramount,Gamount,Bamount;

#define S0 PCout(6)
#define S1 PCout(7)
#define S2 PCout(8)
#define S3 PCout(9)
#define OUT PAin(8)

u16 Get_amount(void);
void tcs3200_init(u8 s0,u8 s1);
void whitebalance(void);
u16 tcs3200_RED(void);
u16 tcs3200_GREEN(void);
u16 tcs3200_BLUE(void);
#endif

以下是tim.c文件中的
#include “tim.h”

#include “gpio.h”

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim4;

/* TIM1 init function */
void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_IC_InitTypeDef sConfigIC;
TIM_MasterConfigTypeDef sMasterConfig;

htim1.Instance = TIM1;
htim1.Init.Prescaler = 720-1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

}
/* TIM4 init function */
void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 0;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
_Error_Handler(FILE, LINE);
}

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */

/* USER CODE END TIM1_MspInit 0 /
/
TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();

/**TIM1 GPIO Configuration    
PA8     ------> TIM1_CH1 
*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN TIM1_MspInit 1 */

/* USER CODE END TIM1_MspInit 1 /
}
else if(tim_baseHandle->Instance==TIM4)
{
/
USER CODE BEGIN TIM4_MspInit 0 */

/* USER CODE END TIM4_MspInit 0 /
/
TIM4 clock enable /
__HAL_RCC_TIM4_CLK_ENABLE();
/
USER CODE BEGIN TIM4_MspInit 1 */

/* USER CODE END TIM4_MspInit 1 */
}
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{

if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspDeInit 0 */

/* USER CODE END TIM1_MspDeInit 0 /
/
Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();

/**TIM1 GPIO Configuration    
PA8     ------> TIM1_CH1 
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);

/* TIM1 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM1_CC_IRQn);

/* USER CODE BEGIN TIM1_MspDeInit 1 */

/* USER CODE END TIM1_MspDeInit 1 /
}
else if(tim_baseHandle->Instance==TIM4)
{
/
USER CODE BEGIN TIM4_MspDeInit 0 */

/* USER CODE END TIM4_MspDeInit 0 /
/
Peripheral clock disable /
__HAL_RCC_TIM4_CLK_DISABLE();
/
USER CODE BEGIN TIM4_MspDeInit 1 */

/* USER CODE END TIM4_MspDeInit 1 */
}
}

/* USER CODE BEGIN 1 */
uint32_t duty = 0;
uint32_t freq = 0;
uint32_t tmp1 = 0, tmp2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef htim)//hal_tim.h回调函数
{
// volatile static uint32_t tmp1 = 0, tmp2 = 0;
/此例程只需要定时器输入捕获频率通道/
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
tmp1 = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1);//周期
}
/占空比可以不进行计算,计算也问题不大/
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
tmp2 = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_2);//占空比
}
}
//
/
USER CODE END 1 */
delay.c 中的配置:
#include “stm32f1xx_hal.h”
#include “tim.h”
#include “usart.h”
#include “sys.h”
#include “delay.h”
#include “stdio.h”
#include “stm32_hal_legacy.h”

u8 t=0,timer_second=0,timer_minute=0,timer_hour=0,timer_day=0,delayus_t=0;

//void timeclock_init(){
// HAL_TIM_Base_Start_IT(&htim2);
//}

void delay_init(){
__HAL_TIM_ENABLE(&htim4);
}

void delay_us(u32 nus){
__HAL_TIM_SetCounter(&htim4, 0);//htim17
while(__HAL_TIM_GetCounter(&htim4) < (36 * nus));//TIM4挂载在APB1的peripheral时钟线,时钟为36Mhz
__HAL_TIM_SetCounter(&htim4, 0);//htim17
while(__HAL_TIM_GetCounter(&htim4) < (36 * nus));//TIM4挂载在APB1的peripheral时钟线,时钟为36Mhz
return;
/* Disable the Peripheral */
}
Cube 的配置如下图所示:
在这里插入图片描述

TCS3200颜色传感器概述: TCS3200颜色传感器是一款全彩的颜色检测器,包括了一块TAOS TCS3200RGB感应芯片和4个白光LED灯,TCS3200能在一定的范围内检测和测量几乎所有的可见光。它适合于色度计测量应用领域。比如彩色打印、医疗诊断、计算机彩色监视器校准以及油漆、纺织品、化妆品和印刷材料的过程控制。 通常所看到的物体颜色,实际上是物体表面吸收了照射到它上面的白光(日光)中的一部分有色成分,而反射出的另一部分有色光在人眼中的反应。白色是由各种频率的可见光混合在一起构成的,也就是说白光中包含着各种颜色的色光(如红R、黄Y、绿G、青V、蓝B、紫P)。根据德国物理学家赫姆霍兹(Helinholtz)的三原色理论可知,各种颜色是由不同比例的三原色(红、绿、蓝)混合而成的。 由上面的三原色感应原理可知,如果知道构成各种颜色的三原色的值,就能够知道所测试物体的颜色。对于TCS3200D 来说,当选定一个颜色滤波器时,它只允许某种特定的原色通过,阻止其它原色的通过。例如:当选择红色滤波器时,入射光中只有红色可以通过,蓝色和绿色都被阻止,这样就可以得到红色光的光强;同理,选择其它的滤波器,就可以得到蓝色光和绿色光的光强。通过这三个光强值,就可以分析出反射到TCS3200D传感器上的光的颜色。 TCS3200颜色传感器实物展示: TCS3200颜色传感器描述: 感应芯片:TCS3200(全彩颜色检测器) 静态识别物体颜色,不同颜色输出不同频率方波 支持LED灯补光控制 TCS3200颜色传感器参数: 工作电压:2.7V ~ 5.5V 推荐检测距离:10mm 尺寸:36.0mm * 20.6mm 固定孔尺寸:2.0mm TCS3200颜色传感器主要用途: 颜色排序、感应与校准环境光、测试条阅读和颜色匹配等。 接口说明:(以接入MCU为例) VCC:接2.7V ~ 5.5V GND:接电源地 LED:接MCU.IO (控制四个白色LED灯的状态) OUT:接MCU.IO (RGB三原色对应的输出频率) S0/S1:接MCU.IO (选择不同的输出比例因子) S2/S3:接MCU.IO (选择不同色光的滤波器) 操作说明: S0/S1选择输出频率的比例因子,S2/S3依次选择三原色的滤波器类型,此时OUT端口输出的就是相应三原色的频率,与RGB颜色对照表比对即可得到所测物体的颜色。 注意: 颜色识别时要避免外界光线的干扰 首次使用模块模块重启或更换光源时,需进行白平衡调整 相关技术资料: 如何进行TCS3200各控制引脚与Arduino控制器的硬件连线问题,详见链接:https://www.eefocus.com/zhang700309/blog/13-08/2963... 用TCS3200D做颜色识别时,如何将测得的脉冲数转换为RGB的值?链接:https://wenda.so.com/q/1367943564064205 实物购买链接:https://www.waveshare.net/shop/Color-Sensor.htm
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值