A. 单片机RGB调色程序 要求基于PWM(STC系列单片机c语言)可以实现至少60种颜色调节,有多种模
选用STC12C56XX的单片机,利用三路PWM来调色就简单了,再多的颜色无非是把表格做的大点,利用查表法,来获取颜色的PWM寄存器的初装值就可以了。
B. 用 stc12c5a60s2单片机控制颜色传感器tcs3200的程序,我做得不知为什么识别不了,
1、参考网上程序或者模块提供的程序
2、仔细参读datasheet,尤其研究时序以及逻辑功能的实现
3、多动脑筋思考,学会调试程序,多网络Google。
/*模块的使用方法:把板距离白纸2CM处开机,使输出的数据位FFFFFFF(白平衡),接下来就可以正常使用
实现功能:对颜色传感器输出RGB
使用芯片:AT89S52或者STC89C52或AT89S51STC89C51
晶振:12MHZ
编译环境:Keil
作者:zhengzhongxign39*/
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
//==============LCD1602接口连接方法=====================
/*-----------------------------------------------------
|DB0-----P0.0|DB4-----P0.4|RW-------P2.3|
|DB1-----P0.1|DB5-----P0.5|RS-------P2.4|
|DB2-----P0.2|DB6-----P0.6|E--------P2.2|
|DB3-----P0.3|DB7-----P0.7|
---------------------------------------------------*/
//================================================*/
#defineLCM_DataP0//LCD1602数据接口
#defineBusy0x80//用于检测LCM状态字中的Busy标识
sbitLCM_RW=P2^3;//读写控制输入端,LCD1602的第五脚
sbitLCM_RS=P2^4;//寄存器选择输入端,LCD1602的第四脚
sbitLCM_E=P2^2;//使能信号输入端,LCD1602的第6脚
//=================颜色传感模块连接=====================
/*-----------------------------------------------------
|EO-----GND
|S0-----VCC|S2-----P2.0|OUT-------P3.5
|S1-----VCC|S3-----P2.1|
---------------------------------------------------*/
sbittcs230_s2=P2^0;//TCS230S2接单片机P2.0
sbittcs230_s3=P2^1;//TCS230S3接单片机P2.1
sbittcs230_en=P3^0;//TCS230EN(E0)接GND
//**************函数声明***************************************
voidWriteDataLCM(ucharWDLCM);//LCD模块写数据
voidWriteCommandLCM(ucharWCLCM,BuysC);//LCD模块写指令
ucharReadStatusLCM(void);//读LCD模块的忙标
voidDisplayOneChar(ucharX,ucharY,ucharASCII);//在第X+1行的第Y+1位置显示一个字符
voidLCMInit(void);//LCD初始
voidDelayMs(uintMs);//1MS基准延时程序
voidpingheng();//白平衡子程序
voidceliang();//实际颜色程序
uintryz,gyz,byz;//分别定义红色因子绿色因子蓝色因子
uintrb,gb,bb;//RGB值
uchartab1[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//***********************主程序******************************
main()
{
TMOD=0x51;//设定T0以工作方式1定时10毫秒
LCMInit();//LCD初始
pingheng();//上电时先白平衡一次
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');
DelayMs(250);//每隔0.25秒测试一次颜色
}
}
//******************************************************
//白平衡子程序
voidceliang()
{
//*********求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=(unsignedlong)(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=(unsignedlong)(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=(unsignedlong)(TH1*256+TL1)*255/gyz;
if(gb>255)gb=255;//判断RGB值是否合法
}
//******************************************************
//白平衡子程序
voidpingheng()
{
//**************求取红色因子***********************
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)
}
/*======================================================================
LCM初始化
其他程序网上自己找找参照
C. 51单片机从TFT彩屏上读取某一点颜色的函数方法
这和TFT液晶屏型号有关,还和你采用何种接线方式有关
如以下是ILI9341控制的单片机读方法,它采用16位数据线,所以一次读出16位,一个点本来要读3次,但时序要求读4次
R = *(__IO uint16_t *)Bank1_LCD_D实际上就是 给液晶屏一个读信号,然后单片机从总线上获得数据,这是STM32单片机以8088总线的时序操作方式,因此只是一条指令,由于51单片机是8位数据线,因此这一句要分好多语句才能完成
uint16_t LCD_RD_data(void) //连续读4次
{
uint16_t R=0, G=0, B=0 ;
R = *(__IO uint16_t *)Bank1_LCD_D; /*FIRST READ OUT DUMMY DATA*/
R = *(__IO uint16_t *)Bank1_LCD_D; /*READ OUT RED DATA */
B = *(__IO uint16_t *)Bank1_LCD_D; /*READ OUT BLACK DATA*/
G = *(__IO uint16_t *)Bank1_LCD_D; /*READ OUT GREEN DATA*/
return (((R>>11)<<11) | ((G>>10)<<5) | (B>>11));
}
uint16_t LCD_GetPoint(uint16_t x , uint16_t y)//完整的读程序
{
uint16_t temp;
LCD_SetCursor(x, y);
LCD_ILI9341_CMD(0x2e); /* 读数据 的命令*/
temp=LCD_RD_data();
return (temp);
}
D. 单片机(任何一种)+ov7670做图像识别的程序,比如说能识别出图像的颜色或者图像中的点的位置,有思路也行
识别颜色和位置应该比较简单啊,我之前就做过用STC12C5A60加ov7670控制小车识别指定颜色,思路是这样的:
配置好OV7670,比如说输出格式为RGB565,分辨率为160X120,在程序中设置R,G,B阀值对每个像素的R,G,B进行比较,如果阀值比对OK,就输出此像素的坐标值。假若设置左上角为坐标原点(0,0),则第一行结束的坐标即为(159,0),依次对整个图像数据采集判读即可得到相应颜色的坐标值进而判读指定颜色目标的位置。
E. 单片机机械手怎么识别三种颜色的球
不同颜色的波长不同,机械手上加上颜色传感器就可以识别了