|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示, h3 }6 n! A' K
( d& F9 `% R* b% q
k) I3 ?7 O0 K) X0 ?1 y7 A3 m. ?
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!' M5 |4 c2 }9 d* g* ^+ R
- R X5 n& B! C
5 _, w2 o! _6 B% E
) L8 ]3 N8 ?0 O' ? c- P9 z# f" s l9 l8 o
8 v0 j& ^4 ^4 Q6 s" P) x" G. C4 [# y& Q H( o0 J" C# n8 I& H2 T
单片机源程序:3 \; k0 z/ t3 f2 E
#include <reg52.h> //添加STC89C52所需头文件
. X5 \& \( z: r#include <string.h>* e+ _) F7 x/ [% h/ J7 ]4 s
#define uchar unsigned char //宏定义无符号字符型变量
7 x- [. F0 G/ U9 w0 \$ H" u+ d#define uint unsigned int //宏定义无符号整型变量
?+ [8 ]4 p S# Y |" Juchar str[3]; //定义数组) B. i. z2 J8 c# Z
uchar *s; //定义指针
+ E* y/ j# W6 e! e: u" T+ }uint date; //定义数据类型* ~" Y; j0 z- r Y
uint dispcount=0; //中断计数
/ u9 k3 W' w' u, ruint lck=0; //定时器计数9 ^) Q3 |% a4 q0 h
uint disp=0; //频率值计数
& U3 y( Y' j h' u2 Z2 `sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器, N' n3 ]* i3 x3 E9 ~3 M
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作
7 _3 C4 I( h7 W' wsbit E=P2^5; //使能端
4 W$ ~6 Y, @; i, v! p' C. hsbit s0 = P2^0; //声明引脚- z/ z; r: G6 I( H% g& M; j' W
sbit s1 = P2^1;
! [8 ?2 ^9 R2 B7 {4 ~( r- l, ~sbit s3 = P1^7;, y7 g& e; z3 N
sbit s2 = P1^6; I% Z4 Z6 G- m$ c. x0 x
sbit oe = P1^2; d" ]( H; {+ @. A _4 K
/**************************************************
2 y% x5 Y( {/ L& @ 延迟函数,延时1ms & \0 D6 @* Z7 p
**************************************************/
: Y V$ M& B/ nvoid delay1ms(uint i)
" i1 I8 v% F4 D2 F{ uint j;5 ^( U5 R' w2 ?: A: h" F
while(i--)
( Q0 c% f( y# h4 u' g8 g; J3 J { ( E/ y' z9 r! _$ b0 t! p
for(j=0;j<125;j++);
' m/ A j+ _& @ A% K }4 C& z- H7 X$ ~# X# J% S5 _
}
- y+ H; Q( v: d9 \& \- E! @/**************************************************7 v# b- n5 W0 H u: n. Q) k4 b
初始化STC89C52 ) P: c7 U G: A* `- s
**************************************************/
A, C- T; R$ Y4 \4 k3 cvoid initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms- S5 b4 F d( B, f
v6 |* H/ ? @; V; F6 O1 c6 S7 j TMOD=0x0;) n4 [, J2 q, l) g% t9 c( m
TH0=0xe0;- J. M" v: g9 ?
TL0=0x18;
2 `- m1 x) L4 W+ ~% o' x" N V}! {, I" ~6 g# `( W9 k) f
void timer0(void) interrupt 1{ //定时器函数 4 f8 n5 m2 j* z! ?7 Y# | v
TH0=0xe0; //装入初值- U& D, p R: |" u: w$ {( q) v
TL0=0x18; //装入初值(定时器中断每1ms中断一次)* \; P% D2 I4 a8 n" u# P, ^
lck++; //设置累加变量,累加1000次即为1S8 E6 [) _" C; y4 ~- q' w: n8 X: \
if(lck==1000){ //判断是否到了1S
3 ?, ?7 {' _/ A& ] disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数" f: K% p6 x1 m& Y Z
lck=0; //对累加变量清零,用于下1S的累加计数/ ?: K. f5 P; M* ?
dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数
6 H5 P. b8 E# k6 v7 a }4 @+ k; m; n2 I4 \9 H, f
}
/ c9 h; [# U$ X# wvoid int0(void) interrupt 0{//外部中断0的处理函数; }5 [* @0 P) M- d( |0 B! F6 \/ Y5 a
dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口
$ u3 _8 g# t4 J. F //每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数
0 i* [$ b5 H( u5 H1 N- O5 ~3 z}
! w; \& M% L* E$ x. d/*******RGB三种颜色通道选择模块 4 S, J; e7 K7 J
**************************************************/
1 s$ y* ]5 d' @void red()
0 U5 N e, Z) C/ i{ //红色通道选通函数: d5 g; X1 Q: R+ n8 S; g. S7 @% g
oe = 0; //使能TCS3200* a1 [6 d, F1 d. V6 ^0 M2 b
s2 = 0; //选通红色滤波器2 ?/ ^+ K& [ W" |, A% K
s3 = 0;$ h# T1 g0 t/ |
s0 = 0; //设置输出为2%比率
$ X5 |8 O, x) J n$ w s1 = 1;7 X+ S3 k3 r1 R& O
delay1ms(1100);//延迟1S
% N+ N/ F8 P( u9 t date=disp/100;//依据方法2,求出比例系数( f7 c3 o8 d0 ?! ~% {& Y
date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值" }* C3 e) _1 ~
}6 u! Q: }8 y' D- p9 I
void green() //绿色通道选通函数% y. R5 ~+ x% e( z/ B1 ]- \
{ 8 D+ U, \* _* [) @
s0 = 0;: {4 Z/ w% p H2 ]& J( t) j) @
s1 = 1; //设置输出2%的比率
! q+ z, \3 A( \8 k3 W6 d6 t oe = 0;
/ B# H. Q" Y* P* V; b( r1 I s2 = 1;0 X& s2 L( P6 I
s3 = 1;
0 N; M+ k. _9 _8 w2 v- { delay1ms(1100);! G. `6 i9 I" P4 y8 }) w' c+ r
date=disp/100;/ j4 c% s+ ^/ u. f O
date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值: Y' k# Z9 C. W! ?2 Z2 d) o
}
]* y/ x$ m! E7 _, xvoid blue() //蓝色通道
- e0 r7 {5 Z( c1 T{
) \* J/ _) A1 M) ^4 G, i0 P //P1=0x81;2 ]8 W, V( _7 h: j4 q0 n+ B
s0 = 0;3 b2 p9 C0 c' S& X& G
s1 = 1;
/ K3 d+ w8 K i3 A s3 = 1;
+ p3 R2 ?! s& H9 u# a s2 = 0;9 o- h/ v; Q1 {) v
oe = 0;
2 C; ?7 E7 N6 ?3 Q6 t8 l" M( } delay1ms(1100);# c Q; v! @7 ?1 ]4 l* U
date=disp/100;! a: J# n9 Y& {) P- n, ]
date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值
3 N% Q* T. }5 |}
' _! h5 v: I$ @4 e6 t5 ]/**************************************************5 E# g# s+ J5 _$ _
整型数转化成字符串,以便LCD输出显示
2 t& O5 q3 q) l& i9 \0 c**************************************************/
6 P- m; X, e1 T' X9 N8 c8 w# ouchar * int2str(uint d)
( i! m9 c6 U. I# m4 d{ if(d>=255)
! `5 @, m1 k- u4 X$ K! R; ^ { d=255;* E, ~/ O5 P% S3 ], f/ ~
str[0]='0'+d/100;
" B @* E# [; m+ E' ustr[1]='0'+d%100/10;
+ a2 O6 d2 ~" m; q( k! m8 l, z7 L' G; N str[2]='0'+d%10; }7 D7 D' [2 i' I9 T: t
else
, Q1 v" T& d+ s9 b# K9 [ { str[0]='0'+d/100;
; f& H: V8 J b& \ str[1]='0'+d%100/10;
2 T6 x# W, s3 @4 j1 a9 `$ S6 Y9 v" `' @ str[2]='0'+d%10; }+ [+ f& u9 c6 Q( q
return str;( r" I( C8 H3 O; }+ T+ s# ^
}
: J8 C5 J A- f% c/*****LCD显示模块*********/# W) g/ S9 J( X: i+ m4 Y
, f, ^* Z5 k: V6 M( {
& S: r7 A: T4 e$ vvoid LCD_w_com(unsigned com) //写命令函数,com为 要写的指令0 C) @, o0 Y8 D6 Q; f4 K1 Y
{ RW=0; RS=0; E=1;* q1 U% {1 d0 R7 [' q7 S
P0=com; delay1ms(10);/ x8 A+ T4 c5 N: N
E=0; RW=1;. _4 g. \* q0 z0 L3 S0 I3 S
}
9 s5 u% { m; o. \4 Z. Z void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据, T9 B) M1 R% J) _* s0 b
{ RW=0; RS=1; E=1;' D' @; {& z$ u# r# t/ Y( Q5 G1 x
P0=dat; delay1ms(10);2 a% }0 a" Y. z
E=0; RW=1;
) i# G! H' s/ R! @9 @3 V8 D}
B0 z; ~# R6 a5 a ]void init_LCD(void) // 初始化lcd
, B& B$ l; w7 N3 k) F* T- y( I{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效* H1 t2 h% o7 C! ^8 C+ B
LCD_w_com(0x0e); // 显示字符 关闭光标
% H6 G8 d5 ?& `: U: Z& Z LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1
$ m" T: k( o1 z}# q1 O% l& h5 J' D0 E- ^9 \: t& e; ]
void clear_LCD() //清屏
9 m; t6 A9 x% z$ Z( L( O; O9 [{ ( l6 W: W. d1 w* W7 x4 u
LCD_w_com(0x01); //清屏指令
, H( l+ P x5 |- u- O/ ] LCD_w_com(0x02); // 光标归位 即光标置于左上位置9 D1 i& n9 I) ?% u
}9 ]* C* s* D& @% I
void display_LCD_string(uchar *p) //字符串输出函数; G& \" M* n8 g: \
{ while(*p)' t4 X* I% P5 Z8 ]' D9 t. @
{ LCD_w_dat(*p); p++; delay1ms(10); }) ]! {6 u, R' W$ ^- H
}
/ Q% n+ P6 A% Z) F7 A" G: x2 Y) jvoid gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列
t0 l5 W7 X. J' x+ {% x( I{ if(x==1) LCD_w_com(0x80+y);+ j0 o6 w0 b4 b B- z) p, |7 x
else LCD_w_com(0xC0+y);6 Y0 e- Z( Y9 p! v7 e0 p2 V2 S
}
& h0 j% ]9 g1 M& }# s3 \/ B' O% ]+ b) G8 q
5 X6 {6 D: v8 q( |, |% y
/**************************************************6 r3 L. }# S, j7 K
主函数
4 g8 U& U$ L5 N! O% [**************************************************/
/ L7 }/ m3 R% D+ n. _void main(void)
+ v, h' n% W) M1 Q' u{ IT0=1; //INT0下降沿中断
; [. N! d: p: @# I y( s+ ^" D EX0=1; //允许INT0中断
8 ^, W, ?, i% O4 z$ |2 }: w5 E9 k8 g% T initTimer(); //装入初值
* M+ _' }& C6 P' O2 A n' U# }2 e+ X3 N TR0=1; //开定时器T0
1 ^7 K ]+ C. P" P/ B- @% | ET0=1; //允许T0中断 v, K/ C4 ?: ^: m; P
EA=1; //中断总控制
! T7 m; t/ E' o init_LCD(); //LCD初始化0 _" O4 s# ~" Q: x) U# ]( v
clear_LCD(); //清屏
! Y/ U g2 n1 U5 b, M# @% q+ [8 C while(1)
; i/ l1 w4 ~, _1 s7 E) r$ Z {
& l2 a' k7 m) r& L7 O gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值' I3 H9 w# c V0 V: t& A' l- c" X
0 }1 e1 N% z0 D: o& \/ r* |$ w' V9 S0 }- i
: j! T& U1 K- j& N3 _" I( O…………限于本文篇幅 余下代码请从论坛下载附件…………5 O, i. k9 x2 ?
4 ~5 I9 O+ w% } X! i6 K: {6 Y ?% J+ M' W; D. u4 Q
|
|