|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机用LCD1602循环右移显示welcome to china仿真源程序
$ l {- k1 s" Y; G& d w R
: u4 {) O% F, z; l4 H' O! D; s" W0 a//用LCD循环右移显示"Welcome to China"$ S* I( G9 p& }( t* Z# ~3 c6 o9 C
#include<reg51.h> //包含单片机寄存器的头文件% \6 r4 O* c; Q
#include<intrins.h> //包含_nop_()函数定义的头文件/ |; ~& N/ D" m4 A* r
sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚+ g; A2 c, h+ P! B( l {3 i
sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚
3 ^! r& L. a* k/ [! bsbit E=P2^2; //使能信号位,将E位定义为P2.2引脚! J4 {4 J' M6 q9 _: `# A7 G" ]% Y
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚
5 \2 v1 P' s7 s: @6 E4 q, aunsigned char code string[ ]={"Welcome to China"}; 9 b* B# u3 ~/ M. G: e1 t, r
/*****************************************************: i: g4 h6 Z* Q! }
函数功能:延时1ms* Q, U) Y: C `+ X
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒# N' j3 W9 _5 T2 B3 g' `
***************************************************/
5 V% T& c4 A0 w1 Lvoid delay1ms()
# }( c$ `! f% L; ]3 k- {2 W{7 g9 m3 A9 ]5 A$ P5 O+ ^+ L0 r( Y" J7 v
unsigned char i,j; : |9 q3 D3 u: y
for(i=0;i<10;i++)2 {/ O4 \8 ?# @( L$ |2 `4 g
for(j=0;j<33;j++)
: |- K( a: N8 _3 r; l( S ; 2 h R& t" H5 k: X! [( x0 |
}
" F6 S" P7 e: k3 C( i/ ^# a /*****************************************************
7 l: e, Z/ B' `* H$ ?函数功能:延时若干毫秒. h: |, f* m! T
入口参数:n
! d! I8 j( i. G# n! s- c7 e- W***************************************************/6 u; G7 {+ F3 I" G+ R e- b, R
void delay(unsigned char n)
( k' d. d) q% V% U {
3 K3 |. O. c) R. U% v2 A" c3 k' H% E unsigned char i;
, g5 G: k6 K# N for(i=0;i<n;i++)
* a* b6 Z) L) `$ ~) j1 P- l delay1ms();
5 C( I( `7 D& X" H, ? }
, k4 }+ T$ M4 n' o1 a/*****************************************************( N* `0 L# h9 V( |: N+ U
函数功能:判断液晶模块的忙碌状态! q" N4 R* |, E; x. O+ i
返回值:result。result=1,忙碌;result=0,不忙
1 E& T# e5 n# m***************************************************/
) B/ D! S; ]3 y! F- l; ^ unsigned char BusyTest(void)
# J, v9 S5 g$ T4 R/ P& U2 t {
& l7 B, x1 z8 B0 Y$ E bit result;" U( `) L, t! l/ J. f; l. A
RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态% [, f6 ^' m& t9 F8 _5 ]3 Y R6 T
RW=1;
4 P4 t( ~& O; \* v' |5 x; ?9 S E=1; //E=1,才允许读写: d, Z' H _% p0 z/ W3 q$ ]
_nop_(); //空操作 M8 h; e- u. M/ X) R+ A9 v
_nop_();
: x- n% ^7 t* H7 L! a- V: T _nop_();
6 ?% m# l4 E; t" r% l9 I( v; N _nop_(); //空操作四个机器周期,给硬件反应时间
; \8 l0 t d( g/ O result=BF; //将忙碌标志电平赋给result
: x9 {/ k6 o$ V) y) F2 z E=0;
& r2 ^5 ~) L! M# y& H$ H! A9 w return result;# B& E0 M; V2 s! a
}
, S u/ }& I+ L9 Q4 Y$ z# U! L/*****************************************************, V9 |8 f& o5 \5 x0 _
函数功能:将模式设置指令或显示地址写入液晶模块
8 S4 t1 V4 _6 G+ A, u入口参数:dictate0 e9 u, o% v. \
***************************************************/1 z7 Y6 E/ l9 i( [! X. F7 o( X
void WriteInstruction (unsigned char dictate)) m @4 M. z& j4 M7 Q# o
{ , Z* k' g3 @3 ]2 G/ }
while(BusyTest()==1); //如果忙就等待
5 z: M ?8 {, h- e, A8 L# g$ Y1 X RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令) a! _0 z" Z& a' F2 U
RW=0;
7 u: `) h e1 i" Y% z E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
5 P1 |+ {- O- \( s2 ^' E // 就是让E从0到1发生正跳变,所以应先置"0"
2 S5 s2 M: R/ q) g _nop_();
# q0 z8 L0 F: ^9 T4 { _nop_(); //空操作两个机器周期,给硬件反应时间
% b$ ?0 k# r7 X* m# B$ U) I1 [ @ P0=dictate; //将数据送入P0口,即写入指令或地址
3 [( U! [8 h4 m6 l5 | _nop_();/ T4 Z" B8 j1 R" G" z
_nop_();4 h+ `' ]' s7 C [/ t! ^5 k
_nop_();
% X4 {4 Z1 X B _nop_(); //空操作四个机器周期,给硬件反应时间, H8 p! h6 w; w. K' n, @$ d& H1 q
E=1; //E置高电平
* W, w3 @9 G- }( _4 | _nop_();
- @2 a7 v: a5 {8 t: E _nop_();
1 b! E9 D0 B8 X3 p9 |' J _nop_();0 p. h; F. }) }. p* B
_nop_(); //空操作四个机器周期,给硬件反应时间
+ r Z. t) s5 Z" d4 {2 c E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令7 w$ X4 g( C3 ^2 `8 @+ @. g
}
( g6 j/ @5 r, f3 B/*****************************************************
" j! U5 q7 p& \& U* _函数功能:指定字符显示的实际地址' c2 ], R) ^7 e8 g0 ^* z2 n
入口参数:x
% @0 k5 W5 o* J) e0 N$ t- P***************************************************/8 ^! B/ i) L5 z$ G
void WriteAddress(unsigned char x)
8 l2 r4 k' o4 K! b; Z {
% H" r4 D5 t4 }- }! Q WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"# {% g, p; Z+ O5 z+ U3 h
}$ F: C r u8 \ u! a
/*****************************************************6 ?$ v0 \- c2 K* f! s" O% L
函数功能:将数据(字符的标准ASCII码)写入液晶模块1 k" W* l+ U8 d2 K9 |4 @1 c
入口参数:y(为字符常量)
1 A4 c; H/ ~; v***************************************************/9 O# v0 W! e) _# D8 \' |+ e8 U
void WriteData(unsigned char y)
1 a+ z o, |& L! c4 X- A6 S) U {
2 p' ?3 r. o4 H) u4 n while(BusyTest()==1);
0 D) b" X- V; |+ C/ V J) d8 H RS=1; //RS为高电平,RW为低电平时,可以写入数据& \$ i7 K3 A9 n! e" S* { W
RW=0;
' x* a+ O1 d! U7 [/ X) [( m E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
3 I C$ _( C# d // 就是让E从0到1发生正跳变,所以应先置"0") y6 ^, O; y. ?4 }$ r: G" `
P0=y; //将数据送入P0口,即将数据写入液晶模块# u q6 A' @7 k. y5 O
_nop_();
' g' I% [ N( l7 m _nop_();. V8 B$ a+ D# u; p
_nop_(); w _1 I, F4 I* |( U$ f
_nop_(); //空操作四个机器周期,给硬件反应时间
0 C9 x5 k8 h9 x' j E=1; //E置高电平
4 ~3 e) ~: [7 P" m$ f i _nop_();/ c5 _- t2 ]- Z$ w0 t% h
_nop_();
3 t; H0 \, j5 z7 j0 X3 n S _nop_();
7 L4 i& v$ }8 I% l4 I8 N4 `' g/ S _nop_(); //空操作四个机器周期,给硬件反应时间
/ r) B/ [ R S0 J# a# u E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
: |- q) A( h' ^" P; G8 s* ` }$ b7 y2 I( h1 z
/*****************************************************5 ^) O& p8 i2 \( x
函数功能:对LCD的显示模式进行初始化设置
% B3 |- H* w# n& S***************************************************/
8 p& F3 ?5 |, C& D5 _# [, k! m' j1 Pvoid LcdInitiate(void)
g) r* D" A% k% _9 v{- S7 C) o# J& I- Y6 `
delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间. I: b! y. D' S$ O! `* n
WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口# @* [; X0 M# t C
delay(5); //延时5ms
. x8 g$ F- d7 D$ K( u WriteInstruction(0x38);
5 P1 C0 _8 L [' Q3 E# Q delay(5);4 B1 N U: i' ?& i- k
WriteInstruction(0x38);- H2 x; G! c: u& F; V
delay(5);! i1 M' @3 f( O3 f7 i; u. l
WriteInstruction(0x0f); //显示模式设置:显示开,有光标,光标闪烁! b$ f3 D- C- w/ H+ y% c
delay(5);
. w! O8 u o+ S* o0 T% X, | WriteInstruction(0x06); //显示模式设置:光标右移,字符不移! x, @& D0 F' N- \9 C3 N
delay(5);
% F( I/ L) `5 ~. N2 J WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除& ?5 t7 ^6 a# F* ~2 }
delay(5);& B- ~3 q2 p( @
}
7 {& M( }: F8 M4 N0 w! G5 l% X* cvoid main(void) //主函数
, e5 P3 j L9 o+ v N# n) u( {) S {, n% Q1 _5 c- y$ N
unsigned char i;7 Y8 Y5 W" g; ~! O m
LcdInitiate(); //调用LCD初始化函数
, h% i6 \: \" d0 F* B delay(10);
) D2 e& D6 M0 M% w while(1)
7 V9 I0 D3 c. q! ` {
1 N0 ^9 S5 x: |& m4 k1 _% [ WriteInstruction(0x01);//清显示:清屏幕指令% \# e% H( W; t6 U( R' J
WriteAddress(0x00); // 设置显示位置为第一行的第1个字
, M0 t6 j2 H3 q$ R# H/ H i = 0;5 S+ ?; e: @( ~6 p d
while(string != '\0')//只要没有写到字符串结束标志,就继续写
g9 Q- R& J$ J0 |1 Q+ |: z { // 显示字符: i- A% j3 E! k7 s5 C! D& b
WriteData(string);
1 I) x! u5 ?% h i++;# I. Y' G6 e( l; r
delay(150);$ m6 v% W' u p' L9 y# ^$ ~
}
2 H2 U7 B; E6 n D. V% P for(i=0;i<4;i++)
$ X3 i. Q0 G/ t2 r delay(250);
% S, q( f4 r: |9 t8 A& a1 l" i9 a9 B, B5 L I j' o) G- J1 F
…………限于本文篇幅 余下代码请从论坛下载附件…………
( U# E2 M }: n( T2 f% P# h
$ {: E7 Y8 P- X) O1 K1 n* v/ L- ~ n
7 C+ m! G0 F; d0 ], q+ `) ~5 Q: x |
|