|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示
& H5 H" B) Y( E8 \8 p1 G2 n' E% i5 p
* k/ B( g$ i7 C. x) J% b) N- F+ U3 D
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!/ ]5 i* p, p$ ]5 H1 a% p
* V, y! \. c; i7 b0 i( E
" G O/ e; i1 d& U' ]
8 w5 F5 n5 k8 K& n2 O' ?2 u* r' }! i! W' P( J
1 e) h/ Q8 P" j4 b) S0 r2 ^) |
单片机源程序:& M( G3 ?$ v7 S- ~$ g6 B" d
#include <reg52.h> //添加STC89C52所需头文件9 A- V" L6 J1 E) |; k+ {' T% ^, h- r
#include <string.h>$ K& \" g1 ~5 {: ?" h( U5 G" M
#define uchar unsigned char //宏定义无符号字符型变量) j3 }) g1 E* C" G" {4 H
#define uint unsigned int //宏定义无符号整型变量
( S* ?% f" e g1 u+ iuchar str[3]; //定义数组
0 T2 L. u! w: s' n' Quchar *s; //定义指针
6 \% ^: C: O# A$ i$ quint date; //定义数据类型# e- ]4 V7 s6 g2 i
uint dispcount=0; //中断计数
% Q6 f+ L$ \- P* Q1 M, ]3 Ouint lck=0; //定时器计数& G+ F6 C; O/ G5 M
uint disp=0; //频率值计数
/ Q2 }. P) P, r- v/ g5 Esbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器0 W% H- S5 G2 {& U2 W4 B
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作
/ y. J4 j: N5 u9 _3 ^# usbit E=P2^5; //使能端2 y2 `" ?: R, f# x' _
sbit s0 = P2^0; //声明引脚- n T1 v. p8 k: X* V3 D' I* G
sbit s1 = P2^1;
6 e: s+ \1 \8 B: k L; [sbit s3 = P1^7;3 M, x' {0 t) I& ?: |5 J
sbit s2 = P1^6;; g4 g0 H5 z( b; L4 X
sbit oe = P1^2;
+ i6 x& p# O+ y9 ]4 ?/**************************************************2 I" @& u$ _1 ^4 }9 |0 p+ R
延迟函数,延时1ms
8 A# D* ^3 u* D* @3 v K**************************************************/3 m5 m8 N, j7 V
void delay1ms(uint i)
1 `) g% P- ^; @6 }/ ?4 s4 g{ uint j;0 @, i2 B5 l( V$ o. u
while(i--). g9 l" R! c, k: N0 C( O: q/ @/ N& \
{
+ o8 z- E- x0 w) X for(j=0;j<125;j++);& a* s: |1 p% d# l
}, m, v( W0 f( j: p, D
}
) ~+ d! `( `2 U. ~/**************************************************$ H6 D! u& m9 [- L; X3 }
初始化STC89C52
# E- X R: O$ A- O4 ?7 ~**************************************************/
& i% N! T4 R$ o5 R% N1 E hvoid initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms9 V/ U9 l6 `( l
) x' B t- Z1 j5 n' |& z- M! u TMOD=0x0;, d/ i* H3 H* H' i& U* j8 _# D: \$ n
TH0=0xe0;
/ x* O2 e( E! }0 p4 Y4 o0 F- Y! y) R TL0=0x18;
* g/ V3 x% v- r$ t$ y: C$ n( f8 b}
# s4 j* m, \: V8 {3 I$ g8 vvoid timer0(void) interrupt 1{ //定时器函数 / m( U/ v. L1 w0 G
TH0=0xe0; //装入初值. o# X, `7 Z/ C! n9 { `1 ?
TL0=0x18; //装入初值(定时器中断每1ms中断一次)- s7 B/ }' F) p, z
lck++; //设置累加变量,累加1000次即为1S- V+ }& l- x F& D h8 E" D
if(lck==1000){ //判断是否到了1S
- \" R% \9 n# a& t5 M- s disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数
$ O; a. |3 \2 E5 f lck=0; //对累加变量清零,用于下1S的累加计数1 B. G, R" n2 r3 f
dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数2 N9 N5 F" |7 |1 R& A# F
}
2 U7 m- \& t. }$ G" Q}* h/ N3 w. K( d. y, f+ T
void int0(void) interrupt 0{//外部中断0的处理函数
- }0 R5 N, J: X$ G3 w7 s1 C dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口
$ n8 z# z' B' S, P //每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数
- w+ W( H& m& k; }# q}
/ ~; `) L1 T% r6 \. ^# R/*******RGB三种颜色通道选择模块 1 j6 k+ X4 Y. ^# c! j& |
**************************************************/ 3 i @% d9 n& B; B8 j+ @
void red() 1 K& n/ {# M( H! z. S
{ //红色通道选通函数
2 _0 w: m* b# R4 W. \3 V: m oe = 0; //使能TCS32001 z" i& U6 m0 Z# p7 c. \
s2 = 0; //选通红色滤波器( G, P, p" \3 t: r4 u' k$ t1 N- l
s3 = 0;) V: U3 u" D0 R5 d E* ]0 {
s0 = 0; //设置输出为2%比率
% y" Q& I% M, Y) e5 c" ?+ R; o Y s1 = 1;
( v4 A6 g+ O) w! t0 ^5 {- Q. I delay1ms(1100);//延迟1S7 g0 ]+ T- X% ]3 r* G: J
date=disp/100;//依据方法2,求出比例系数
% x* t4 ^; X, b- L1 ^ date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值9 l* {/ L* ~9 Z5 s; O
}0 d B. [. h$ E; E" V" b2 o
void green() //绿色通道选通函数2 d* K$ D9 D" Z% X! f b b4 v
{
2 ^4 M- z& i; g R6 ~ s0 = 0;
2 ?4 n8 x3 P* F- s0 q4 h s1 = 1; //设置输出2%的比率
5 v; L U# w7 U7 p% ~; V- E; {* ~ oe = 0;# J( C# u; p6 M8 f/ t2 S( H+ i6 b
s2 = 1;: o Z5 l* b9 l9 H& V! l6 v
s3 = 1;
9 a1 ?" j2 d7 q" p) q/ ]( I$ M: m delay1ms(1100);
8 J% w- V2 i# \7 A: j7 m: B date=disp/100;; p( u. t, f9 Q1 Q- T
date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值' c8 U2 L8 X& V0 K9 ]2 ]. `( S
} 3 h7 C. @; s+ j1 v4 s8 H X" y
void blue() //蓝色通道
. |; Z% l+ J! n8 A( ^0 M{ ' J1 [" w. p8 R) l8 }" I+ E" z
//P1=0x81;+ f2 ^. @1 H v
s0 = 0;* k4 |! I; b* k; F
s1 = 1;
% c* [/ G9 i( E; I3 X! a s3 = 1;9 W1 Q% j; o3 O' a) O
s2 = 0;
, B$ r3 y; C% ]* P6 T0 C oe = 0;
& s8 o0 M% S& C9 s delay1ms(1100);
% v; G2 L) M( X+ O date=disp/100;
1 J# t0 y# k! T0 J date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值* X9 C! ^2 D& U4 x
}% h. K. p6 J) n" ~5 [$ W+ F
/**************************************************% J. M9 |0 Y+ b: Y
整型数转化成字符串,以便LCD输出显示
7 d$ n2 y9 g$ {& P9 ? y' w6 @+ ^**************************************************/
0 B- H9 B% u) ]: m/ L) i: [2 ^uchar * int2str(uint d); S7 l2 p1 G9 j+ C* x
{ if(d>=255)
m7 ], h+ e' K8 ] { d=255;
/ {. f' h! j f8 Istr[0]='0'+d/100; b. ? ^) J I5 X3 Z$ ]
str[1]='0'+d%100/10;
! ?! a! {2 s' v' [, [ str[2]='0'+d%10; }
3 v( E# @8 H+ ]: ?' Q1 e' X; Q6 V- H else
2 A. J+ _$ z8 {3 U9 U { str[0]='0'+d/100;4 [& \: S5 j! a% S: G
str[1]='0'+d%100/10;
: v/ S- [9 l* o' y; ~. H( }8 k str[2]='0'+d%10; }5 a! G! n- I8 n
return str;
/ W0 V [* m1 y. a2 T a}
8 ?; o! a8 I0 ~0 t& y( ^8 o: h/*****LCD显示模块*********/' A1 V2 z- T7 \ D0 k# S
\8 \( B* n; p' ]" I
1 Q c: }' H9 O6 evoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
r( n& S. a: C/ G' k{ RW=0; RS=0; E=1;5 h. @$ U2 A- f2 W! ^3 @
P0=com; delay1ms(10);
, g6 T% v& ?8 b* ~6 p E=0; RW=1;
3 s/ a. X7 z6 x. O- S) y' A( M; U0 }4 M}4 h* n$ ?5 Q" X# T; N7 y
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据2 m, ^, q j+ {! p' J$ v* T
{ RW=0; RS=1; E=1;
; n5 p( t- r/ z) F P0=dat; delay1ms(10);) S q l7 o, R' O4 `" i
E=0; RW=1;) g9 Y4 h8 w+ T' f
}
; ~9 ~: T- Q/ B5 X y0 u7 b! |void init_LCD(void) // 初始化lcd; y! s/ ]* a$ v
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效
1 s2 ~- m0 \- X1 u" O LCD_w_com(0x0e); // 显示字符 关闭光标
% p8 x% y6 p# v2 J+ `# W LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1( H: _+ w. {/ ?- j Y3 Y$ a( }
}* K f2 M% Q- Z( ^4 x& ~& @4 D) }
void clear_LCD() //清屏
$ n1 J* @+ v& K/ X/ Q- D{ / `3 S$ W. L& P4 w2 Q
LCD_w_com(0x01); //清屏指令8 e% s; ~2 @9 { r
LCD_w_com(0x02); // 光标归位 即光标置于左上位置
, X' q/ L9 T9 h% A}
1 M( [3 @! G8 L' l; F# z' G; x- V" \void display_LCD_string(uchar *p) //字符串输出函数/ }, ]2 N: [* Z2 {
{ while(*p)
U5 N2 W0 p( x { LCD_w_dat(*p); p++; delay1ms(10); }$ G2 {8 x% d, v
}
0 _4 b) \# G7 \9 B$ `! I! v; vvoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列4 L5 G0 v' O- L5 z% [
{ if(x==1) LCD_w_com(0x80+y);9 i6 B4 h K8 l" e9 a. J. t
else LCD_w_com(0xC0+y);
" M1 [8 J# g9 v! l5 b}: N: N8 K+ O! b! B3 x
- J. e' p, q1 z+ D; v! [
9 l. C, t( |7 v. z' L8 b# C# t
/**************************************************
) P2 W$ `) _/ j9 Z 主函数
* [$ k* R4 b7 z3 B, g8 N( i**************************************************/
9 L2 z' g1 H& u" A1 Mvoid main(void)
! U% d Y4 I2 p' I+ ~{ IT0=1; //INT0下降沿中断! L( i$ T- T9 E1 Y" T5 \/ G
EX0=1; //允许INT0中断
2 {1 O9 \5 y7 N- ]* a* u1 u initTimer(); //装入初值3 x6 c! }% ` s G: A% W* w
TR0=1; //开定时器T0
# U8 \# n4 c ]" n6 o; L. V ET0=1; //允许T0中断
1 f7 z- N% n1 @5 k( ^ |& p EA=1; //中断总控制9 y( q' q% ]6 B7 V- ?- f2 m- c8 ^
init_LCD(); //LCD初始化
; y1 L0 m7 z( d% x! m clear_LCD(); //清屏8 ~) q- K3 m/ a+ a
while(1)
5 |" m! D* ^( Q6 j+ v J {
% ] G5 ?) l7 r gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值
) p7 L7 i) a+ [$ l/ w+ z* n* ]
* e: D$ [" A7 h$ T! p: {% g7 l. k1 ~, U# K% o8 ^- F8 v6 i1 G
i: S% M8 L6 d) c
…………限于本文篇幅 余下代码请从论坛下载附件…………
/ f4 \+ l* t* C! ?
' k' J9 v* A& @/ d! g1 I; i. m) S( m! K6 O- I
|
|