例程资料链接如下:
BD网盘链接:
https://pan.baidu.com/s/1B1Fa4GhmScSGR6VQNDsE3w
提取码:855c
一、简介
1.GY-33是一种基于TCS34725颜色传感器的颜色识别模块。TCS34725是一种高精度光学传感器,能够检测红、绿、蓝三个基本色的光谱信息,从而实现对物体颜色的准确识别,该模块的具体应用场景包括以下几个方面:
(1)电子设备颜色校准:在电子设备制造过程中,颜色一致性非常重要。使用GY-33模块可以帮助制造商检测和校准电子设备的颜色,确保不同设备之间的颜色表现一致。
(2)色彩分析和精确匹配:GY-33模块在颜色分析和匹配方面有广泛应用。例如,在印刷行业中,可以使用该模块来检测和匹配颜色样本,从而确保印刷品的准确颜色表现。
(3)机器人视觉系统:GY-33模块可以用于机器人视觉系统,帮助机器人在环境中对不同颜色的物体进行识别和分类。这在物流、仓储和自动导航系统中非常有用,机器人可以根据物体的颜色属性执行相应的任务。
二、所需物料
本实验使用到了CW32F030C8小蓝板、GY-33颜色识别模块、0.96寸OLED显示屏,RGB全彩LED模块、轻触开关模块及Keil5开发环境。
CW32F030C8小蓝板
GY-33颜色识别模块
RGB全彩LED模块
实物展示
【GY-33与单片机连线】:VCC<-->+3.3V
GND<-->GND
DR<-->PA5
CT<-->PA4
【LED与单片机连线】:V<-->+3.3V
R<-->PA0
G<-->PA1
B<-->PA2
【轻触开关与单片机连线】:VCC<-->+3.3V
GND<-->GND
OUT<-->PB9
此模块有两种方式读取数据,即串口UART或者 MCU_IIC,本次实验采用MCU_IIC的方式。
有简单的7种颜色识别,单片机不参与数据处理工作,不需要计算RGB值,直接读取吧 数据即可。需要特别注意的是:
三、核心代码
main.c: #include "main.h" #include "RGB.h" #include "GTIM.h" #include "Delay.h" #include "GY_33.h" #include "OLED.h" #include "Key.h" #include "BTIM.h" #define LENGTH 3 //读取数据的长度 uint8_t press_flag=0; //按键按下标识 uint8_t data[LENGTH]={0}; //存放读取到的RGB数据 uint8_t color[1]={0}; //存放模块识别到的颜色数据 char *str[]={"blue","dblue","green","black","white","pink","yellow","red"};//模块可以识别到的颜色 int main() { uint8_t i; OLED_Init(); //OLED显示 RGB_GPIO_Init(); //RGB灯GPIO初始化 GTIM2_Init(); //GTIM2初始化配置为PWM输出模式 I2C_GPIO_Init(); //GY-33模块GPIO初始化 Key_GPIO_Init(); //按键GPIO初始化 BTIM_Init(); //BTIM定时器初始化,定时控制按键扫描周期 // WriteData(GY33_ADDR,Config,0x51); //启动白平衡,等级亮度为5 while(1) { if(press_flag==1) //若按键标识已打开,代表有按键按下,执行按键功能 { OLED_Clear(); //清屏 if(ReadData(GY33_ADDR,R,data,LENGTH)) //读取模块检测颜色并进行处理后返回的RGB值 { OLED_ShowString(1,1,"RGB:"); OLED_ShowNum(1,5,data[0],3); //R值 OLED_ShowNum(2,5,data[1],3); //G值 OLED_ShowNum(3,5,data[2],3); //B值 } RGB_Running(data); //RGB全彩LED灯根据读取到的RGB进行显示 Delay_ms(100); //数据读取间隔应不小于100ms if(ReadData(GY33_ADDR,Color,color,1))//读取模块检测颜色并进行处理后的颜色信息返回值 { for(i=0;i<8;i++) //8-bits数据,逐位判断 { if((color[0]>>i)==1) //判断哪一位为1 { OLED_ShowString(4,1,"Color:"); OLED_ShowString(4,7,str[7-i]); //显示对应颜色 break; } } } press_flag=0; //执行完关闭按键标识 } } } void BTIM1_IRQHandler(void) //BTIM1中断服务函数 { static unsigned int cnt = 0; if(BTIM_GetITStatus(CW_BTIM1,BTIM_IT_OV)) { if(++cnt>=20) //20ms定时,执行一次按键扫描 { cnt = 0; if(Key_Scan()==1) //返回值不为0时 press_flag=1; //打开按键标识 } BTIM_ClearITPendingBit(CW_BTIM1,BTIM_IT_OV); //清除标志位 } } GY-33.c: #include "main.h" #include "Delay.h" #include "GY_33.h" void I2C_GPIO_Init(void) //GY-33颜色识别模块GPIO初始化 { __RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.IT=GPIO_IT_NONE; GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_OD; //开漏输出 GPIO_InitStruct.Pins=GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Speed=GPIO_SPEED_HIGH; GPIO_Init(CW_GPIOA, &GPIO_InitStruct); SCL(1); SDA(1); } void I2C_Delay() //I2C延时函数 { Delay_us(time); } uint8_t I2C_Start(void) //发送起始信号 { SDA(1); SCL(1); I2C_Delay(); if(ReadSDA==0) return 0; SDA(0); I2C_Delay(); if(ReadSDA==1) return 0; SCL(0); I2C_Delay(); return 1; } void I2C_Stop(void) //发送停止信号 { SDA(0); SCL(0); I2C_Delay(); SCL(1); I2C_Delay(); SDA(1); } void I2C_SendACK(uint8_t ackbit) //发送应答 { SDA(ackbit); SCL(1); I2C_Delay(); SCL(0); I2C_Delay(); } void I2C_SendByte(uint8_t Byte) //发送1字节(8-bit)的数据 { uint8_t i; SCL(0); for (i = 0; i < 8; i++) { if(Byte&0x80) SDA(1); else SDA(0); SCL(1); I2C_Delay(); SCL(0); Byte<<=1; I2C_Delay(); } } uint8_t I2C_ReceiveByte(void) //接收1字节(8-bit)的数据 { uint8_t data,i; SDA(1); Delay_us(1); for(i=0;i<8;i++) { SCL(1); data<<=1; if(ReadSDA==1) data|=0x01; I2C_Delay(); SCL(0); I2C_Delay(); } return data; } uint8_t I2C_WaitAck(void) //等待应答 { uint16_t i; SDA(1); SCL(1); while(ReadSDA==1) { if(++i==500) break; } if(ReadSDA==1) { SCL(0); return 0; } I2C_Delay(); SCL(0); I2C_Delay(); return 1; } uint8_t WriteData(uint8_t Slave_Addr,uint8_t REG_Addr,uint8_t data) //写操作 { if(I2C_Start()==0) RETURN I2C_SendByte(Slave_Addr); if(I2C_WaitAck()==0) RETURN I2C_SendByte(REG_Addr); if(I2C_WaitAck()==0) RETURN I2C_SendByte(data); if(I2C_WaitAck()==0) RETURN I2C_Stop(); //发送停止信号 return 1; } uint8_t ReadData(uint8_t Slave_Addr,uint8_t REG_Addr,uint8_t *data,uint8_t length) //读操作 { if(I2C_Start()==0) RETURN I2C_SendByte(Slave_Addr); if(I2C_WaitAck()==0) RETURN I2C_SendByte(REG_Addr); if(I2C_WaitAck()==0) RETURN if(I2C_Start()==0) RETURN I2C_SendByte(Slave_Addr+1); if(I2C_WaitAck()==0) RETURN while(--length) { *data++=I2C_ReceiveByte(); I2C_SendACK(0); Delay_ms(110); } *data=I2C_ReceiveByte(); I2C_SendACK(1); I2C_Stop(); //发送停止信号 return 1; }
四、实物展示+效果演示
来源: CW32生态社区
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。