|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示
# F3 @2 I0 |8 j0 p" X. }; g( J
- b8 o$ o# [; g$ w2 L( E& w$ ]/ X4 S& p. D0 u1 ?) Z
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!1 v! j3 h5 V& A/ P) a
' ]* K: j6 o+ c" F- ?3 r* P: V; O( z
. q1 l# W" ^6 i. O
- \1 q8 p5 o2 `% G8 r
8 b; Q: W# C2 s$ u) I3 I4 ]6 j( M! d4 n2 d. r( c
单片机源程序:9 ^4 r9 S( b8 J
#include <reg52.h> //添加STC89C52所需头文件
! x( M7 B8 W- \4 ?. G2 l#include <string.h>& c( y9 v0 H9 N6 [$ k+ S
#define uchar unsigned char //宏定义无符号字符型变量! l0 s' t7 O' a, J' V) B/ U* Q* w
#define uint unsigned int //宏定义无符号整型变量
8 ]4 E# c4 t( u% L1 tuchar str[3]; //定义数组
. O0 z& t( ?: M7 H" Y3 t# Luchar *s; //定义指针
+ s) d( o, S4 ^4 Puint date; //定义数据类型
* k9 P: u4 y8 o% ]% Y) G* A- Duint dispcount=0; //中断计数
0 L1 w8 N0 }4 quint lck=0; //定时器计数; P! \ f k( Q! Q4 j
uint disp=0; //频率值计数
9 ^: V8 |" ?- C& [sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器( l1 m/ C2 k% n, e5 o8 Z. B: R& ^
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作' G: d: {4 ^ _% z5 M* D. `$ Z
sbit E=P2^5; //使能端5 s, L; I$ M% t# Z+ |/ I8 T
sbit s0 = P2^0; //声明引脚* r& I3 s* t/ Y: j% R3 t7 S
sbit s1 = P2^1;4 X- q2 L2 O& v4 l0 d8 b7 Y
sbit s3 = P1^7;3 }! z0 x: i2 w5 w
sbit s2 = P1^6;
1 L; c" Y; E- x$ V+ K9 \$ Q: ^sbit oe = P1^2;, J4 M9 I: l1 E. w0 l( o; k/ k
/**************************************************
. `7 y( i: N8 t0 l- H9 C( B2 l 延迟函数,延时1ms 1 j/ |5 Y$ p5 g) V/ T' I: I) a' T
**************************************************/ h( l+ M3 i; ], [# |; M
void delay1ms(uint i)
% G# C* Y# I+ I) v{ uint j;1 y7 M& w" L( w% ^
while(i--)9 d5 Z# }: `& w4 x3 I3 P
{
1 P) h- S5 n6 R/ j9 g6 X for(j=0;j<125;j++);
0 V1 c% K6 |$ ]9 [' \ }
3 X+ z% G) n" \2 h; J}" W+ S% {0 U! d, _6 V% M8 O& q5 S
/**************************************************
6 i! g' b4 N7 y& P 初始化STC89C52
4 v: ^1 v' m; A**************************************************/1 v8 V: Y4 z1 K: r
void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms
1 W& \& c* o! l7 `6 g' W" V: i; T % z* L) }" A" p2 @8 C
TMOD=0x0;- h( y! T8 m! a* j+ d
TH0=0xe0;" Z/ H5 i. [. _7 V$ i) ?
TL0=0x18;! o D- h T' K k2 j
}
. f% h4 n9 T( Svoid timer0(void) interrupt 1{ //定时器函数 ; i& [: O h( p7 o3 f
TH0=0xe0; //装入初值# W7 v+ n L$ f1 m- u6 \! \# d
TL0=0x18; //装入初值(定时器中断每1ms中断一次)
; z8 O5 y9 |. V lck++; //设置累加变量,累加1000次即为1S: K) z* H% }& F* {" t. M
if(lck==1000){ //判断是否到了1S
9 S) A( Z' V4 G; p. y; N# t8 X. d4 O+ A disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数3 b% ?9 N' |7 |- Z5 t
lck=0; //对累加变量清零,用于下1S的累加计数
: h& A; r- n) w3 R+ c dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数" ^; L+ O0 m7 n% d4 a& V5 E& f
}
) I% \3 l- [) k6 n5 I7 ]" `}
" j! B& b, m* Z# G8 C/ Ivoid int0(void) interrupt 0{//外部中断0的处理函数
" i3 }1 J) ?- C' h5 B/ s dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口! ]* L# z, f$ O5 _$ @1 H+ h( K
//每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数" ^( e+ L$ C/ T% \
}
5 B7 O/ w% d0 s/*******RGB三种颜色通道选择模块 9 T% l9 G0 D4 U u3 D/ Y1 R/ l
**************************************************/
: U+ y0 H, V: }9 \! x, U- o( Qvoid red()
6 `1 S/ ]' H* B \+ Z$ b{ //红色通道选通函数
' G# B/ H9 g" [& x oe = 0; //使能TCS3200( b" u/ F2 b% Q5 D# y) K# N
s2 = 0; //选通红色滤波器
: b8 F9 X- u2 C* p" J s3 = 0;) j: S( I6 K) O4 I' ?) A7 J
s0 = 0; //设置输出为2%比率: }& f5 S( T* c9 |
s1 = 1;
/ @2 i" D, S3 B" t% @* t delay1ms(1100);//延迟1S
- J" U1 Q/ a$ Z" N date=disp/100;//依据方法2,求出比例系数& [8 i' e' x. K6 m
date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值. t+ M* x8 J/ e9 ^) [) `, O! }
}
/ g/ X2 H& P6 Z3 \/ _void green() //绿色通道选通函数
* l: E! S$ E! m" V! H{ * [1 D8 A+ I) X1 V* F8 R
s0 = 0;
" I" f: T% Y l! I9 H+ J- Y s1 = 1; //设置输出2%的比率. H- w5 ?2 \' {4 O
oe = 0;
! K' Q9 ?! V0 ~; T6 H s2 = 1;
' }/ ]7 O+ J3 R+ X5 P s3 = 1;
' y- a7 M9 O) r delay1ms(1100);
/ e, h& m( o3 L* y1 X date=disp/100;
3 ~+ Y+ Q8 a6 O$ n$ T) U+ k date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值6 b1 S5 t6 S: N5 _# T4 W+ T8 j, a
}
4 s* Z2 g4 d5 i6 v/ r$ Zvoid blue() //蓝色通道
g; c6 |4 E7 G7 w( D$ r{ ) b2 U( V; X2 B) V
//P1=0x81;8 j: w% q: g: X; B2 m, q
s0 = 0;% J4 l8 e# z5 Z! o- F: Z- W. G
s1 = 1;
! j! i2 }5 o/ e! ^3 x, M) a4 N s3 = 1;
6 _, d4 |' ^6 V s2 = 0;! A b' F5 y' Q! R% N2 o
oe = 0;
& P/ `& n1 O/ ~7 D) O; S' x5 \- f9 J delay1ms(1100);
8 }/ H6 L6 K" {5 v date=disp/100;. Q4 h: @# P% t
date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值
4 o: J# \& [) G7 h5 M( z}
3 o; [9 A0 D7 e) F% x5 c8 S3 B/**************************************************! ?4 e$ S9 [$ B8 g8 o& u# \ O, Y
整型数转化成字符串,以便LCD输出显示
9 H' f# Y! m1 L8 |**************************************************/
2 _' r2 U! I7 h6 N% B- huchar * int2str(uint d)
* L9 E# p7 [0 i{ if(d>=255)
4 Z$ L" [- N. X, A8 ]2 j( ~- s$ c5 l8 b { d=255;
4 o8 p2 T9 G" Ystr[0]='0'+d/100; Z, r' m% d6 o7 L
str[1]='0'+d%100/10;
* _ d2 E8 I( V1 d8 p( K5 q' G) J str[2]='0'+d%10; }7 R7 i. T: v- I3 S' `
else
4 j6 @0 E0 [0 I+ X { str[0]='0'+d/100;- n# m( O! Y7 b2 ~$ Z6 G1 u6 `0 J
str[1]='0'+d%100/10;: v" O# g% e5 x4 F( A
str[2]='0'+d%10; }
9 t/ \0 o3 I7 x2 e: d return str;+ t/ ]: _4 T S! }! o8 u c- J* ?
}
$ k! h( @/ W0 b; w/*****LCD显示模块*********/
7 U% E" k$ j1 }! h: m3 ]+ t) t( u! U- _" s$ F4 g2 j
* k/ I) ?& Y" K; |2 y2 Uvoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
4 o3 N5 d% j& R6 Z{ RW=0; RS=0; E=1;; G# m: b" ]/ p8 i
P0=com; delay1ms(10);
4 y1 V2 |& t* e- o- L3 F& U E=0; RW=1;
+ S: U p; ~/ N4 O8 s}
. J+ S" U7 P5 f* \ void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据- ^" @' g& h( L
{ RW=0; RS=1; E=1;
) p' V2 m0 s3 J" U1 ^ P0=dat; delay1ms(10);4 j+ @* c! P' E+ B0 W- V5 u7 q
E=0; RW=1;
7 V" A5 O$ L# m+ o2 [* D}
1 ?' \( N$ Z0 @4 J3 {5 o3 vvoid init_LCD(void) // 初始化lcd- z& c# u: I6 M% h7 |$ u
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效& v, J! z y0 P* }
LCD_w_com(0x0e); // 显示字符 关闭光标
/ c. Q. \$ M8 z2 I2 Q/ o; I LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1
& O# A3 ]. M5 @* H) m}
2 E+ m# p1 U' E% K* K" cvoid clear_LCD() //清屏
. c4 [+ ]* o" o{
4 l! ?7 o) b4 q# H LCD_w_com(0x01); //清屏指令. U- K) b/ H5 W# N4 O
LCD_w_com(0x02); // 光标归位 即光标置于左上位置
' Q2 V) ]1 Z" N! u7 X4 f0 f/ V6 y0 T}! [4 ^, S5 A V) |% S8 \3 V* q- ^
void display_LCD_string(uchar *p) //字符串输出函数/ N7 ?+ d1 [: y, w) x3 s; E$ i% Z
{ while(*p). e' J% P4 ~. Z3 @
{ LCD_w_dat(*p); p++; delay1ms(10); }
, M1 P$ ^ \# ]( S3 L2 b}
. X$ }/ \2 q5 `2 ovoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列9 ?) G% c; K4 q
{ if(x==1) LCD_w_com(0x80+y);
; ?2 q$ O+ n" b else LCD_w_com(0xC0+y);
4 G/ X6 s' n" W; Y5 ?}
9 g' Q7 }5 l- h! w/ H# ^& p. P" J" }* f- z$ r/ M, q/ T d" Y! t
6 c( I* k5 J! \$ ?0 K
/**************************************************
, [: o% ~( Z3 [/ o" W 主函数 2 Q! n% y# Z" z4 X
**************************************************/
! D1 Z' U) C6 h0 N7 F; a2 |. F5 pvoid main(void)
7 C- l' P4 o/ p. [1 x& d' f{ IT0=1; //INT0下降沿中断* L9 Y6 \) \' ]7 @, b
EX0=1; //允许INT0中断4 } ]9 ^% G9 U, A- A
initTimer(); //装入初值
3 `, I& e6 o! L _( V" W1 r4 k$ p TR0=1; //开定时器T04 w8 x4 C a) F# [
ET0=1; //允许T0中断$ A: }3 f7 R9 E! X: R5 g/ X
EA=1; //中断总控制
7 @8 Z3 p2 n0 q: X+ _& p init_LCD(); //LCD初始化
9 C1 }1 S" h) H- h3 I clear_LCD(); //清屏 O- J8 R+ }8 f% N( G
while(1)
0 `4 D$ [3 G, W1 G1 Q { 2 j- R4 t, ^, l" x( ]
gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值
+ Z1 t2 w* J" U
% l0 X+ C$ C9 G0 h0 _ R$ |0 r7 l: d8 w8 F
% _7 J. R6 x2 S/ y& R
…………限于本文篇幅 余下代码请从论坛下载附件…………
( F- @2 @+ Q# F2 u
1 G9 \- z3 Z. X( J. V2 U
, A1 D z( o) k% t |
|