例程资料链接如下:
BD网盘链接:
https://pan.baidu.com/s/1B1Fa4GhmScSGR6VQNDsE3w
提取码:855c
相关视频:基于CW32的GY-33颜色识别模块的应用
一、简介
GY-33是一种基于TCS34725颜色传感器的颜色识别模块。TCS34725是一种高精度光学传感器,能够检测红、绿、蓝三个基本色的光谱信息,从而实现对物体颜色的准确识别,该模块的具体应用场景包括以下几个方面:
(1)电子设备颜色校准:在电子设备制造过程中,颜色一致性非常重要。使用GY-33模块可以帮助制造商检测和校准电子设备的颜色,确保不同设备之间的颜色表现一致。
(2)色彩分析和精确匹配:GY-33模块在颜色分析和匹配方面有广泛应用。例如,在印刷行业中,可以使用该模块来检测和匹配颜色样本,从而确保印刷品的准确颜色表现。
(3)机器人视觉系统:GY-33模块可以用于机器人视觉系统,帮助机器人在环境中对不同颜色的物体进行识别和分类。这在物流、仓储和自动导航系统中非常有用,机器人可以根据物体的颜色属性执行相应的任务。
二、所需物料
本实验使用到了CW32F030C8小蓝板、GY-33颜色识别模块、0.96寸OLED显示屏,RGB全彩LED模块、轻触开关模块及Keil5开发环境。
实物展示
【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;
}
四、实物展示+效果演示
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/2302_81038468/article/details/136503149
|
 共1人点赞
|