要想识别色彩就离不开色彩传感器的使用,而色彩传感器的种类又有许多种,如早期的TCS230、TCS3200到现在的TCS34725等。
对于TCS230这类的传感器,它是以脉冲计数的方式来获得检测值,并通过色彩通道的选择来获得RGB的值。此外,为了达到一个可供使用的标准值,还需进行白平衡等处理,使用起来相对比较麻烦。
图1 TCS230
而现在推出的色彩传感器,如TCS34725则是数字化的,并采用I2C接口来传送数据,在使用时直接就可读取到色彩的RGB值,并可获得两种色彩模式的检测结果,即RGB模式和HSL模式。因此在使用上,它要比以前的色彩传感器要方便许多,功能也丰富一些。
图2 TCS34725
1. 整体结构
为此,在制作色彩识别与样本色彩显示器时是直接选取TCS34725来做检测器件,该设计的整体结构见图3所示。
图3 整体结构
在整体结构中,是以复旦微的FM33LGxx开发板作为处理核心,由TCS34725检测色彩值,由彩色的LCD屏来承担显示任务,其实物构成如图4所示。
图4 实物构成
2.色彩传感器及其使用
TCS34725是采用I2C方式工作,其遵循的通讯协议如下:
TCS34725与开发板的引脚连接关系为:
PE9 ---SCL
PD10---SDA
由于TCS34725使用I2C的方式工作,为此是以GPIO口来模拟I2C的方式来实现。
其中,对所用引脚的功能配置函数为:
void TCS34725_I2C_Init()
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOD, FL_GPIO_PIN_10);
GPIO_InitStruct.pin = FL_GPIO_PIN_10;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
FL_GPIO_ResetOutputPin(GPIOE, FL_GPIO_PIN_9);
GPIO_InitStruct.pin = FL_GPIO_PIN_9;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void TCS_SDA_OUT()
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOD, FL_GPIO_PIN_10);
GPIO_InitStruct.pin = FL_GPIO_PIN_10;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
void TCS_SDA_IN()
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOD, FL_GPIO_PIN_10);
GPIO_InitStruct.pin = FL_GPIO_PIN_10;
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT;
GPIO_InitStruct.pull = FL_ENABLE;
FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
void TCS34725_I2C_Send_Byte(u8 byte)
{
u8 i;
TCS_SDA_OUT();
TCS_SCL_L;
for(i = 0; i < 8; i++)
{
if(((byte&0x80)>>7)==1) TCS_SDA_H;
else
TCS_SDA_L;
byte <<= 1;
FL_DelayUs(2);
TCS_SCL_H;
FL_DelayUs(2);
TCS_SCL_L;
FL_DelayUs(2);
}
}
u8 TCS34725_I2C_Read_Byte(u8 ack)
{
u8 i,receive = 0;
TCS_SDA_IN();
for(i = 0; i < 8; i++)
{
TCS_SCL_L;
FL_DelayUs(2);
TCS_SCL_H;
receive <<= 1;
if(TCS_SDA_READ) receive++;
FL_DelayUs(1);
}
if (!ack) TCS34725_I2C_NACK();
else TCS34725_I2C_ACK();
return receive;
}
u8 TCS34725_Init(void)
{
u8 id=0;
TCS34725_I2C_Init();
TCS34725_Read(TCS34725_ID, &id, 1);
if(id==0x4D | id==0x44)
{
TCS34725_SetIntegrationTime(TCS34725_INTEGRATIONTIME_50MS);
TCS34725_SetGain(TCS34725_GAIN_1X);
TCS34725_Enable();
return 1;
}
return 0;
}
u8 TCS34725_GetRawData(COLOR_RGBC *rgbc)
{
u8 status = TCS34725_STATUS_AVALID;
TCS34725_Read(TCS34725_STATUS, &status, 1);
if(status & TCS34725_STATUS_AVALID)
{
rgbc->c = TCS34725_GetChannelData(TCS34725_CDATAL);
rgbc->r = TCS34725_GetChannelData(TCS34725_RDATAL);
rgbc->g = TCS34725_GetChannelData(TCS34725_GDATAL);
rgbc->b = TCS34725_GetChannelData(TCS34725_BDATAL);
return 1;
}
return 0;
}
在显示方面,所使用的显示器件为0.96寸的彩色LCD屏,其显示分辨率为160*80像素点。该显示屏采用SPI接口方式工作,为此它与开发板的引脚连接关系为:
void lcd_app(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOD, FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_5);
GPIO_InitStruct.pin = FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_5;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_5);
GPIO_InitStruct.pin = FL_GPIO_PIN_5;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
以GPIO口模拟SPI方式发送字节数据的函数为:
void LCD_Writ_Bus(u8 dat)
{
u8 i;
OLED_CS_Clr();
for(i=0;i<8;i++)
{
OLED_SCLK_Clr();
if(dat&0x80)
OLED_SDIN_Set();
else
OLED_SDIN_Clr();
OLED_SCLK_Set();
dat<<=1;
}
OLED_CS_Set();
}
voidLcd_Init(void)
void LCD_box(u16 x1,u16 y1,u16 x2,u16 y2)
{
int i,l;
LCD_Address_Set(x1,y1,x2,y1);
l=x2-x1;
for(i=0;i<l;i++)
{
LCD_WR_DATA8(0xff);
LCD_WR_DATA8(0xff);
}
LCD_Address_Set(x1,y2,x2,y2);
for(i=0;i<l;i++)
{
LCD_WR_DATA8(0xff);
LCD_WR_DATA8(0xff);
}
l=y2-y1;
for(i=0;i<l;i++)
{
LCD_DrawPoint(x1,y1+i,WHITE);
}
for(i=0;i<l;i++)
{
LCD_DrawPoint(x2,y1+i,WHITE);
}
}
void LCD_color(u16 Color)
{
u16 i,j;
LCD_Address_Set(110,30,129,49);
for(i=0;i<20;i++)
{
for (j=0;j<20;j++)
{
LCD_WR_DATA(Color);
}
}
}
功能处理的主程序:
int main(void)
{
u16 rv,gv,bv,fv;
MF_Clock_Init();
MF_SystemClock_Config();
FL_Init();
MF_Config_Init();
UserInit();
led_int();
lcd_app();
Lcd_Init();
LCD_Clear(BLACK);
BACK_COLOR=BLACK;
FL_DelayMs(2000);
LCD_ShowString(20,30,"R: G: B:",YELLOW);
LCD_color(RED);
LCD_box(109,29,130,50);
TCS34725_Init();
TCS34725_GetRawData(&rgb);
while(1)
{
TCS34725_GetRawData(&rgb);
rv=rgb.r*255/rgb.c;
gv=rgb.g*255/rgb.c;
bv=rgb.b*255/rgb.c;
LCD_ShowNum(0,50,rv,4,YELLOW);
LCD_ShowNum(32,50,gv,4,YELLOW);
LCD_ShowNum(64,50,bv,4,YELLOW);
fv=((rv>>3)<<8)+((gv>>2)<<5)+(bv>>3);
LCD_color(fv);
FL_DelayMs(1000);
LED0_TOG();
}
}
图5 检测粉色
图6 检测绿色
图7 检测蓝色。---------------------
作者:jinglixixi
链接:https://bbs.21ic.com/icview-3275564-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。