基于CW32系列MCU的GY-33颜色识别模块设计

描述

一、简介

1.GY-33是一种基于TCS34725颜色传感器的颜色识别模块。TCS34725是一种高精度光学传感器,能够检测红、绿、蓝三个基本色的光谱信息,从而实现对物体颜色的准确识别,该模块的具体应用场景包括以下几个方面:

(1)电子设备颜色校准:在电子设备制造过程中,颜色一致性非常重要。使用GY-33模块可以帮助制造商检测和校准电子设备的颜色,确保不同设备之间的颜色表现一致。

(2)色彩分析和精确匹配:GY-33模块在颜色分析和匹配方面有广泛应用。例如,在印刷行业中,可以使用该模块来检测和匹配颜色样本,从而确保印刷品的准确颜色表现。

(3)机器人视觉系统:GY-33模块可以用于机器人视觉系统,帮助机器人在环境中对不同颜色的物体进行识别和分类。这在物流、仓储和自动导航系统中非常有用,机器人可以根据物体的颜色属性执行相应的任务。

    二、所需物料

本实验使用到了CW32F030C8小蓝板、GY-33颜色识别模块、0.96寸OLED显示屏,RGB全彩LED模块、轻触开关模块及Keil5开发环境。

keil5

CW32F030C8小蓝板

keil5
GY-33颜色识别模块
keil5
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的方式。

keil5

keil5

keil5

有简单的7种颜色识别,单片机不参与数据处理工作,不需要计算RGB值,直接读取吧 数据即可。需要特别注意的是:

keil5

keil5

  三、核心代码

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;              
}

 

  四、实物展示+效果演示

keil5

keil5

keil5

keil5

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分