|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
TCS3200颜色识别-51单片机源码 LCD1602液晶显示
5 {5 B. p& i! l) V- `& T
4 J2 F! q5 c! Q& b( {, q1 X- v y& z5 [) a7 |
此款源码,是用于51单片机颜色识别所用,所用模块还有TCS3200和LCD1602,适合毕业设计(仅限本科)和课余自乐!' r1 C( b/ D7 v8 B, G+ m. h
8 X6 G7 Y0 w6 k1 |1 Q! V' Y
% c/ H0 _8 o% x; h8 |
8 _1 Y" |' K, j0 Q1 N& k
3 y: Q9 f1 i! p7 H" g! z
4 j* N# c6 g) ~4 o- p" y( N单片机源程序:
' {3 g; z. W* U7 S' T4 k I. ^2 [#include <reg52.h> //添加STC89C52所需头文件
, b' L6 v" X. g#include <string.h>2 U5 ]$ a* l; [
#define uchar unsigned char //宏定义无符号字符型变量1 E' d1 N. F5 h! O1 ~6 s1 {' _
#define uint unsigned int //宏定义无符号整型变量
( I0 G: g! h9 W _4 Wuchar str[3]; //定义数组) d( b) I' H: J8 n# _4 `* Z! f
uchar *s; //定义指针
; l' v( M1 u0 t7 p! u5 v1 vuint date; //定义数据类型
K7 n: k: M7 C- _* I% Kuint dispcount=0; //中断计数$ m( h C `! b# r: f
uint lck=0; //定时器计数8 R7 t; r( c* v6 s4 C* U' `; U
uint disp=0; //频率值计数. F+ m/ G) [/ H# D) G
sbit RS=P1^0; //数据/命令选择端,高电平-数据寄存器,低-指令寄存器3 U5 U" u$ q1 w: I
sbit RW=P1^1; //读/写选择端,高-读操作,低-写操作" x' A" P' Z) `" T
sbit E=P2^5; //使能端
# h: b8 [/ d- |; |! i- `7 A8 Msbit s0 = P2^0; //声明引脚
e' p2 a' X, u9 D7 jsbit s1 = P2^1;) Q, Y, M8 ^4 `
sbit s3 = P1^7;
+ M7 A' U9 B) C& F9 qsbit s2 = P1^6;
* N# N2 A1 J9 J6 ~0 T k, Isbit oe = P1^2;
* y. L8 j, [7 f# ~1 y7 A3 T _3 F/**************************************************7 d* r- ^( @. x) R
延迟函数,延时1ms
5 \$ n# N% B/ C2 o% f) X& q**************************************************/
" ]0 W8 n# i2 H" G4 T& }2 t5 e/ w) Qvoid delay1ms(uint i)
4 `! d1 g6 A3 y& k- b{ uint j;4 A3 d. i7 A" H# `
while(i--)
" T9 x8 p P( |' x {
9 @! o1 O" d9 ] for(j=0;j<125;j++);
1 Q# C* |/ ]& A" f2 o% l }
j& ]2 D; I# _& [}
b9 E$ n8 K+ E4 f5 A! A% l- t/**************************************************' _$ x7 L8 Y+ b& _
初始化STC89C52 # {, p% P) N6 V- T }# t; b& t# k
**************************************************/: M" m: w6 F" Q/ d8 k
void initTimer(void){ //定时器0初始化函数,包括装入初值,设置定时时间为1ms" p, \5 l7 v8 w
# s0 S+ |0 k2 q) A }& d TMOD=0x0;! D3 O5 [2 [$ C3 a$ _
TH0=0xe0;+ _7 b4 Y! w! U0 m; K8 b
TL0=0x18;
- o; E8 d! I) \+ V}
$ x* T I% K3 T5 uvoid timer0(void) interrupt 1{ //定时器函数
. H, j2 }% n- c TH0=0xe0; //装入初值
4 E+ Z+ Y4 m* ^ TL0=0x18; //装入初值(定时器中断每1ms中断一次)
. W8 X Y7 S8 Y- A- j% |( h- P lck++; //设置累加变量,累加1000次即为1S1 d3 C0 y, l+ [+ K. U
if(lck==1000){ //判断是否到了1S
2 r6 l" ~/ L. U4 ~/ C2 l disp=dispcount; //将外部中断0内的累加数据(接收TCS3200的脉冲次数)赋值给disp,便于传递参数
/ n( ?3 n/ |5 d9 ?% P# ` lck=0; //对累加变量清零,用于下1S的累加计数
( K" `4 v/ F, S" Y3 W9 \: z( N- r dispcount=0; //对外部中断0的累加数据进行清零,便于下一次对脉冲的计数$ B; J6 ~. }6 o' m7 C I4 |+ \
}
7 z: g) _0 y6 h M: F( n* v}% V1 _, S$ V& N: h* p ?
void int0(void) interrupt 0{//外部中断0的处理函数: k. s/ Y% v+ o$ v9 v3 Z2 [
dispcount++; //外部中断0,TCS3200的OUT端口接到了STC89C52的INT0端口: X$ w: t% C( B7 }4 P
//每一次中断,计数加1,当到达1S时,将此数据放在定时器函数中计数
. K1 u8 W/ @, ^* g2 t}
& E3 t5 e) j+ t5 z, K' p- h/*******RGB三种颜色通道选择模块 ' V7 q2 S m1 G
**************************************************/ 9 P1 t( E( k, Y8 z
void red() 6 e H0 Y* V; F
{ //红色通道选通函数
) n7 j/ R ]0 I, H oe = 0; //使能TCS3200* P+ E% ~9 F: T( a+ j
s2 = 0; //选通红色滤波器
6 I) E! ^, V; d9 e2 o s3 = 0;7 m, U$ f- v3 ^; W) P0 D6 Z
s0 = 0; //设置输出为2%比率
7 }9 {& d& p |0 d. V* e3 h s1 = 1;
" ~+ K# Y. @. u. E) U9 K$ O delay1ms(1100);//延迟1S. G6 R0 V D" \, u6 x3 x& ]( A. L
date=disp/100;//依据方法2,求出比例系数' Z8 L8 r0 P+ N/ w: p
date=(255.0/153)*date;//153是在纯白情况下测得的红色通道频率值
5 {: a4 |- t1 @2 f7 I2 w' P}
4 O7 V* L. @3 @% e9 ]! O' T$ xvoid green() //绿色通道选通函数5 v' d* P8 h0 D, }6 U. D
{ 0 E) g) s& x4 U9 | d
s0 = 0;
* S Q1 P& X) Q6 J, u. | s1 = 1; //设置输出2%的比率# l' k9 ]" v2 n- O
oe = 0; e% v9 ~2 g4 v8 @, i
s2 = 1;) G) E) z. q4 v6 P* |$ G& U& i
s3 = 1;* d' i, F3 e3 p% q' s9 ]
delay1ms(1100);$ m( @. D- \/ m- }3 v! _
date=disp/100;
0 l, U. [6 o) K* h2 D9 X1 o date=(255.0/145)*date;//145是在纯白情况下测得的绿色通道频率值
1 K' Z" F2 @# H# X8 g} 6 \0 F' m# B# L2 i. x4 |$ p1 N1 D
void blue() //蓝色通道
. {' W# B/ a+ Y{ 4 N9 _$ ?: t* B# ^# e T- ?
//P1=0x81;1 Y( P* `2 g! Y# [
s0 = 0;: w$ A2 J2 j8 Z3 e6 j6 [
s1 = 1;
0 k6 v& V; c7 j1 k$ f; i s3 = 1;
5 v; e' J% l$ M+ ` s2 = 0;
5 a- x7 p) t4 k oe = 0;1 I6 a! o3 _ h+ D/ o
delay1ms(1100);
4 z4 m* f) w" b# O8 F date=disp/100;
" m. w; `6 w- Z) E1 A3 \$ s1 c date=(255.0/183)*date; //183是在纯白情况下测得的蓝色通道频率值8 _4 K- G# b1 ?' f# l* {
}; d; c6 _* {& q7 u
/**************************************************
# B+ }) {7 p( A 整型数转化成字符串,以便LCD输出显示
) p h3 n! h9 k4 Q: p**************************************************/
! G v$ y$ I6 u0 P Buchar * int2str(uint d)$ W4 |2 ~4 Z! w2 S5 A7 P
{ if(d>=255)6 N4 u ?2 J: @4 M t# q; a
{ d=255;
9 j" B& [+ @8 A: p' |7 ^str[0]='0'+d/100;8 [) M* \8 ]8 l; i6 }7 R
str[1]='0'+d%100/10;6 ]# ?! C9 D- n5 i. Y& M/ U4 P
str[2]='0'+d%10; }
' r3 Y2 N" t+ U! Z7 K) i else
/ C# @/ j. s, I2 X { str[0]='0'+d/100;
* S% X' `) A+ S' ]4 [ str[1]='0'+d%100/10;" x' j: R5 O V
str[2]='0'+d%10; }
+ P; u. |1 k9 U- } return str;
7 N; o2 @8 {5 [ ~+ ]1 S: ]' P}4 C Q# d8 v4 S* ^5 I
/*****LCD显示模块*********/
0 A- k8 @3 P' ^; l( v
. i- p$ i: [) m4 K- B' e/ E! P; Y- g% e8 V, ~2 B4 y' F; }
void LCD_w_com(unsigned com) //写命令函数,com为 要写的指令; k# U$ @$ \7 L
{ RW=0; RS=0; E=1;, r3 b! a5 T! J2 F! p; Q" F
P0=com; delay1ms(10);$ m% h4 w6 B& U7 X# v5 H
E=0; RW=1;
( F! [! y8 s+ G$ Z2 ^}
. F4 W- X5 D7 \& i* t void LCD_w_dat(uchar dat) // 写数据 函数, 写要显示的数据
" d9 g5 L* C9 S0 R, J6 j{ RW=0; RS=1; E=1;
; K: u8 F$ b7 u% ?* h( k P0=dat; delay1ms(10);
, e+ S$ l" @- e3 {: p2 ] E=0; RW=1;. s9 T5 {/ M) j* w& ^
}2 S+ E$ D; G+ ?. b$ y1 x( ^+ V% K
void init_LCD(void) // 初始化lcd( `) u e5 ~! l* ?2 M+ N! l" I
{ LCD_w_com(0x38); // lcd为两行显示8位数据线有效
/ @7 S& w* x8 H) a LCD_w_com(0x0e); // 显示字符 关闭光标
8 B$ T3 `' I" M( I% E9 r LCD_w_com(0x06); // 输入方式设置 光标向右移动一位 ac-1
1 c4 }# p. M- o}
2 m; `- W: \: W( g; Y, L$ Dvoid clear_LCD() //清屏6 U# a' {9 N" y% w
{ 1 {* |. @$ b1 W7 D' x: U
LCD_w_com(0x01); //清屏指令8 x' h$ I' E5 V% l) m" ^
LCD_w_com(0x02); // 光标归位 即光标置于左上位置# q+ ^' k* ]# V7 o5 q# `
}; p w$ \: l/ B$ {) M# M
void display_LCD_string(uchar *p) //字符串输出函数
# R1 G+ L% y, ~{ while(*p)
, b% X, }$ F1 `9 }1 ^ { LCD_w_dat(*p); p++; delay1ms(10); }' O7 }4 R, \1 B" W
}
( c' S9 H$ j: @* F* j R5 [7 `void gotoxy(unsigned x,unsigned y) //定位 ,x为行,y为列+ t( T3 p: t# P8 c2 d& v+ m, C
{ if(x==1) LCD_w_com(0x80+y);
4 M: z# i8 R: ^ ^% r0 w else LCD_w_com(0xC0+y);5 X" C: j- X! F. [1 \! y0 e* n
}
! I$ I2 s/ r3 O( h5 e- ]0 Z2 g) ^& A; h' z
$ [9 o& M5 Q ?7 h
/**************************************************& p: _) L9 k, _* s, N4 Q( W- {
主函数
6 | E3 g0 g" u l( R**************************************************/. ~0 h) u; _: z9 \
void main(void)1 K- l/ p9 ^; v+ r* N7 f. i% ?* d
{ IT0=1; //INT0下降沿中断3 L2 h0 m3 R c8 V7 p1 R
EX0=1; //允许INT0中断 r. I- u# A" M; E* t( c& P
initTimer(); //装入初值# q* t9 R2 X8 r p
TR0=1; //开定时器T0
, ?/ M3 N7 d6 W# ~ ET0=1; //允许T0中断
) E8 F8 U* U+ }. i EA=1; //中断总控制- A0 O. w9 d2 S. T: d
init_LCD(); //LCD初始化9 S0 A$ Y! l* s; i$ G6 v
clear_LCD(); //清屏. N/ a7 @7 t {
while(1)5 P& M" Q& W" l6 o/ \
{ $ f* g6 w4 r, H0 K) }: N
gotoxy(1,00); display_LCD_string("R:"); red(); //调用红色通道并显示色彩值2 a6 p2 k5 f9 I" E+ v
; L# i" p9 ?7 \: {1 L0 ]& _! {1 O: Q' I% N
# H' G2 z( P9 m, W$ g
…………限于本文篇幅 余下代码请从论坛下载附件…………
2 }8 x1 a+ ?1 K1 B( L, o) x3 x. A& J$ {( u& M5 V! S
/ ^4 b9 {. Y/ x3 Q3 ]! E |
|