|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示6 S' l7 g0 q% {4 ]; g% E3 \
: |7 M, _& d e; _. h8 v- @
1 V/ X+ f; n3 @& \6 g" _此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!4 P, n7 W) U* W1 q- R
7 Z _9 G( I: f9 p; C3 [
7 U+ Y$ R5 Q6 q3 Q% V 1 T+ |2 L j3 d& i7 s' h: k
7 d3 Q5 O E/ k2 R' T T7 M' Y8 Q9 q
单片机源程序:
E' ^7 J2 o1 n# G! D* ^#include <reg52.h> //添加STC89C52所需头文件
. ]1 L Y) M9 ? S#include <string.h>' ~% Q: b: z4 A' Y E
#define uchar unsigned char //宏定义无符号字符型变量
! O' x1 x: k% B+ }#define uint unsigned int //宏定义无符号整型变量
+ \! K# x7 \: ?9 t7 x- g- E# duchar str[3]; //定义数组1 w) h2 \ E( ?- J j" Z4 x* P4 V
uchar *s; //定义指针$ m3 c8 R. K C5 v1 [7 b* D0 w
uint date; //定义数据类型5 u6 ^/ j. x- [0 N5 y! x
uint dispcount=0; //中断计数. e; x+ N' L& X4 U& B
uint lck=0; //定时器计数' N5 i b6 {& }- K8 a
uint disp=0; //频率值计数
# M0 {) ^% J. s% ~; Msbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器
; J# Y6 ^# c, l4 w% K/ M, Asbit RW=P1^1; //读/写选择端,高-读操作,低-写操作0 |; K' G& V6 [, `! r3 w8 ^+ R
sbit E=P2^5; //使能端
: o+ C7 {2 V- d3 }- E6 T8 l! Vsbit s0 = P2^0; //声明引脚. C3 C8 Y4 [( r8 b
sbit s1 = P2^1;* K1 U$ ^+ b" N+ u4 j% Z! P C2 T
sbit s3 = P1^7;" N" ^: Z* ^# p% U+ g I
sbit s2 = P1^6; W& k6 T. t0 `3 P+ H, f4 E" ?
sbit oe = P1^2;
, A& k4 M* I" Q6 u+ {" u/**************************************************: M4 |7 {2 }1 [) @' g5 V. s# O6 w
延迟函数,延时1ms
: {+ ^8 P$ \5 }! V. F6 B) H& U**************************************************/
8 [) O) V4 m* y- I0 P! Z- T: M1 e2 _void delay1ms(uint i) 6 I0 y" H4 c! z8 p! e3 n, ]
{ uint j;% _1 x% N( R. M! T H; @9 K
while(i--)/ D, A4 E4 q! y/ X6 O W
{ ) S# c1 W0 ~8 w" d1 y* I- C
for(j=0;j<125;j++);3 Z' c0 s1 q5 P# Q) r6 P) D
}
; M' `5 K4 T0 G/ o P& _9 m}
6 s7 N; ~ y3 Q$ ]" h/**************************************************
" l" |7 w" J; |6 j 初始化STC89C52
. t$ f4 M" o( d**************************************************/3 ?' C2 f- p. g) n9 M2 R
void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms( `' A0 }; Q k. i+ V- |; s
) d6 ?1 S c1 k- N TMOD=0x0;5 A6 R1 k$ w8 ^ v' G c% u
TH0=0xe0;" R# `- r3 U" J' b/ J9 p
TL0=0x18;! @5 I0 X7 q% g4 s' A
}, P% T$ B& `+ U4 w+ o: e
void timer0(void) interrupt 1{ //定时器函数
3 v3 {9 U: B9 e1 a' F TH0=0xe0; //装入初值
; B' G6 x/ d* B9 g TL0=0x18; //装入初值(定时器中断每1ms中断一次)
6 u! t, V: u8 e: u4 k: C9 G" K lck++; //设置累加变量,累加1000次即为1S
5 |8 M- a$ I/ s0 o8 [3 k. h3 t& k if(lck==1000){ //判断是否到了1S
9 i9 K5 Z! d: N# C! G/ N$ B disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数
% a8 p* N( z4 t& H. ]& Z lck=0; //对累加变量清零,用于下1S的累加计数
) Y+ c2 N3 k& p. S: X dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数
5 u5 J, l$ Y/ [" B4 n9 x! Q5 @( A }
\# x* T% I/ |. R. L. h}/ V3 r7 R4 a; H3 X1 u. D: \
void int0(void) interrupt 0{//外部中断0的处理函数. @* s& Y" z- h" f; E0 Y
dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口
~5 y2 S4 Z0 c" q+ P2 x. L8 ~) S2 u7 G //每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数* a; A" T+ ?* F9 [4 \. b4 U) R
}
! a' i8 S; ~! @) p( ^7 E/*******RGB三种颜色通道选择模块
0 Z: t6 |+ L! y3 l. X, \) z. k**************************************************/
2 N# e y9 b1 h9 ?void red()
9 |4 p8 C* g6 m" q8 c. R{ //红色通道选通函数
8 Z: [/ N" o$ v2 U$ p oe = 0; //使能TCS32008 G9 ]) Q( Q$ F1 v$ [9 ~* t
s2 = 0; //选通红色滤波器
' p W- c& q( c! s) ~+ C s3 = 0;3 a4 {& i4 s5 [ D! T- d6 b
s0 = 0; //设置输出为2%比率
2 ~3 d4 o+ Y, X9 u- }6 H0 k s1 = 1;$ l5 [! B* a& x; t% }& p& e9 y$ m: J9 x
delay1ms(1100);//延迟1S
B' e$ e. X6 T3 X& u date=disp/100;//依据方法2,求出比例系数 l* A2 h- f: F- z8 J
date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值1 t& }- v; G( {. u k% N9 }
}
) c0 h! C' N7 [, b9 G' E4 kvoid green() //绿色通道选通函数" F+ `3 G7 B, m& E: [2 c% M P
{
, Z4 g* S% O: k/ x! u8 \8 | s0 = 0;
/ A. N7 Q1 j1 S) h s1 = 1; //设置输出2%的比率
/ E- r5 b J, I* d' U- I oe = 0;
8 p8 c3 j" E2 R s2 = 1;0 R1 \- n- c6 ], i6 U
s3 = 1;5 N! {2 P" |% _" q) P7 O
delay1ms(1100);
3 p5 y% W) d |( N date=disp/100; c; `( T; O4 d. E& ^) i, a$ Z
date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值
; C* X, }+ J6 M" F3 x}
) q& j7 l5 s! g/ }. h' |8 d- Evoid blue() //蓝色通道$ ^, |2 ]& m% v* |6 g
{
/ N2 L0 N* r3 S. D //P1=0x81;3 i$ B" p$ }, m0 `+ V
s0 = 0;) ~; ~" g+ p! o5 p3 m* [# K
s1 = 1;
1 u, x9 p/ ~! d' y8 s s3 = 1;
7 s6 \, w$ W; o7 h s2 = 0;# k* x- }0 N$ O- A: m
oe = 0;, l3 A$ W& h3 R5 `( E+ N3 f
delay1ms(1100);
; Y1 F" h( c1 O$ X8 ~* _ date=disp/100;
6 q: h3 ]( N7 G2 ~' b: \ date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值
- s; g9 ]$ F V} g$ s! k5 Q" @, s2 k1 D
/**************************************************
/ C; X* T# O* F- U 整型数转化成字符串,以便LCD输出显示 8 v5 e, U9 m: E b% g
**************************************************/0 v* G2 Z7 F7 a% h& I3 `
uchar * int2str(uint d)
+ h3 I$ f0 O9 k( d5 f{ if(d>=255)% x5 a1 ]# \3 X1 j, ?
{ d=255;5 W3 `& P# l- v
str[0]='0'+d/100;7 w3 M9 H! { z6 F. i. G" I Z- N
str[1]='0'+d%100/10;6 S' _! [) S# @ }7 N! W$ E9 |
str[2]='0'+d%10; }( A0 \# b4 E/ k3 ?: S @+ J8 T4 Q% Z
else9 s! K, B1 q* s& k
{ str[0]='0'+d/100;3 Q- x Y) P9 ^; U7 L* Q
str[1]='0'+d%100/10;
# I! f& x8 o$ o; @$ m- V str[2]='0'+d%10; }
5 |: I2 ~8 W5 Y return str;' j- S5 J: b5 {; W |6 u
}
$ |* a* b B' N; u k q4 i9 _/*****LCD显示模块*********// c9 H- p" Z2 T. y% o. F$ z
' O" F4 A; @- l5 R3 x5 p
: @1 X0 u q+ W6 Ovoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
0 [2 d1 T4 b( E( m& p{ RW=0; RS=0; E=1;0 I1 K4 I1 a0 w* X
P0=com; delay1ms(10);
) |- z4 {3 Q/ ^ E=0; RW=1;
3 v+ w1 L. _' O$ J. I5 C}; ~9 a+ }; g6 y; [* w0 I5 }7 E
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据' `* g1 w; o h7 ~: \
{ RW=0; RS=1; E=1;
4 W( G; g- Y( q+ x; D( ~) D# I3 h P0=dat; delay1ms(10);
+ ^- f) c: h* z E=0; RW=1;
5 c- Q0 w, j5 j* ~+ O7 ]# S}& {* j% L3 f& ~
void init_LCD(void) // 初始化lcd: W- r) e' ~9 w3 l
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效( t6 n6 f; y) J' t: r; u! z
LCD_w_com(0x0e); // 显示字符 关闭光标# a, n/ h& f" T
LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1
: Q/ ?: a# o& {& v# L}0 P4 V( t6 L# J3 i3 S9 l& V3 H
void clear_LCD() //清屏" h5 {! e- c9 g$ a+ N
{ 2 l& |' X0 }, d( K: N" o9 \
LCD_w_com(0x01); //清屏指令
/ g) C1 R* s6 c LCD_w_com(0x02); // 光标归位 即光标置于左上位置% L) h4 }( X$ f, U0 M$ C3 {
}: R# S: S H6 M9 K0 H6 J
void display_LCD_string(uchar *p) //字符串输出函数. r& K1 X. i3 [
{ while(*p)
W- t+ \) O1 ~ { LCD_w_dat(*p); p++; delay1ms(10); }
2 ]8 s5 w* o$ D) h6 g. T}
8 \6 d$ ]( h9 B/ h( P8 g# xvoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列1 c8 w% `8 O7 k" Q2 S
{ if(x==1) LCD_w_com(0x80+y);4 E( \: o& a! S" v8 E1 I
else LCD_w_com(0xC0+y);
3 H4 A8 e! v5 j/ A$ A+ ]/ `0 F}
3 w4 |0 M3 K* j' Z- x4 T2 X; J
( |) F% P Q; Y9 E8 k3 }4 j- \) V* L5 C
/**************************************************
) E" ^# c9 p( e2 y% {8 B 主函数 4 |% {" Q6 h1 c" X
**************************************************/4 g0 y; V9 v7 `0 y8 f
void main(void)
8 R+ [1 W0 V7 t1 X% j{ IT0=1; //INT0下降沿中断
6 J+ g9 I! o8 w5 j EX0=1; //允许INT0中断
. f- j' D) L$ t* w; J( A initTimer(); //装入初值' G) | ~% ]+ q) N+ D8 H
TR0=1; //开定时器T0
b i" H; ^% z+ S2 z- l5 p ET0=1; //允许T0中断
( q$ L, R, {7 S2 a1 t EA=1; //中断总控制( D4 M5 h/ o }$ O1 M2 c
init_LCD(); //LCD初始化* ~7 z$ L! i$ E4 V8 d$ k
clear_LCD(); //清屏
6 m7 X% I8 G, W$ x$ r' m while(1), ]# ?+ }" R& v' h8 [
{ ' `1 T D9 o. T9 z1 A9 p( x( x" a: x
gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值
0 b% T# k7 g* z# f" q + E/ B& j. k& P
2 M. ~) {' ~: D" G- x0 c- C
( }8 } \/ V- I) Z8 C…………限于本文篇幅 余下代码请从论坛下载附件…………! a S* U, y( k' V1 s
/ z9 @& J0 Y* f* `4 F
d; S& ^8 j( H5 {/ t, h( Z2 ^ |
|