|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机用LCD1602循环右移显示welcome to china仿真源程序
9 d! H6 K8 _$ b* c& o5 d3 Z6 Y0 _0 J# R5 z3 Q. @% f
//用LCD循环右移显示"Welcome to China"# n( Z) \+ u: ?: c
#include<reg51.h> //包含单片机寄存器的头文件
8 ]0 g B' {* V# g8 \& l#include<intrins.h> //包含_nop_()函数定义的头文件, e% g& n) }. S; N" I6 C
sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚
& i, `: a1 c+ i' i% lsbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚
$ M4 o) q, a* u) Q' a+ j( @sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚
) o6 B/ C6 e) |5 D" h- ?/ Fsbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚8 j: t Q* i7 `' s5 M
unsigned char code string[ ]={"Welcome to China"};
8 Y- \2 {% ]( Q" \+ r& q- O& n/*****************************************************
" K; @4 B: r9 d/ N函数功能:延时1ms [ k$ {+ _5 ?# _# d
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒" T) \+ H8 _: i
***************************************************/
% `! a. B$ v- {void delay1ms()
! N0 g1 j4 {- x) x" V E{
^8 [' a0 O. ^ unsigned char i,j;
9 t* t) H0 i. E' ] for(i=0;i<10;i++)
: B. f9 O$ _3 Z+ R0 W for(j=0;j<33;j++)! q/ ~, \- y3 o; ~- I7 i( l
; ) P( t% z8 t3 I" F3 x* G- B+ i
}
3 I' X {) c2 f% b5 y /*****************************************************
# ~/ r; `- k: J9 v1 {* q0 {函数功能:延时若干毫秒
2 A, t* S3 ]; ?4 T9 p' k入口参数:n
/ U& h- f7 V. s$ [9 W3 p. C8 R***************************************************/7 I/ \8 p0 K8 ~+ Y. H% B+ S" H7 c2 F
void delay(unsigned char n)' X. [" j& H; Y# {9 T: P5 w
{
/ s2 Z+ Q1 H0 U, n' V unsigned char i;3 Y- s/ A. C; V B
for(i=0;i<n;i++)
) z* ]9 h7 b3 A- ` delay1ms();
: H2 Q) t6 I9 u0 U( n1 X }
3 J, E2 B. N9 I' E% Y: f& m- W/*****************************************************- L( f% J6 o( ~2 ?
函数功能:判断液晶模块的忙碌状态
8 o3 ]+ A B g/ @返回值:result。result=1,忙碌;result=0,不忙
& ^( V* Z; p- |; ?5 w2 X/ Q***************************************************/
t5 Z- ^3 a7 ` unsigned char BusyTest(void)- {: h7 c& H# |% z: r6 }+ u
{
; M/ L2 d0 ~8 B8 d bit result;
2 o6 g7 N8 l7 q- n6 f RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态9 j* v2 G4 m: a
RW=1;
7 _- @2 t9 b0 q( ~0 d3 O8 { ? E=1; //E=1,才允许读写3 c* P$ ~' ~! }6 i
_nop_(); //空操作
* |% Q: ^* }' V; X$ i _nop_();, v$ y8 P! s! \! r
_nop_(); 3 _1 i0 Q8 `4 P) m% R0 U
_nop_(); //空操作四个机器周期,给硬件反应时间 " ?6 G9 }) ?9 f8 ?. @! ^2 w; W8 k
result=BF; //将忙碌标志电平赋给result
/ B9 U1 h) E+ N E=0;
- U4 _; X+ f% \3 k8 Z( e- q9 s return result;
4 i, p& v; B w0 h }! H* a/ @# Y. f: x/ q
/****************************************************** }; }5 [: M+ p) J8 Y
函数功能:将模式设置指令或显示地址写入液晶模块
Q3 m5 u" N3 W% m入口参数:dictate
1 s$ W' ^9 I6 y9 e8 q***************************************************/6 T2 ]9 W I9 y9 a
void WriteInstruction (unsigned char dictate)% y* ?! ~' O& j8 s$ z
{
. k1 F: y0 e7 R7 c2 F% d while(BusyTest()==1); //如果忙就等待! k, F8 ~& u' y) H7 K# y) ~
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令7 F* b0 E# q" e& m, d, T1 x
RW=0; 3 L0 Q* k; r- z0 b4 F; w
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
$ R" O4 O( c8 t& _9 c) u" O6 ^ // 就是让E从0到1发生正跳变,所以应先置"0"" Y; u3 Y g6 A; D( c9 q3 w: i' `
_nop_();0 D) D# E9 ^5 {( k1 u; }
_nop_(); //空操作两个机器周期,给硬件反应时间; K/ R% S, _* i% \
P0=dictate; //将数据送入P0口,即写入指令或地址
$ P( B% |4 {* Q; Z. T: z _nop_();
4 d. l; D, ?% M0 E' H1 h _nop_();
! H+ e' O1 l) t- l) w _nop_();
1 D2 x9 Q ?4 i0 p" v9 ? _nop_(); //空操作四个机器周期,给硬件反应时间
+ m, }4 k# P4 R+ c E=1; //E置高电平
+ O2 k y6 I, Z+ y1 T: W _nop_();1 j$ ~7 s' q8 P! d, M! H, f) A
_nop_();
7 I: s5 E( K$ M4 @& p _nop_();
5 K# z# F, a. @0 E1 R1 `6 t& P _nop_(); //空操作四个机器周期,给硬件反应时间# i. G" s$ T! ^1 L7 e6 I9 M: C
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
9 c% U4 S' x, N) I }
5 q& ]. X) V7 b: r* g3 I; x5 M/*****************************************************
( z v4 U4 x+ C+ {4 S$ U: Q9 p+ y函数功能:指定字符显示的实际地址: D" J ^! h" c% Y# v( v$ I, L
入口参数:x! y: E3 B ]7 t. w( F+ S
***************************************************/+ k2 @' s: e2 b& e
void WriteAddress(unsigned char x)
2 @8 F: e! O. } {7 r. K/ d) \, I+ o2 T
WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
2 X" q1 p) l7 N; N }5 m& W+ r0 W4 Z9 ]! z L9 N
/*****************************************************
J! S* |# `7 ]; {9 R函数功能:将数据(字符的标准ASCII码)写入液晶模块
# z/ B) U5 L! G3 _7 I) N, L% k+ \入口参数:y(为字符常量)% X" E# h# G4 o, H8 l$ B3 x2 x2 f
***************************************************/
, J7 r( R' y# b- v% V void WriteData(unsigned char y)( O* j6 b6 j# w, o C
{& f# {+ ?' |1 S) a6 d" S
while(BusyTest()==1);
* Z! i4 Y9 r" n RS=1; //RS为高电平,RW为低电平时,可以写入数据" X0 f. b; ?' `2 O: m! ^
RW=0;1 R( Z, v/ W3 W+ `$ K
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,/ P" ^$ L) ^, p$ V( w+ M# r
// 就是让E从0到1发生正跳变,所以应先置"0"
6 D; S. O+ u" c1 R; @+ ]: k P0=y; //将数据送入P0口,即将数据写入液晶模块
^4 T1 C& M' D& O0 c _nop_();& Z% U% q0 r" L6 B' Y; ~
_nop_();
3 ~. \$ L: v/ t! s& x5 @; q _nop_();" \, R4 f0 h! j8 c
_nop_(); //空操作四个机器周期,给硬件反应时间2 P* d B7 u1 k+ V6 h1 {$ h
E=1; //E置高电平
+ {$ ]. r. u% y _nop_();
; ~% s1 n. ~6 y! ? _nop_();
' i; _! L) l2 Q R8 K _nop_();8 r+ \& ~- r0 D: ?: \4 ?
_nop_(); //空操作四个机器周期,给硬件反应时间
% \1 K1 x( S; C E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
3 x6 u$ x, w8 A: k% c; N; T4 N }
$ m. y. e! Q1 a3 {2 ~8 C8 i m7 R/*****************************************************
( S: N3 C$ |2 z' Z函数功能:对LCD的显示模式进行初始化设置% F. Y( G+ p! ^/ q4 L# q
***************************************************/; `% M9 G% f7 q% ~0 O: t6 B
void LcdInitiate(void)
1 o7 y5 b" {! W# c{. e x- _3 b) O- b! Y w
delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间+ @5 ~. i) H. z( Q, e% E: `7 _
WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
% m' n2 z# M' F delay(5); //延时5ms
! t8 B. ^9 t& ` ~" ~ WriteInstruction(0x38);
8 g) t7 V+ P/ d. }$ }8 f delay(5);( [% w9 N2 z5 n
WriteInstruction(0x38);
& ^8 w2 t) G$ F0 d' L delay(5);7 m2 X$ k9 F7 `! U: y4 A* m( u
WriteInstruction(0x0f); //显示模式设置:显示开,有光标,光标闪烁) k4 z6 r8 o) H$ X. v7 e5 W! x) O
delay(5);
7 r8 p1 i8 N9 x( T8 Z WriteInstruction(0x06); //显示模式设置:光标右移,字符不移/ F+ m/ }" b+ L0 W& y, O; v/ `
delay(5);
7 Y# G+ i2 k! Z8 F1 J, E WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除' s- L! `3 H5 h
delay(5);3 V! U/ j O6 k$ b
}
7 K) ]; T, N, O' s) }$ k5 R% ]void main(void) //主函数
1 n& W1 a8 v W0 v" P& h) ~8 ^ {
; L7 i4 C b' H, f$ I unsigned char i;
2 d) }2 [, ~) }& Z5 G- k2 o/ r8 | LcdInitiate(); //调用LCD初始化函数
3 D( O' _4 C5 p delay(10);
$ p% K: L' _ u8 i+ _ U# b( f while(1)# H; m1 k# a; e+ C
{
( m3 q% v8 ]6 ?7 v WriteInstruction(0x01);//清显示:清屏幕指令
& }, o! y# A L WriteAddress(0x00); // 设置显示位置为第一行的第1个字
0 `5 ]5 _8 p8 k! `8 g0 _( X$ [ i = 0;7 |) k# v1 R) c/ a
while(string != '\0')//只要没有写到字符串结束标志,就继续写
4 ^ K( x% A2 r1 _- G$ u9 S { // 显示字符, M1 e8 e6 q$ B% [7 u& d' _" w. d- {
WriteData(string);/ i4 O F! v0 Z! J, v. X
i++;
! k0 v" t+ J5 L R1 @ delay(150);
& J' }# ~- @/ j } % u. }3 J2 D7 p7 \+ ` |7 ]* a
for(i=0;i<4;i++)$ l( B2 B0 y" f+ m/ f/ T
delay(250);
5 j' F+ d$ F3 f% C2 t% j, }7 C) t) e4 t' F0 j
…………限于本文篇幅 余下代码请从论坛下载附件…………
2 `8 J4 R0 }7 w) Z0 \4 F# q* o9 u/ Q w
* P. G8 z' @* p2 O% y4 c% E+ G
, f$ ~: g2 ^7 L- p. d |
|