找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 2287|回復(fù): 10
打印 上一主題 下一主題
收起左側(cè)

關(guān)于顏色傳感器TCS230的測量RGB值的實(shí)驗(yàn)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:958627 發(fā)表于 2021-8-3 18:20 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
大家好,我是學(xué)習(xí)單片機(jī)的新手,我在用TCS230和單片機(jī)STC8A8K64S4A12做測量RGB值的實(shí)驗(yàn),但不知為何,液晶屏只顯示RGB值皆為255,不會變化,所以想求助各位有沒有碰到過這種情況,怎么解決的?

程序在樓下

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:280000 發(fā)表于 2021-8-4 08:58 | 只看該作者
單片機(jī)和顏色傳感器通信協(xié)議編寫的有問題吧,沒有讀取到正確的數(shù)據(jù)
回復(fù)

使用道具 舉報

板凳
ID:958627 發(fā)表于 2021-8-4 09:01 | 只看該作者
湖南 發(fā)表于 2021-8-4 08:58
單片機(jī)和顏色傳感器通信協(xié)議編寫的有問題吧,沒有讀取到正確的數(shù)據(jù)

您好,您可以幫助我一下嗎,這是我的程序
#include <stc8a.h>
#include <LCD1602.h>
#define uchar unsigned char
#define uint  unsigned int

//=================顏色傳感模塊連接=====================
/*-----------------------------------------------------
       |EO-----GND
       |S0-----VCC | S2-----P1.0 | OUT-------P3.5
       |S1-----VCC | S3-----P1.1 |
  ---------------------------------------------------*/
sbit    tcs230_s2=P1^0;//TCS230 S2接單片機(jī)P1.0
sbit    tcs230_s3=P1^1;//TCS230 S3接單片機(jī)P1.1
sbit    tcs230_en=P3^0; //TCS230 EN(E0)接GND
//**************函數(shù)聲明***************************************
void    DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置顯示一個字符
void    baipingheng();//白平衡子程序
void    celiang();//實(shí)際顏色程序
void    LCD1602_Init(void);
void    LCD1602_Display_Str(uchar* str);
void    Delay_ms(unsigned int ms);
uint    ryz,gyz,byz;//分別定義紅色因子 綠色因子 藍(lán)色因子
uint    rb,gb,bb;//RGB值
uchar   tab1[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//***********************主程序******************************
main()   
{   
   TMOD=0x51;//設(shè)定T0以工作方式1定時10毫秒
   LCD1602_Init();//LCD初始
   baipingheng();//上電時先白平衡一次
   while(1)
   {
       celiang();//顏色測試
       DisplayOneChar(0, 0,'R');//以十進(jìn)制顯示RGB中紅色的分值
       DisplayOneChar(0, 1, rb/100+0x30); //顯示百位數(shù)據(jù)
       DisplayOneChar(0, 2, rb/10%10+0x30);//顯示十位數(shù)據(jù)
       DisplayOneChar(0, 3, rb%10+0x30);//顯示個位數(shù)據(jù)
                   DisplayOneChar(0, 5,'G');//以十進(jìn)制顯示RGB中綠色的分值
       DisplayOneChar(0, 6, gb/100+0x30); //顯示百位數(shù)據(jù)
       DisplayOneChar(0, 7, gb/10%10+0x30);
       DisplayOneChar(0, 8, gb%10+0x30);
       DisplayOneChar(0, 10,'B');//以十進(jìn)制顯示RGB中藍(lán)色的分值
       DisplayOneChar(0, 11, bb/100+0x30);
       DisplayOneChar(0, 12, bb/10%10+0x30);
       DisplayOneChar(0, 13, bb%10+0x30);
       //*****在LCD1602的第二行以16進(jìn)制顯示RGB*******************
       DisplayOneChar(1, 1, tab1[rb/16]);
       DisplayOneChar(1, 2, tab1[rb%16]);
       DisplayOneChar(1, 3, 'H');
       DisplayOneChar(1, 6, tab1[gb/16]);
       DisplayOneChar(1, 7, tab1[rb%16]);
       DisplayOneChar(1, 8, 'H');
       DisplayOneChar(1, 11,tab1[bb/16]);
       DisplayOneChar(1, 12,tab1[bb%16]);
       DisplayOneChar(1, 13,'H');
       Delay_ms(1000);//每隔2.5秒測試一次顏色
   }
}
//******************************************************
//白平衡子程序
void   celiang()
{
        TMOD=0x51;//設(shè)定T0以工作方式1定時10毫秒
     //*********求R值************************************
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=0;
     tcs230_s3=0;//選擇紅色濾光器
     tcs230_en=0;
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     rb=(unsigned long)(TH1*256+TL1)*255/ryz;
     if(rb>255)rb=255;//判斷RGB值是否合法
     //***********求B值**************************************
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=0;
     tcs230_s3=1;//選擇藍(lán)色濾光器
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     bb=(unsigned long)(TH1*256+TL1)*255/byz;
     if(bb>255)bb=255;//判斷RGB值是否合法     
     //***********求G值**************************************   
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=1;
     tcs230_s3=1;//選擇綠色濾光器
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     tcs230_en=1;
     gb=(unsigned long)(TH1*256+TL1)*255/gyz;
     if(gb>255)gb=255;//判斷RGB值是否合法  
}
//******************************************************
//白平衡子程序
void    baipingheng()
{
        TMOD=0x51;//設(shè)定T0以工作方式1定時10毫秒
     //**************求取紅色因子***********************
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=0;
     tcs230_s3=0;//選擇紅色濾光器
     tcs230_en=0;
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     ryz=TH1*256+TL1;//其實(shí)這里的比例因子應(yīng)該為255/(TH1*256+TL1)
     //**************求取藍(lán)色因子***********************
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=0;
     tcs230_s3=1;//選擇藍(lán)色濾光器
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     byz=TH1*256+TL1;//其實(shí)這里的比例因子應(yīng)該為255/(TH1*256+TL1)
     //**************求綠紅色因子***********************
     TH0=(65536-10000)/256;
           TL0=(65536-10000)%256;
     TH1=0;
     TL1=0;
     tcs230_s2=1;
     tcs230_s3=1;//選擇綠色濾光器
     TR0=1;//10毫秒開始計時
     TR1=1;//開始計數(shù)
     while(TF0==0);//等待定時器溢出
     TF0=0;//清楚定時器0溢出標(biāo)志
     TR0=0;//關(guān)閉定時0
     TR1=0;
     tcs230_en=1;
     gyz=TH1*256+TL1;//其實(shí)這里的比例因子應(yīng)該為255/(TH1*256+TL1)
}
/***********************************************
函數(shù)名稱:LCD1602_Init
功    能:LCD1602初始化
入口參數(shù):無
返 回 值:無       
備    注:詳見數(shù)據(jù)手冊定義。
************************************************/
void LCD1602_Init(void)  
{
        //將P04 P05 P06 P07設(shè)置為準(zhǔn)雙向口
        P0_Mode_IO_PU(PIN_4|PIN_5|PIN_6|PIN_7);  
        //將P41 P43 P44設(shè)置為準(zhǔn)雙向口
        P4_Mode_IO_PU(PIN_1|PIN_3|PIN_4);
       
  Delay_ms(15);                              //上電延時15ms
        LCD1602_SetFourMode();        //設(shè)置為四線模式
  Delay_ms(5);
  LCD1602_WriteCMD(0x28); //寫顯示指令(不檢測忙信號)
  Delay_ms(5);
  LCD1602_WriteCMD(0x28); //寫顯示指令(不檢測忙信號)
  LCD1602_CheckBusy();
  LCD1602_WriteCMD(0x28); //寫顯示指令
  LCD1602_CheckBusy();
  LCD1602_WriteCMD(0x08); //顯示關(guān)閉
  LCD1602_CheckBusy();
  LCD1602_WriteCMD(0x01); //清屏
  LCD1602_CheckBusy();
  LCD1602_WriteCMD(0x06); //顯示光標(biāo)移動設(shè)置
  LCD1602_CheckBusy();
  LCD1602_WriteCMD(0x0c); //顯示開及光標(biāo)設(shè)置  
}

/***********************************************
函數(shù)名稱:LCD1602_Display_Str
功    能:lcd1602顯示字符函數(shù)
入口參數(shù):str指針地址
返 回 值:無       
備    注:無
************************************************/
void LCD1602_Display_Str(uchar* str)
{
        while(*str!='\0')               //未到字符串末尾
  {
                LCD1602_CheckBusy();   //檢測忙信號
    LCD1602_WriteDAT(*str);//寫入數(shù)據(jù)
          str++;
  }
}

/*======================================================================
功 能:     在1602 指定位置顯示一個字符:第一行位置0~15,第二行16~31
說 明:     第 X 行,第 y 列  注意:字符串不能長于16個字符
======================================================================*/
void DisplayOneChar( uchar X, uchar Y, uchar ASCII)
{
  X &= 0x1;
  Y &= 0xF; //限制Y不能大于15,X不能大于1
  if (X) Y |= 0x40; //當(dāng)要顯示第二行時地址碼+0x40;
  Y |= 0x80; // 算出指令碼
  LCM_WriteCMD(Y,0); //這里不檢測忙信號,發(fā)送地址碼
  LCD1602_Display_Str(&ASCII);
}

/***********************************************
函數(shù)名稱:Delay_ms
功    能:STC8系列單片機(jī)1ms延時程序
入口參數(shù):ms:延時的毫秒數(shù)
返 回 值:無       
備    注:示波器實(shí)測:1.01ms,內(nèi)部時鐘:24MHz           
************************************************/
void Delay_ms(unsigned int ms)
{
  unsigned int i;
  while( (ms--) != 0)
  {
    for(i = 0; i < 1850; i++);
  }            
}
回復(fù)

使用道具 舉報

地板
ID:958627 發(fā)表于 2021-8-4 09:02 | 只看該作者
湖南 發(fā)表于 2021-8-4 08:58
單片機(jī)和顏色傳感器通信協(xié)議編寫的有問題吧,沒有讀取到正確的數(shù)據(jù)

這是LCD1602的程序
#include "LCD1602.h"
//包含該函數(shù)可以使用_nop_()函數(shù)
#include <intrins.h>

#define  Busy  0x80
/***********************************************
函數(shù)名稱:LCD1602_Delay1us
功    能:STC 1T單片機(jī)1us延時程序
入口參數(shù):us:延時的微秒數(shù)
返 回 值:無       
備    注:外部時鐘24MHz
************************************************/
void LCD1602_Delay1us(unsigned int us)
{
  while( us--)
  {
    _nop_();
  }            
}

/*************************************
* 函 數(shù) 名: LCD1602_WriteHalfByte
* 函數(shù)功能: 向lcd1602寫入半個字節(jié)數(shù)據(jù)
* 入口參數(shù): dat:數(shù)據(jù)
* 返    回: 無
* 備    注:寫入的數(shù)據(jù)為高四位有效,低四位無效
**************************************/
void LCD1602_WriteHalfByte(unsigned char dat)
{
        LCD1602_D7=dat&0x80;        //取數(shù)據(jù)的第7位       
        LCD1602_D6=dat&0x40;        //取數(shù)據(jù)的第6位
        LCD1602_D5=dat&0x20;        //取數(shù)據(jù)的第5位       
        LCD1602_D4=dat&0x10;        //取數(shù)據(jù)的第4位
}
/*************************************
* 函 數(shù) 名: LCD1602_ReadHalfByte
* 函數(shù)功能: 從lcd1602半個讀取字節(jié)數(shù)據(jù)
* 入口參數(shù): dat:數(shù)據(jù)
* 返    回: 無
* 備    注:讀出的數(shù)據(jù)為高四位有效,低四位無效
**************************************/
unsigned char LCD1602_ReadHalfByte(void)
{
        unsigned char LCD1602_Dat=0;
        //輸入先置高
        LCD1602_D7=1;
        LCD1602_D6=1;
        LCD1602_D5=1;
        LCD1602_D4=1;

        if(LCD1602_D7==1)
        {
                LCD1602_Dat |=0x80;
        }
        if(LCD1602_D6==1)
        {
                LCD1602_Dat |=0x40;
        }
        if(LCD1602_D5==1)
        {
                LCD1602_Dat |=0x20;
        }
        if(LCD1602_D4==1)
        {
                LCD1602_Dat |=0x10;
        }

        return LCD1602_Dat;
}

void LCM_WriteCMD(unsigned char cmd,BusyC)
{
        unsigned char H_Data,L_Data;
       
   if(BusyC)
                LCD1602_CheckBusy();
         
        H_Data=cmd&0xf0;                          //取高四位
        L_Data=(cmd&0x0f)<<4;          //取低四位

  EN_Clr();
  RS_Clr();
  RW_Clr();

  LCD1602_Delay1us(10);                          
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入高四位
  LCD1602_WriteHalfByte(H_Data);
  LCD1602_Delay1us(10);
  EN_Clr();

        LCD1602_Delay1us(10);
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入低四位
  LCD1602_WriteHalfByte(L_Data);
  LCD1602_Delay1us(10);
  EN_Clr();
}
/*************************************
* 函 數(shù) 名: LCD1602_WriteCMD
* 函數(shù)功能: 向lcd1602寫指令
* 入口參數(shù): cmd:指令
* 返    回: 無
* 備    注:無
**************************************/
void LCD1602_WriteCMD(unsigned char cmd)
{
        unsigned char H_Data,L_Data;

        H_Data=cmd&0xf0;                          //取高四位
        L_Data=(cmd&0x0f)<<4;          //取低四位

  EN_Clr();
  RS_Clr();
  RW_Clr();

  LCD1602_Delay1us(10);                          
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入高四位
  LCD1602_WriteHalfByte(H_Data);
  LCD1602_Delay1us(10);
  EN_Clr();

        LCD1602_Delay1us(10);
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入低四位
  LCD1602_WriteHalfByte(L_Data);
  LCD1602_Delay1us(10);
  EN_Clr();
}
/***********************************************
函數(shù)名稱:LCD1602_WriteDAT
功    能:向lcd1602寫數(shù)據(jù)
入口參數(shù):dat:數(shù)據(jù)
返 回 值:無       
備    注:無
************************************************/
void LCD1602_WriteDAT(unsigned char dat)
{
        unsigned char H_Data,L_Data;

        H_Data=dat&0xf0;                  //取高四位
        L_Data=(dat&0x0f)<<4; //取低四位

        EN_Clr();
  RS_Set();
  RW_Clr();

  LCD1602_Delay1us(10);
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入高四位
  LCD1602_WriteHalfByte(H_Data);
  LCD1602_Delay1us(10);
  EN_Clr();

        LCD1602_Delay1us(10);
  EN_Set();
  LCD1602_Delay1us(10);                          //寫入低四位
  LCD1602_WriteHalfByte(L_Data);
  LCD1602_Delay1us(10);
  EN_Clr();
}
/***********************************************
函數(shù)名稱:LCD1602_CheckBusy
功    能:檢測lcd1602忙信號
入口參數(shù):無
返 回 值:無       
備    注:無
************************************************/
void LCD1602_CheckBusy(void)
{
        unsigned char H_Data,L_Data;
       
  while(1)
  {   
    EN_Clr();                  
    RS_Clr();
    RW_Set();

    LCD1602_Delay1us(10);
    EN_Set();
    LCD1602_Delay1us(10);
    H_Data=LCD1602_ReadHalfByte();    //讀取忙通道數(shù)據(jù)高四位
    LCD1602_Delay1us(10);
    EN_Clr();
               
                LCD1602_Delay1us(10);
    EN_Set();
    LCD1602_Delay1us(10);
    L_Data=LCD1602_ReadHalfByte();    //讀取忙通道數(shù)據(jù)低四位
    LCD1602_Delay1us(10);
    EN_Clr();

    if((H_Data&0x80)!=0x80)                                          //判斷忙信號
    {   
      break;
    }
  }
}
/***********************************************
函數(shù)名稱:LCD1602_SetFourMode
功    能:設(shè)置lcd1602為四線模式。
入口參數(shù):無
返 回 值:無       
備    注:無
************************************************/
void LCD1602_SetFourMode(void)
{
        EN_Clr();
  RS_Clr();
  RW_Clr();

  LCD1602_Delay1us(10);
  EN_Set();
  LCD1602_Delay1us(10);
  LCD1602_WriteHalfByte(0x20);//寫入控制字節(jié),四位模式
  LCD1602_Delay1us(10);
  EN_Clr();
}
回復(fù)

使用道具 舉報

5#
ID:958627 發(fā)表于 2021-8-4 09:03 | 只看該作者
湖南 發(fā)表于 2021-8-4 08:58
單片機(jī)和顏色傳感器通信協(xié)議編寫的有問題吧,沒有讀取到正確的數(shù)據(jù)

謝謝您了
回復(fù)

使用道具 舉報

6#
ID:844772 發(fā)表于 2021-8-4 09:03 | 只看該作者
我只在arduino用過,沒出啥特別問題,只是離遠(yuǎn)的時候測的不準(zhǔn)。
回復(fù)

使用道具 舉報

7#
ID:958627 發(fā)表于 2021-8-4 09:17 | 只看該作者
現(xiàn)在我已經(jīng)有程序了,并且編譯過并沒有任何錯誤,所以想讓各位幫我看一下是有哪里不妥當(dāng)嗎
回復(fù)

使用道具 舉報

8#
ID:958627 發(fā)表于 2021-8-4 09:18 | 只看該作者
這里是我的程序
回復(fù)

使用道具 舉報

9#
ID:844772 發(fā)表于 2021-8-4 15:44 | 只看該作者
bb=(unsigned long)(TH1*256+TL1)*255/byz; 這句有點(diǎn)問題,數(shù)據(jù)類型也不對,建議你先不用白平衡,改為bb=TH1*256+TL1,距離近點(diǎn)用不著白平衡。等差不多了,你再調(diào)白平衡。
回復(fù)

使用道具 舉報

10#
ID:958627 發(fā)表于 2021-8-4 15:58 | 只看該作者
glinfei 發(fā)表于 2021-8-4 15:44
bb=(unsigned long)(TH1*256+TL1)*255/byz; 這句有點(diǎn)問題,數(shù)據(jù)類型也不對,建議你先不用白平衡,改為bb=TH ...

你好,我嘗試改變了,但是依舊顯示的全部是255
回復(fù)

使用道具 舉報

11#
ID:844772 發(fā)表于 2021-8-4 17:22 | 只看該作者
安逸啊 發(fā)表于 2021-8-4 15:58
你好,我嘗試改變了,但是依舊顯示的全部是255

抱歉,我沒說清楚,既然沒做白平衡,它的范圍是0-65535,你看是不是在這個范圍,這決定你模塊是否有效,
我主要認(rèn)為你在強(qiáng)制類轉(zhuǎn)換上有問題,簡單辦法是改比例因子算法: 1。是改這句 ryz=65535/(TH1*256+TL1);//其實(shí)這里的比例因子應(yīng)該為255/(TH1*256+TL1)  2。是改bb=(TH1*256+TL1)/byz;
當(dāng)然三個顏色都要改啊。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表