|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示8 g/ X. U' ~: A8 ?) V, @! }
8 Y/ h- y9 h. y% X
: {& o) S4 \: x A0 d# d
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!0 i$ m" ?9 I5 Y
5 L- I0 m1 Q+ N5 f$ T- b1 a) I" V4 T+ u2 Y. ]! j. @2 l
, L1 _; x% {! [6 X( ?% K& l
2 e% z: J7 P; l4 K$ A9 f) G6 T. X
! `' D; `6 {: V; G" d* X单片机源程序:/ J/ r5 b9 N3 X3 x. O
#include <reg52.h> //添加STC89C52所需头文件* [" e0 H4 q3 H8 a: W3 h7 F
#include <string.h>
( k! Q" e* q% s7 t% f#define uchar unsigned char //宏定义无符号字符型变量8 h, o+ O3 k( _: T: V0 n5 J
#define uint unsigned int //宏定义无符号整型变量( G# f' N7 w8 n9 @( _6 R9 N' }
uchar str[3]; //定义数组$ g$ j$ e- c' `" F7 p
uchar *s; //定义指针
+ \" ]4 C% ]) ^, Muint date; //定义数据类型: _7 A5 _: t, g& |( A
uint dispcount=0; //中断计数4 N7 N7 e B; S( z
uint lck=0; //定时器计数
" H, v& E. p) Z2 Y( f2 N$ m! `uint disp=0; //频率值计数
8 v" V4 ]) x# P |sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器! b ? Q/ \6 ~) P% N
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作( ?( t7 P; X! Y& u' S
sbit E=P2^5; //使能端1 d+ I9 k3 i7 u" w2 T- ?1 w( \* L0 _
sbit s0 = P2^0; //声明引脚
$ @( k3 m: `8 _' K' v; o9 p0 z( Wsbit s1 = P2^1;; L6 k- D0 _6 c! e, S
sbit s3 = P1^7;
* k7 v" y* Y7 {1 d/ R- h# qsbit s2 = P1^6;
/ S( n$ s; |- j0 `1 x8 M' msbit oe = P1^2;4 b' q: v, t; T; }$ G& S
/**************************************************
, f+ d' v y3 c0 V9 A, S5 \ 延迟函数,延时1ms - h( k h; a" {0 q5 U9 S8 j
**************************************************/
3 n' \% B* _. r! d+ w( Y; Xvoid delay1ms(uint i) , K# q. U3 y3 z" B* H7 K
{ uint j;3 V/ T+ {# N( P, I, a. D% g
while(i--)
9 M2 F1 U4 {- b. q2 d2 ]1 k5 V {
) Q7 |8 l8 ]1 n) _8 C: W+ j for(j=0;j<125;j++);- \5 T1 U$ \% v- g: \& W6 N
}
( @- \; E& V) u}) Q$ P1 z5 g3 [% e) \7 n
/**************************************************
1 f. V) e: j1 Z, m 初始化STC89C52
8 ~* p, I8 O3 i+ C, M% O5 p9 N" v**************************************************/
# w! T3 L$ O; f# N; y, Evoid initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms! r$ ^9 ^2 q4 W4 R0 J% Q# l
, T6 [, K; C7 a& r; [
TMOD=0x0;
( F# _; ^" ]# z0 i! {& L TH0=0xe0;: r6 V# ?/ H. C' [ D4 A2 W& Q8 J4 F5 l& [
TL0=0x18;0 I2 u- H* k" ~$ K6 u/ `" m
}: P Z! b# D3 {2 m# K7 g, L
void timer0(void) interrupt 1{ //定时器函数
. K. P* }: O$ H7 q3 C- l TH0=0xe0; //装入初值' s8 a8 H o8 l0 a# _ D9 J, a
TL0=0x18; //装入初值(定时器中断每1ms中断一次)
! R+ w- O8 Z% d lck++; //设置累加变量,累加1000次即为1S
1 `3 A2 e$ E0 ^ if(lck==1000){ //判断是否到了1S1 H6 ~( e/ A$ J3 z0 W+ ]
disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数; H- V: h, |; Z3 B( U0 N
lck=0; //对累加变量清零,用于下1S的累加计数5 U8 C- L3 z" z
dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数8 w7 q6 ~: R% O7 `- O
}" W3 b$ P2 I k% H r p
}
+ F: b# ?( K3 j8 O* ?0 Nvoid int0(void) interrupt 0{//外部中断0的处理函数
. U& b- K* \/ x! z5 [# { dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口3 [4 S, c; c+ A. x5 E7 |4 G
//每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数& `" v+ s( H) k7 ?
}
9 r+ B# C, T" D) J, g( h) Z8 A/*******RGB三种颜色通道选择模块
* `% u( i1 E6 p5 U% D! v**************************************************/
+ X3 o/ m* @- C5 n+ f/ M/ w( L& mvoid red()
8 l0 [3 w( N- f! Y6 {' x{ //红色通道选通函数
: s4 z' h, c4 A, k0 j% n" j( X oe = 0; //使能TCS32002 B: ?( }9 D {# i/ O7 F+ J
s2 = 0; //选通红色滤波器
: e3 K% v0 B5 v s3 = 0;5 o2 ]8 Q5 F9 \) d. n& y* J
s0 = 0; //设置输出为2%比率
+ N' e! q7 G# T: `+ N) h s1 = 1;
6 t; X# l8 C9 P' P% P delay1ms(1100);//延迟1S
% m" R0 S- ~* c1 K* C date=disp/100;//依据方法2,求出比例系数
/ W x |5 O+ P& B. K$ H date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值
: W$ n, n7 y0 z/ r# g}
# Q/ e5 ] M. J5 z5 bvoid green() //绿色通道选通函数
& j$ d! B p6 ?{
, l$ m! s" ]4 K2 ^ s0 = 0;: k6 k' A: E4 U& v
s1 = 1; //设置输出2%的比率& U7 _0 k- ^8 _% _: O& l
oe = 0;
9 T% z: r; `3 E: N5 t$ l s2 = 1;, Q% u% V8 ]' w( L
s3 = 1;
2 y% K6 i: q( I delay1ms(1100);, }+ o7 F3 n& E- e) Q0 l
date=disp/100;8 x9 X% X' x1 C6 V! Q
date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值( H" R+ `. X. S4 ]: D* t; d
}
# k: h4 m) x1 q. w0 Bvoid blue() //蓝色通道
7 C5 \$ E& X$ x: I! C{ 6 o# J; p$ \9 M( c8 |* J% B3 \
//P1=0x81;
8 t! }$ T% R) y p% x8 G s0 = 0;
+ W: C$ m" \! j- v$ H: x8 q s1 = 1;$ d. F/ U. t/ T' G
s3 = 1;' D t4 ]* g' R3 h; p D' X8 ?+ {
s2 = 0;- M5 c' {0 k+ V5 C' b0 O
oe = 0;
9 j! }3 `0 s& A4 p# Q delay1ms(1100);
1 \5 R+ l* f. H* }, C, U' v8 K date=disp/100;$ Q3 \( [. _& N
date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值
, a( @. @! j, c' n}
" ~) `. f1 f% r+ Z8 L8 p/**************************************************
+ r' J5 a; W* I' {, m3 m 整型数转化成字符串,以便LCD输出显示
/ n7 D' Q3 ]" F**************************************************/
! C5 U; C6 h1 O. w6 L) duchar * int2str(uint d)) I: ~, A! [: D5 _; O
{ if(d>=255)1 V! F9 T- O! @
{ d=255;
5 Q; }" W( i, jstr[0]='0'+d/100;
3 C ]" R0 @" Y$ xstr[1]='0'+d%100/10;
+ |5 u& ]+ R9 O+ B7 o) z0 X$ x* t str[2]='0'+d%10; }7 R! e; k, w6 K+ g2 J3 Y7 r
else
* o" @6 ?5 _/ S- e% x, ^. _ { str[0]='0'+d/100;6 K. I8 N: f, ^& W. ]- `+ _
str[1]='0'+d%100/10;8 a8 i: E- u( w. o1 Y% R
str[2]='0'+d%10; }
2 Q" d7 S$ N9 q% Y1 `) O return str;
# w7 ?! B$ |# s3 Y7 v3 z1 I}
. R2 H: y& D- o8 \' |1 k X- g8 r/*****LCD显示模块*********// N- }' D, e* l! Y# P
* {9 m3 @$ _/ V0 p
* E8 K2 V' n" Dvoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
" \" m; g8 q5 }# g{ RW=0; RS=0; E=1;0 @; ~' w( C1 t
P0=com; delay1ms(10);
. J0 k6 r. ^( x E=0; RW=1;$ O1 o3 m2 ?8 l3 L# Q
}7 a5 a: d6 P j# T( w2 V; F( d
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据
1 Z8 U. D; w0 J2 K& Z2 f# E{ RW=0; RS=1; E=1;9 }2 V4 v V! h8 S/ n2 P, T. y
P0=dat; delay1ms(10);
1 Z9 ~: \' w3 z& u E=0; RW=1;5 a% U: `" U n" K0 }
}5 C5 S7 h0 L3 w& m, u8 d4 h
void init_LCD(void) // 初始化lcd) U5 F, J7 B! a* W2 K2 F
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效
) G3 X' b* ?. N' y) E, S$ d1 U LCD_w_com(0x0e); // 显示字符 关闭光标
% Y9 E& G( W- V L$ p LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1/ Q* J5 M" Y, b) V1 v) j& n
}
# ]2 T/ H) n+ Q0 rvoid clear_LCD() //清屏' J* A3 k5 @. Z# T, T, f
{
9 G5 e: R8 G2 O, o# m! i, d LCD_w_com(0x01); //清屏指令
' H$ V! e/ ~, `! }0 t/ g8 D# z! } LCD_w_com(0x02); // 光标归位 即光标置于左上位置5 U6 W+ p% _5 L. Q H
}
c2 x% B1 C4 s8 Y4 @' ~% W& Zvoid display_LCD_string(uchar *p) //字符串输出函数
; A5 Y6 B3 k6 m! r* q2 l, X{ while(*p), n4 S# a1 z; C1 k' [; m1 {3 q9 P
{ LCD_w_dat(*p); p++; delay1ms(10); }: a+ M3 T6 `( b% F# n0 ]9 {0 ?
}
( x: B4 M* Y) j+ I: ?- P1 kvoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列8 V; {$ k) ~! A. c
{ if(x==1) LCD_w_com(0x80+y);
( t5 D* Y2 @: d- D else LCD_w_com(0xC0+y);
* b, C3 X" D/ u2 u}
; m5 g6 S6 A& o+ |* Y7 a5 E1 Z, \8 N2 Z4 `: Z9 N
V& [+ N% c- @. {' d5 B/ v
/**************************************************
* E5 _4 v" ?: {) ~: l 主函数
9 R y0 B! q C% D3 T**************************************************/
) P5 U" b: U' \" Avoid main(void)3 B7 A5 _5 H8 B
{ IT0=1; //INT0下降沿中断
: X4 k# n0 ?* F EX0=1; //允许INT0中断+ Q6 c- F& S t% F6 o
initTimer(); //装入初值* Z2 N3 h7 g9 u! [/ v4 K# ?3 S
TR0=1; //开定时器T0
: M! _1 u/ J/ y6 U: v5 O4 H ET0=1; //允许T0中断, j8 C. z# t( U& c
EA=1; //中断总控制
8 Y) B! y- k( [# v- G. O init_LCD(); //LCD初始化; Q3 w1 ]. b' W" g7 F! U9 o% |
clear_LCD(); //清屏
: m; r4 Z" t, ^. w6 G while(1)% p1 l+ E5 A! X* I4 A
{
! H' h9 e* g: |6 \$ b- {! z; Q gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值
$ c- g; e. d# X7 U& O 2 _& z- A4 R- p4 `; [9 K
- j9 d% Q3 m! y4 b
- @- h: v4 N2 |8 h5 E; M( _…………限于本文篇幅 余下代码请从论坛下载附件…………
4 }' [- ]3 g( \/ y
$ O. Q$ y2 s9 A& D$ h' V+ k& ^% J$ H) `
|
|