您好,您可以帮助我一下吗,这是我的程序
#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接单片机P1.0
sbit tcs230_s3=P1^1;//TCS230 S3接单片机P1.1
sbit tcs230_en=P3^0; //TCS230 EN(E0)接GND
//**************函数声明***************************************
void DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符
void baipingheng();//白平衡子程序
void celiang();//实际颜色程序
void LCD1602_Init(void);
void LCD1602_Display_Str(uchar* str);
void Delay_ms(unsigned int ms);
uint ryz,gyz,byz;//分别定义红色因子 绿色因子 蓝色因子
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;//设定T0以工作方式1定时10毫秒
LCD1602_Init();//LCD初始
baipingheng();//上电时先白平衡一次
while(1)
{
celiang();//颜色测试
DisplayOneChar(0, 0,'R');//以十进制显示RGB中红色的分值
DisplayOneChar(0, 1, rb/100+0x30); //显示百位数据
DisplayOneChar(0, 2, rb/10%10+0x30);//显示十位数据
DisplayOneChar(0, 3, rb%10+0x30);//显示个位数据
DisplayOneChar(0, 5,'G');//以十进制显示RGB中绿色的分值
DisplayOneChar(0, 6, gb/100+0x30); //显示百位数据
DisplayOneChar(0, 7, gb/10%10+0x30);
DisplayOneChar(0, 8, gb%10+0x30);
DisplayOneChar(0, 10,'B');//以十进制显示RGB中蓝色的分值
DisplayOneChar(0, 11, bb/100+0x30);
DisplayOneChar(0, 12, bb/10%10+0x30);
DisplayOneChar(0, 13, bb%10+0x30);
//*****在LCD1602的第二行以16进制显示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;//设定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;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时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;//选择蓝色滤光器
TR0=1;//10毫秒开始计时
TR1=1;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时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;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时0
TR1=0;
tcs230_en=1;
gb=(unsigned long)(TH1*256+TL1)*255/gyz;
if(gb>255)gb=255;//判断RGB值是否合法
}
//******************************************************
//白平衡子程序
void baipingheng()
{
TMOD=0x51;//设定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;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时0
TR1=0;
ryz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)
//**************求取蓝色因子***********************
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
TH1=0;
TL1=0;
tcs230_s2=0;
tcs230_s3=1;//选择蓝色滤光器
TR0=1;//10毫秒开始计时
TR1=1;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时0
TR1=0;
byz=TH1*256+TL1;//其实这里的比例因子应该为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;//开始计数
while(TF0==0);//等待定时器溢出
TF0=0;//清楚定时器0溢出标志
TR0=0;//关闭定时0
TR1=0;
tcs230_en=1;
gyz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)
}
/***********************************************
函数名称:LCD1602_Init
功 能:LCD1602初始化
入口参数:无
返 回 值:无
备 注:详见数据手册定义。
************************************************/
void LCD1602_Init(void)
{
//将P04 P05 P06 P07设置为准双向口
P0_Mode_IO_PU(PIN_4|PIN_5|PIN_6|PIN_7);
//将P41 P43 P44设置为准双向口
P4_Mode_IO_PU(PIN_1|PIN_3|PIN_4);
Delay_ms(15); //上电延时15ms
LCD1602_SetFourMode(); //设置为四线模式
Delay_ms(5);
LCD1602_WriteCMD(0x28); //写显示指令(不检测忙信号)
Delay_ms(5);
LCD1602_WriteCMD(0x28); //写显示指令(不检测忙信号)
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x28); //写显示指令
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x08); //显示关闭
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x01); //清屏
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x06); //显示光标移动设置
LCD1602_CheckBusy();
LCD1602_WriteCMD(0x0c); //显示开及光标设置
}
/***********************************************
函数名称:LCD1602_Display_Str
功 能:lcd1602显示字符函数
入口参数:str指针地址
返 回 值:无
备 注:无
************************************************/
void LCD1602_Display_Str(uchar* str)
{
while(*str!='\0') //未到字符串末尾
{
LCD1602_CheckBusy(); //检测忙信号
LCD1602_WriteDAT(*str);//写入数据
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; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
LCM_WriteCMD(Y,0); //这里不检测忙信号,发送地址码
LCD1602_Display_Str(&ASCII);
}
/***********************************************
函数名称:Delay_ms
功 能:STC8系列单片机1ms延时程序
入口参数:ms:延时的毫秒数
返 回 值:无
备 注:示波器实测:1.01ms,内部时钟:24MHz
************************************************/
void Delay_ms(unsigned int ms)
{
unsigned int i;
while( (ms--) != 0)
{
for(i = 0; i < 1850; i++);
}
} |