|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示6 f0 F0 [: N, z: k( p# X6 ]
% a: F: I6 ^+ W1 Q) L v/ @
; c$ d$ o; y, h7 A: ~/ M此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!% u) A+ W/ _% I. K$ G
1 M A+ n/ J% w1 z, O+ q8 _6 q) ~$ L! j; _/ `% [
) q7 G. w+ F, q* K, S N0 P$ G: q
) A. }; y) O2 E U) {
5 H$ ^! V$ J& M( y5 x
单片机源程序:) I) P7 l6 n/ `! w, \7 p9 e9 Q
#include <reg52.h> //添加STC89C52所需头文件
3 ^. j: A' E) ?' C#include <string.h>
$ s7 [6 i- d+ Q: Z: ^0 C4 d#define uchar unsigned char //宏定义无符号字符型变量6 r( N0 m6 b( A9 _# V9 J
#define uint unsigned int //宏定义无符号整型变量' b; F" H# @* v" U/ ]
uchar str[3]; //定义数组' ] c- F1 H; ^: J* e7 P/ u- l
uchar *s; //定义指针
5 C( t$ _, p+ Uuint date; //定义数据类型
8 ]; w; T& S! e$ k) Q- t6 S6 Ruint dispcount=0; //中断计数
: f. s4 a1 M+ P( `! k! yuint lck=0; //定时器计数7 a2 g* K ^5 d( x% o9 x
uint disp=0; //频率值计数& f& C* Z; g' s3 i3 }& C
sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器% {" E( R" x/ X9 a
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作5 y/ e" T) y$ t! c& V. m
sbit E=P2^5; //使能端
) e& l8 B7 b5 Tsbit s0 = P2^0; //声明引脚
* f! g/ _5 ^8 x6 M3 {# A: E0 Tsbit s1 = P2^1;) @* u& g) n+ C, b) d# |
sbit s3 = P1^7;
' z2 U* Y6 q0 _) Lsbit s2 = P1^6;
1 R: B" i# w) T% `6 G( v6 msbit oe = P1^2;& m3 A) k/ n7 u) w
/**************************************************
* [) }) A' O) A 延迟函数,延时1ms 4 i, }- u, s' X' R M
**************************************************/+ x' H" G5 z2 _ A6 P
void delay1ms(uint i)
$ S1 L; \& _. t1 Y{ uint j;
7 Q B- @" f, [ Q3 M; b9 i while(i--)
7 ~8 Y$ `- t% P. e# I/ B* S {
; @ s$ A/ n& O* G for(j=0;j<125;j++);- r0 m D3 A$ X* l: u
}
. b* B' ~. G: A; s: G5 t# B2 ~}4 \, y$ w4 k: I
/**************************************************
0 u* _! e$ s, `1 E 初始化STC89C52
5 H$ A5 X, @ s) ^5 \**************************************************/
8 J" e& X( L# k3 z( e4 ?void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms
# {2 ?) b; |$ r& M' x8 |9 J 5 A3 [: \0 a8 r5 G* v. d
TMOD=0x0;$ G: }2 r6 v" A- o+ L' P) p8 S
TH0=0xe0;
1 i0 j7 M- \" u3 J: Q" ^4 j TL0=0x18;) V- G% | x) U0 D& Y
}. ?/ Y/ f1 z" Y4 ~6 L/ Q ^
void timer0(void) interrupt 1{ //定时器函数 0 d; m! m) n4 n9 \) a: Q) }
TH0=0xe0; //装入初值: q6 \ a( c- o2 @
TL0=0x18; //装入初值(定时器中断每1ms中断一次)' |0 o$ B, e* j& U% L
lck++; //设置累加变量,累加1000次即为1S
- E$ F: J6 }- L! P! b if(lck==1000){ //判断是否到了1S
5 p' P! Y' `1 e- r# P disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数/ u d, S/ x" G6 C5 l
lck=0; //对累加变量清零,用于下1S的累加计数
/ Z: H& O! U. }; X% o5 G X; b8 Q1 ] dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数
% |* T+ o0 w/ l5 c# m% J6 k }
3 c2 I$ V0 l% d9 y3 v4 W r}7 k0 R/ Z8 D% P
void int0(void) interrupt 0{//外部中断0的处理函数6 Z; h1 x7 V; b. u
dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口
/ o# P( I' i! U //每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数5 N- `( ]$ _2 Y7 f4 T9 Q5 W+ m8 @' l
}7 L h& ^2 e b! d& Y
/*******RGB三种颜色通道选择模块
+ y) o5 f5 }8 @& k**************************************************/ ( f. ]5 ^) m: d0 {5 x' W) p0 B& _
void red()
4 I+ [. u6 W8 ~{ //红色通道选通函数
! k ?0 a) Y& X oe = 0; //使能TCS3200
$ g6 D& a" {) A1 Z* K s2 = 0; //选通红色滤波器
* v9 K2 D1 D M- q- J" d) C( K s3 = 0;
) ? P0 L, e, O6 F# C" E+ i s0 = 0; //设置输出为2%比率
# q" t$ L y9 f% @ s1 = 1;. g$ u6 \% G5 f$ x" g. {, h
delay1ms(1100);//延迟1S
8 |, e8 m# [7 L! o3 a date=disp/100;//依据方法2,求出比例系数
( ^5 d; A) j' J* C: D0 m date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值
9 g+ `% Y( Y7 w5 d}
- N! C7 P5 @) Lvoid green() //绿色通道选通函数! ?; N9 m# Y/ J) F4 H' @2 ?9 N3 C
{
# c& e# U+ n- {( q/ N( t s0 = 0;
: E* |. N4 d% ^2 `/ z1 o s1 = 1; //设置输出2%的比率
/ G' ]7 e: w- n6 C7 a$ q oe = 0;3 |- r5 m. |$ B- j* S Z+ a
s2 = 1;
; b( Y D% h( T5 r, n$ r/ }, ?) R s3 = 1;
+ U6 i$ g, U& Y8 D. I delay1ms(1100);
2 M" {- F' ~, E/ ~ date=disp/100;% b; w4 d/ m+ t6 Z7 j( R% M! \: D
date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值1 C3 r. |% C% M' {* Z
}
5 ~' z; g3 D7 j# L, xvoid blue() //蓝色通道8 h$ t( c, U+ z$ K8 a
{ 3 t9 X4 Y. q n# }+ n1 y$ }( I
//P1=0x81;, h5 o( P/ e9 D" e
s0 = 0;
P, q5 q6 O6 |. o# R, }! T2 ~ s1 = 1;9 F2 j' ]5 R6 U, f# o
s3 = 1;
- Z7 i0 |* ]6 r* E3 M9 g3 ]5 ~ s2 = 0;4 O- U o7 {1 ~/ Q
oe = 0;0 A' h! w( W/ w; s
delay1ms(1100);$ |* V+ P* h' h4 Z4 [+ v
date=disp/100;. p2 ]& u+ M( C4 g* O/ g. l) U, O
date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值% Z, l3 c. n, o8 y! \9 P
}- F& I7 }3 g0 V( G1 f0 W
/**************************************************
s3 E2 u6 h' E3 D 整型数转化成字符串,以便LCD输出显示 / \( U9 i4 }7 c( w4 B
**************************************************/" A& Y9 p* a v
uchar * int2str(uint d)1 ?! S' M4 E( E+ I, R8 ? M
{ if(d>=255)! @4 a0 r3 l; q X* v$ B/ ^
{ d=255;& a9 u+ ~% Y. ~" e$ |. w5 c
str[0]='0'+d/100;
' ^, _$ W! T& j9 S# B# z9 \str[1]='0'+d%100/10;7 v6 \% `7 c" j! }
str[2]='0'+d%10; }
+ ]( Q; d9 N! x; { D+ D else! x& C. _0 |$ s0 K% M
{ str[0]='0'+d/100;
# s4 |) k+ a F S6 `3 o, v" \ str[1]='0'+d%100/10;
2 X1 w. R( u. b0 D str[2]='0'+d%10; }
. {* W! z! K- f* P1 q return str;
" T V9 _" I Z( j7 Q5 m}
/ L0 G' s' J5 H; r1 P9 ]# Y8 f/*****LCD显示模块*********/& d: B2 i# \1 K1 _% @
& _2 E* G. T; ?, F I
4 m( P; E+ t$ z6 \* |void LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
. k' u% B, q& ~8 W, \* b{ RW=0; RS=0; E=1;! d- j1 B \) E7 _; I
P0=com; delay1ms(10);1 s( g f) a/ o" e) L1 a4 |
E=0; RW=1;+ y3 q7 \& ^, g) P2 }3 O& \( ^
}8 x+ y- d/ q% m
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据& p3 _/ y @* c5 k
{ RW=0; RS=1; E=1;
' R; ^; h5 b. d P0=dat; delay1ms(10);0 ]3 P* B' o( J* j9 h! h8 w+ B
E=0; RW=1;
3 m& R- q+ o8 R8 J- W4 _}
& `% w. @3 A Q$ d! [, }- d; u$ U# l/ @void init_LCD(void) // 初始化lcd
: o4 N8 N/ \7 M/ \$ M{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效0 D" v- ?( r5 ~8 b
LCD_w_com(0x0e); // 显示字符 关闭光标* h2 L5 w9 } t& y8 r/ J
LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1% i- r8 P: j4 B
}
1 d: p& ]4 q. s6 T1 J% K6 Lvoid clear_LCD() //清屏
, i* X7 e2 \3 d8 _( I{
& S: g' t [& U, ~* ~- m% U LCD_w_com(0x01); //清屏指令* ]5 ^: f7 T1 l2 T
LCD_w_com(0x02); // 光标归位 即光标置于左上位置
K& B2 t3 u' \}# W0 n1 j! R P5 c2 g# B
void display_LCD_string(uchar *p) //字符串输出函数
0 k E* P b5 o* n{ while(*p)
6 d* Q7 y- }3 a, X0 I+ P6 V { LCD_w_dat(*p); p++; delay1ms(10); }5 M% p% w0 w- Z( i' ]; Y7 _% Y% }
}) E0 q- v `0 C/ ?' b- w
void gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列
9 b; P; t' G( d: X" B7 \" z{ if(x==1) LCD_w_com(0x80+y);, v6 z, H! j4 C$ u4 I; T
else LCD_w_com(0xC0+y);
, K5 @) w" s- \7 t, V; j}9 Y; K- T- x) G( N- I1 y
5 ?. Y" l8 i( v% e2 @- K
4 l7 J- R3 ]. x" i$ E- A
/**************************************************0 e/ c, I, _7 m
主函数
: ~2 E' @4 ^ I- A) \" Y**************************************************/
1 m7 h4 g9 u( D( S, Evoid main(void), g; E5 k# ]: u% {& f
{ IT0=1; //INT0下降沿中断
) H1 W! ]! N+ ~5 n% S' |' P- V EX0=1; //允许INT0中断
- Q' i' Z1 r' Z0 g7 v: r1 k initTimer(); //装入初值9 L- p; D, A, ]: ?( E. Q6 @( K6 A
TR0=1; //开定时器T0. A+ s; n- m( L \
ET0=1; //允许T0中断
6 j8 w- c* K$ e2 a9 v* _ EA=1; //中断总控制
- d8 S7 |& \* T1 m: ~! e% e init_LCD(); //LCD初始化4 q) I- }0 p6 ?, W8 j, c: n
clear_LCD(); //清屏
) ?" [. w1 B: i; | while(1)$ R4 @+ h" P9 F' k$ p+ n
{ * {& M# p E6 Q! h" x( y
gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值: h' s* ]6 w+ Z2 a% ]
# h; c& C8 _2 @. \( X! e$ O) J9 B% q- l9 Q, ^
9 j) a) H% v+ q! i; z s…………限于本文篇幅 余下代码请从论坛下载附件…………, c2 T; Q( |1 F/ V! a1 V
6 ~+ v/ v$ |3 a
! F8 h; R9 w7 A; N9 d v4 V |
|