|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示
6 O( S r" v! s1 \- s( J$ X) @; T2 W
6 ]& H- p/ f! q/ ^% P此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!
. v( x( I3 d9 j
7 Z' W) S8 R; T* m6 V- ?6 ^: I3 q$ y3 V! g7 s* L: ?1 C
. l5 f0 A0 Z- F/ O' e
7 B, m1 T, r) z8 V: v0 ~
" r9 E9 A3 d1 x, @, e# k单片机源程序:
) H! {- c* t9 O+ w q' d5 r#include <reg52.h> //添加STC89C52所需头文件
; }8 X, G# F: Z0 t#include <string.h>
# @. U# r, r+ J: [. A#define uchar unsigned char //宏定义无符号字符型变量( H4 \! G) B; ^8 D9 S4 V
#define uint unsigned int //宏定义无符号整型变量
/ o2 Y' J5 }, V. suchar str[3]; //定义数组. _2 G- ~) P" W5 F1 G
uchar *s; //定义指针
) q* f+ M+ \4 j/ O$ B. Guint date; //定义数据类型
! j* ^4 P1 ?& yuint dispcount=0; //中断计数
+ c/ Q7 p9 e- H! Zuint lck=0; //定时器计数4 d! [0 W- g+ e# u F- ?3 K# c
uint disp=0; //频率值计数: J, u' |- X+ J! b
sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器3 c3 ^% r: B1 \( i
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作
, R) b: z: b; f2 W; Dsbit E=P2^5; //使能端
$ o: L* @9 g0 J- l! p% M( Y$ Q# Ysbit s0 = P2^0; //声明引脚
4 f) d, i/ \4 @9 `1 j; i& e- Tsbit s1 = P2^1;
% D- m4 A( q! @6 h, f- h4 Qsbit s3 = P1^7;
, T. G' }/ J; P8 K0 a4 Nsbit s2 = P1^6;
3 p& m% I5 i: Ysbit oe = P1^2;% x5 S0 _$ d. A- \; D
/**************************************************
* H1 k9 q# u# {6 I 延迟函数,延时1ms
: }) I% C# a2 h; n4 w% f4 L( v1 @**************************************************/
& @" W: O" ~) C4 x( t$ B- Bvoid delay1ms(uint i) ) Q" v$ K% u. H/ t Q% Z9 ]2 H
{ uint j;
$ y, U0 o$ V4 e7 E; O while(i--)
6 T7 `* r$ c. @. e+ g* T {
9 ]) d; ]! y' ]2 Z# O for(j=0;j<125;j++);
% D7 o& d- Q/ M# {; A! }! o }' Y% ?" t' q. m; Q4 ^" j; O) ~
}% A( e7 D Q) r( D( a% l u
/**************************************************& i1 ?; |/ o; h
初始化STC89C52
8 f# |" t( {; F% F% B ~; {. \% t**************************************************/9 A; i+ C! s2 z5 u
void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms) O1 n6 [& |1 E/ [ D6 K% Q
* i% G' Q+ U* d4 @! i3 r4 J
TMOD=0x0;9 Q& n6 |7 [4 _' Z5 b# P
TH0=0xe0;
. S0 Q, w: T! g. L- r TL0=0x18;" i% ]" ]6 {, e1 }3 c7 C; [' S
}
% k( x6 l, `% J/ F. svoid timer0(void) interrupt 1{ //定时器函数
7 K" D+ L# `7 K( W5 z& I TH0=0xe0; //装入初值, a+ z% m0 C. ?, d" \
TL0=0x18; //装入初值(定时器中断每1ms中断一次), y; H$ ?( O) L/ B
lck++; //设置累加变量,累加1000次即为1S( X q3 x5 p( m k
if(lck==1000){ //判断是否到了1S6 q. g6 f" d# A- i
disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数
# i" Q# p$ F. J [' F" A; C$ ~ lck=0; //对累加变量清零,用于下1S的累加计数8 k; A& j3 w! k
dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数
1 ?" i1 ~1 T4 e6 \6 ?: c" g+ E }
% k8 x5 y7 m( F/ g, U}
5 R, R9 O6 ?4 P, V9 k% J! gvoid int0(void) interrupt 0{//外部中断0的处理函数% O, Q! {3 T0 M0 `, ~( z/ A, g
dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口
0 ?+ _, T! ]" s' B8 s3 I, J$ y //每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数1 g# u4 l6 q' Y2 W9 \$ {7 W3 j0 Y
}
5 w: Z+ O, T/ T9 E0 ~8 x/*******RGB三种颜色通道选择模块
; g1 l2 P, U/ _# j**************************************************/ 6 T$ ]0 |) F: R2 A7 F/ I6 i/ s+ X
void red()
4 c1 O8 E# n' I9 l) _1 J{ //红色通道选通函数
1 \2 S6 H4 }6 C+ } ` r H( _% T/ J7 E oe = 0; //使能TCS3200
& Y4 k; L1 u5 P4 y/ O/ E s2 = 0; //选通红色滤波器
/ ~: \5 b) B9 Z s3 = 0;5 [* v7 H. ^) E5 _
s0 = 0; //设置输出为2%比率
: E; L0 h- C% ~0 v2 h" x s1 = 1;, H z! W, R, M& t) @' W8 t
delay1ms(1100);//延迟1S
X- a/ Z9 U; S date=disp/100;//依据方法2,求出比例系数
, f7 m3 h- q B( u$ @0 [6 _& a date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值+ d! K) T6 I" B6 c0 S" C$ X* _
}% Y8 O: q& Z0 t- K- W
void green() //绿色通道选通函数
$ B- v9 B+ H$ k2 t( ^{
1 b# |4 n. \) s" P$ H# F0 r s0 = 0;
8 e4 s2 Y8 _3 T; d s1 = 1; //设置输出2%的比率" `$ S) E/ N% d/ O8 D
oe = 0;0 C$ B7 J9 n2 U
s2 = 1;
, A+ J6 e1 P( b# Q$ Q K1 P s3 = 1;2 v& g. W4 O, h; Z! E" i( |
delay1ms(1100);/ d/ \1 E& l) m
date=disp/100;
1 r+ \; c, w! l1 z$ Z date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值: z8 _; m- ]0 Y% N0 u+ ?; E
}
- h- |+ r3 E* K: L& E8 hvoid blue() //蓝色通道' W0 \- }$ g* I u
{ 7 L8 ]1 D3 [$ G3 W7 a
//P1=0x81;" P$ X- _# C) z! M; |: q
s0 = 0;
) a ^3 l# Q+ E1 O% v s1 = 1;; ~- b% G' M; b# @# [2 \. r
s3 = 1;
6 a+ a7 g7 D; A- {8 ]3 A$ Q% S s2 = 0;4 s# b( F) `9 q A& u. l0 o
oe = 0;
; K6 n" A- z; v$ b delay1ms(1100);
3 |: Y, i- K" R8 E5 c. O$ X date=disp/100;
f, w! X6 u* C! b9 G _ date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值
/ k; V, Z* L+ E( Y$ b( O! }1 d \' J}1 j) R: j; W" V, ^" L
/**************************************************1 z5 _/ t, e! e; g" r' W
整型数转化成字符串,以便LCD输出显示 ; B: v5 l# q) a3 j* E
**************************************************/
) c8 y D2 m2 v/ j* J+ Nuchar * int2str(uint d)& U& W' w, u! u" J
{ if(d>=255)
, n A6 d0 W9 `" P; h6 ^- O5 F5 ` { d=255;
3 P) Q! o3 {2 _5 k6 O/ s1 Nstr[0]='0'+d/100;+ H& b2 ^6 w4 t" v. o1 m. U x. l
str[1]='0'+d%100/10;# a# p+ i( d* @8 Q, y" F
str[2]='0'+d%10; }
1 {' n1 Z8 p- A1 b else
y! z2 Z9 V" C9 _2 M { str[0]='0'+d/100;; H; K* b' i# Q9 E6 \
str[1]='0'+d%100/10;+ a- ^' X' U* G; Z) J; \
str[2]='0'+d%10; }
/ I; I9 K* x$ x1 Q' Z4 W return str;- d9 ]- u, |9 u0 f; C. ^
}
$ w: ]7 J# v/ A; E2 [/*****LCD显示模块*********/9 M1 o- ]# {& @7 y6 ?0 K% ]$ J7 E
# H6 o2 E) I- h
1 I1 r% {0 k0 w6 F
void LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
M* K d, H5 V* `{ RW=0; RS=0; E=1;% g& Z: Z" H: X- i! l3 F% T
P0=com; delay1ms(10);
$ ^% P% }* m+ K1 R$ R E=0; RW=1;
# i: j( m, w2 X% {: Y}9 m/ y7 n) j# }. U
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据7 c6 E3 Z% ]- n6 D& ?1 @# r
{ RW=0; RS=1; E=1; x2 D) E# P6 } Z
P0=dat; delay1ms(10);
9 ]; F% G9 x( @8 R E=0; RW=1;, s0 x* n& {: i( T9 V
}0 E4 W3 @' F; |! e
void init_LCD(void) // 初始化lcd2 v+ X2 N7 o% i2 E/ i- t
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效( u+ `" N7 l, B+ O
LCD_w_com(0x0e); // 显示字符 关闭光标
e( s+ d% {0 e LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1
% e' ^& ]% v4 j, u1 k9 }7 V2 c' k% e}! ~" m: y& v; G8 R5 k* F
void clear_LCD() //清屏7 |; T2 f! G6 {2 i) I2 i
{ * q/ Y+ a, ^- Y5 o% |
LCD_w_com(0x01); //清屏指令1 Y: R5 e! {5 O0 i! o- n
LCD_w_com(0x02); // 光标归位 即光标置于左上位置
" t& m7 V' N# W: @- S}# z: I- F9 _! o# D, \4 b. M- V, s
void display_LCD_string(uchar *p) //字符串输出函数
' g8 N2 O. i( w' G8 n% g% D{ while(*p)
7 m& i6 R& r# J: K, ] { LCD_w_dat(*p); p++; delay1ms(10); }
* L( t0 s4 ]! q3 B+ ]}
* |2 |$ @. x* n% x$ Jvoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列
9 \7 u/ i; x% t$ S! q{ if(x==1) LCD_w_com(0x80+y);
5 P+ Y- L4 \+ M+ v: c+ `* P7 Y+ N else LCD_w_com(0xC0+y);
1 t! j8 ^9 a, H( o}
, c1 z6 I) P6 X4 _) V3 V5 ] P) r# D1 A; }( Z
2 _9 Y8 ?3 c4 u% R( E8 D/**************************************************. J$ m# P: K4 ^' m# _# y
主函数
4 Y, O; p: j2 u! y0 o**************************************************/
! H9 h. _/ @0 H% pvoid main(void)/ B2 K* W7 Z' n' q8 S
{ IT0=1; //INT0下降沿中断
8 M' M( t- N, ~ EX0=1; //允许INT0中断
* W5 L ~9 F2 m; m/ c initTimer(); //装入初值( |0 @( p ]+ o0 i2 a" ~) _6 A
TR0=1; //开定时器T0! ]2 y- V' i# X
ET0=1; //允许T0中断
5 V- a K+ B2 ?; T+ ` EA=1; //中断总控制+ @& |0 }2 b# U" ]2 p
init_LCD(); //LCD初始化
8 M# @8 x- U/ V, Q clear_LCD(); //清屏) p; z7 Q4 n7 L1 x" S7 y
while(1)
1 q* f, f. h; D' I' M2 {: o { 0 l; s/ |; x% W- ~
gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值. o6 N! \) A# P+ _8 _* k) c% H
_# U: Q+ w4 L1 h
8 h0 `6 T* {( r, m0 y0 P* [ p6 B4 _4 x) Q, {0 T! K. X
…………限于本文篇幅 余下代码请从论坛下载附件…………) }1 F- B# l7 G: k5 E( H( l
! G/ p) N. [; S
7 W3 a1 r& m1 C. I1 Z/ k |
|