|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示1 a1 t6 t; G- c+ L$ \ D
# b3 s Z3 Q) P& }0 v8 ? t C% \8 O: {, ^4 \7 N# l
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!
# z& {, q8 a$ R, ^% y3 p& w; u
, r( A7 z" m, `+ Y( r) y) z' I, V. {. c) {4 W3 u
1 m9 C0 P% ^! @; ?
! Y# P* a: k0 a1 N
& I% Y! s3 U7 D3 H单片机源程序:
5 V4 J# ^+ k1 r#include <reg52.h> //添加STC89C52所需头文件
7 P; e# ~+ y4 R#include <string.h>. E5 W# d! }% d
#define uchar unsigned char //宏定义无符号字符型变量1 b3 M5 Z+ d/ F
#define uint unsigned int //宏定义无符号整型变量1 a) H9 k% e3 [
uchar str[3]; //定义数组
) Q) O( t" [ f1 f Guchar *s; //定义指针7 R3 a1 z2 B7 C. r( v4 Z R7 z
uint date; //定义数据类型; r; _. ^2 Q$ M/ B8 t* ^8 k1 i+ n
uint dispcount=0; //中断计数
, x# G, l/ @1 i; puint lck=0; //定时器计数1 h5 a+ R6 {/ h& k' I, H
uint disp=0; //频率值计数( m! ~+ n# u9 O! m( Q/ ?& \
sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器
, r, e$ u' C ~/ f/ `: x% P5 Zsbit RW=P1^1; //读/写选择端,高-读操作,低-写操作
8 y7 E p4 Z+ z( D9 Esbit E=P2^5; //使能端6 ~( k" G9 q, k/ U
sbit s0 = P2^0; //声明引脚
6 m' p6 y$ V/ ?- D/ _' Hsbit s1 = P2^1;. {0 P( K& l" }: @) o
sbit s3 = P1^7;
- ^3 j8 u* \% l5 b7 K2 b2 C6 [sbit s2 = P1^6;6 m: Q/ q. O! P( t- i
sbit oe = P1^2;
! o9 z/ u$ |- v* k( g6 [/**************************************************1 X# }6 E- }5 P
延迟函数,延时1ms 1 S1 L: z2 l3 L3 `. o' d1 m
**************************************************/" j6 V2 P7 L: t% z7 ^3 u
void delay1ms(uint i)
, A" |9 s$ _5 I. X( {# _{ uint j;! C. L8 {/ {! w9 p1 E- Z
while(i--). a/ M7 E. X- Z/ t2 Q. J
{
# S+ Q; l* C# I6 e- F1 @7 F% n for(j=0;j<125;j++); r7 ~ m7 N( i& Y
}
" j1 g, C. n5 C5 p- |) _* {6 e}
: p* f5 d; V7 ^: ?/ y, V7 P/**************************************************
6 n0 u1 ]4 L0 E: k: P2 d 初始化STC89C52 9 a' J' z, |% |: } s
**************************************************/* l3 U, ?3 C0 ~1 Y( J& f [0 W; ~
void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms% v. r6 u" S* X7 b( |) ^
7 Y9 ]0 J* s) G TMOD=0x0;2 F+ ]+ X* G! D" @- D- V# s
TH0=0xe0;
% k4 k) V0 F8 ]: f' m9 a6 p TL0=0x18;
0 X# W* Z# D- u( l1 j}
. m" [) F" x! S, n/ svoid timer0(void) interrupt 1{ //定时器函数
9 D) v3 g9 F# P. d2 ~ TH0=0xe0; //装入初值
1 b P% d* t+ j4 ~* r TL0=0x18; //装入初值(定时器中断每1ms中断一次)
9 ]+ Y" s) e7 S. N& { lck++; //设置累加变量,累加1000次即为1S' |2 a+ T" o/ F) `
if(lck==1000){ //判断是否到了1S/ t g! t; u {- c3 b. ]2 o t. c
disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数/ X2 A2 \% C- O* `# H
lck=0; //对累加变量清零,用于下1S的累加计数
8 |* J- Z1 \- y3 x4 { dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数
6 j+ G1 K* ~9 B7 U5 h }
4 w& r1 Z5 m; f3 q; n- c}
* ^1 ~' b2 E1 Lvoid int0(void) interrupt 0{//外部中断0的处理函数
! |% ?8 z! a7 N' [ dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口3 \" W7 s$ w; x9 V; s% \- o
//每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数7 y3 _2 u5 B9 _+ Y) D4 h+ r
}
3 k) o/ t" V3 O/*******RGB三种颜色通道选择模块
% z9 d& o; Q) |**************************************************/
+ S! v! [) q; o1 k. Rvoid red()
5 L0 j. v z6 R' _- ?{ //红色通道选通函数
" @# d2 w; _8 _6 g) [ oe = 0; //使能TCS3200
. U. d ]3 n$ H M s2 = 0; //选通红色滤波器
8 y, n5 E$ ]3 I. ]$ s s3 = 0;, ] v) T3 s$ n, Q& W; a8 k
s0 = 0; //设置输出为2%比率/ l$ Z! N. y1 ?
s1 = 1;
9 L+ h. Y, l3 U& v delay1ms(1100);//延迟1S
0 b/ W/ D+ C+ l* S, ? date=disp/100;//依据方法2,求出比例系数
+ I8 l& P) {! e9 [7 ]# w% M8 x date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值
1 e4 `, S6 J5 P5 ]% d, d: Q" e" l}
+ {2 Y# t2 S8 Z8 V$ r( O; A8 Jvoid green() //绿色通道选通函数- \7 E# K! _# `# S/ J
{
& S& o5 z& M1 I: |. D* K9 q s0 = 0;' h- I8 R1 W0 W( H" E. v, ]' J
s1 = 1; //设置输出2%的比率
7 {! Q! _) Z) K/ M( D" F oe = 0;5 t" e p3 L: k3 {
s2 = 1;$ m9 m5 b- J% Z9 p8 x
s3 = 1;; j; u- R+ x! N; v/ U
delay1ms(1100);
3 e; V @6 d1 @( P8 _$ ?1 O6 Q date=disp/100;
5 z a& p0 t) O8 X: H date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值
3 h5 u" Q, C. P9 R, V3 _1 I} - O& S# w! v$ V7 j8 S: t
void blue() //蓝色通道: @$ ]" G, ~$ X6 t
{ ' C* z# e) d# c' u
//P1=0x81;" a5 d0 J9 D& A, c* W
s0 = 0;$ ^/ b% Z& c2 W7 z m+ n( P
s1 = 1;& O) }+ ?5 p+ _- w$ O
s3 = 1;( i* {- ~4 M" P6 z) v
s2 = 0;
. d7 a9 s t: t; H9 P4 A oe = 0;
9 H/ ^% l/ w# N* h5 V U delay1ms(1100);
+ z9 H" |8 v3 T. C+ A! c. } date=disp/100;0 L% W; \& _! E. ?% a: x
date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值3 i- Z; E( i# Y9 q
}
7 X- |( R$ F* x2 {4 G1 V2 Z" W3 q# a' J/**************************************************
5 |+ j, x: k9 q9 _( H1 s 整型数转化成字符串,以便LCD输出显示 + Z9 p; Z, J, _% A( f' Z% U, z
**************************************************/
& f7 [0 J8 x0 n0 s) J. auchar * int2str(uint d)4 F% F0 w$ N, [2 q0 J( A, O
{ if(d>=255)
0 \- t8 _; D9 l3 b' a R( D" s& n" ] { d=255;2 C' X" J/ i% s0 U. E' V+ y" E) ~
str[0]='0'+d/100;
1 l; G3 E7 w1 p$ \1 {str[1]='0'+d%100/10;) S) V9 Q- y: J" [
str[2]='0'+d%10; }
" y$ @: h! m, ?7 _: j. W$ O) F else
6 s/ m$ a$ w$ g# g { str[0]='0'+d/100;/ L3 l0 d4 h% [6 S% q% G0 p
str[1]='0'+d%100/10;* F! L3 O" l4 F5 I
str[2]='0'+d%10; }9 w3 i+ V4 [6 [9 E' |7 h
return str;7 p& ]3 a" l6 c) y# E5 y
}
9 C& [2 J- W8 I/ N- H/*****LCD显示模块*********/5 P" j- |& b, F( U
; n* P6 f. F3 X, _+ G, {5 V8 i) `
+ O4 ~8 G/ w' w) u$ F" F$ V1 Nvoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令
2 |/ \9 p% i+ n5 Q{ RW=0; RS=0; E=1;/ z) t N( D: i. i: b, C+ z U
P0=com; delay1ms(10);
- e: U9 U" ~' x% R; y9 F" ~6 y E=0; RW=1;4 R' S+ @& t2 ?$ W/ L
}6 W. I4 ?$ w: Z
void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据7 |! r" u3 n1 e8 M' X/ z; _
{ RW=0; RS=1; E=1;
6 {/ m' J! b6 u P0=dat; delay1ms(10);# b1 z& w& L. n1 z( X$ F$ K
E=0; RW=1;! h9 r8 P0 q8 S5 N5 u; g- ?
}
6 ~3 e1 u$ ~: D+ d: svoid init_LCD(void) // 初始化lcd
4 B t9 K- V7 N0 s{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效
8 |9 L7 w( {. }: O" r- P LCD_w_com(0x0e); // 显示字符 关闭光标
3 D6 P, u' W- ?0 W LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-12 f/ ^4 N% k+ r3 B& o
}
. J6 O8 \$ \+ ~void clear_LCD() //清屏2 g! ^, v0 x& c6 X7 D5 p
{
$ G, W ?3 L/ c( G% D" K4 N LCD_w_com(0x01); //清屏指令% {' W/ Z8 ?5 E
LCD_w_com(0x02); // 光标归位 即光标置于左上位置
8 E+ u, C" m4 u9 {& B1 W}( k1 l( k4 N1 R0 B" k
void display_LCD_string(uchar *p) //字符串输出函数
$ o2 i- u* x, q0 |1 m{ while(*p)
! Y* ~2 H" b5 h( w { LCD_w_dat(*p); p++; delay1ms(10); }
5 s9 ?: s' }6 x" b}) Y' B Q+ o: w4 }
void gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列
/ M$ K# x% r/ P{ if(x==1) LCD_w_com(0x80+y);
6 W2 @# B" P- m% p6 U& ?3 j else LCD_w_com(0xC0+y);2 G$ \3 Y, U* w3 w: ]' h: d+ {
}
( |, H. K3 ?" ~% L* L6 ~( m% q
+ H8 |" @$ |5 ^ [) p0 V/**************************************************! L% P* c) _2 {& ^ F) {% a( C4 D
主函数
# E; D, o( H0 m, {. x9 M**************************************************/. s1 D$ j+ `! r3 `. ]
void main(void)0 K( v( k/ B) @/ W+ w6 j$ l3 `
{ IT0=1; //INT0下降沿中断- q% y# V0 v) G) y. O& V# u0 a* u
EX0=1; //允许INT0中断 {. }6 J. c& b: y0 M( z
initTimer(); //装入初值4 ~ H2 R8 \7 q
TR0=1; //开定时器T0* `$ A7 c% Y& z' _% Y/ `" m
ET0=1; //允许T0中断# e; Z* V% q, X% B
EA=1; //中断总控制, F; Q" l5 X+ g
init_LCD(); //LCD初始化
# V- V% ]: Q3 |) l' T5 W3 c clear_LCD(); //清屏
# ^. z" w8 W7 [" J/ A while(1)) }. d- w/ f. m/ J8 D) k
{
7 ?/ _5 Z/ m7 @) I* x+ x gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值/ Y: \+ C% l- ] o0 n) {
2 j% J5 L& J0 i' L3 ~' ~- ?/ j1 t4 n
6 L# ^0 i! w9 I
7 D2 n, [, M a5 s |4 x
…………限于本文篇幅 余下代码请从论坛下载附件…………1 I7 R: o/ f6 A- C+ j7 N4 q7 Q
1 u. b( o: w/ U' j. F/ O# u! q/ B# l2 P
|
|