EDABOSS电子论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 727|回复: 0

[转帖] 单片机练习 - 带中文字库12864LCD显示程序

[复制链接]

106

主题

13

回帖

96

E币

助理工程师

Rank: 3Rank: 3

积分
225
发表于 2018-11-28 15:43:04 | 显示全部楼层 |阅读模式
I/O接口与LCD引脚的连接详见源代码注释.
& C, w9 c$ @: S
//带中文字库的12864LCD显示程序
#include <reg52.H>
#include <intrins.H>6 w* f- k4 l( I" ]9 v4 W* v" ~# m

#define uchar unsigned char
#define uint unsigned int

sbit dula = P2^6;
sbit wela = P2^7;
//SCM12864-05端口定义
#define LCD_DATA P0 //数据口0 c( L6 E' _: u' u  u
sbit RS = P3^5; //并行的指令/数据选择信号, H数据, L命令
sbit RW = P3^6; //并行读写选择信号, H读, L写1 g7 D2 e8 M- ^+ M6 s
sbit E = P3^4; //并行使能端, H有效, L无效& H- X3 N# ~4 @
sbit PSB = P3^7; //并/串接口选择, H并,L串6 J- Q; \8 D6 V8 S
sbit RET = P3^3; //复位, L有效0 n" @- V4 P; _8 W0 p+ L

uchar code datas1[] = {"广东工业大学"};
uchar code datas2[] = {"自动化学院2004级"};: J" G3 |+ ^# I; f- r( j
uchar code datas3[] = {"网络工程 (4)班"};
uchar code datas4[] = {"fengmk2@gmail.com"};6 ]( N& O! O, n' ?- L
2 O# Q# i3 X3 G. T; w
//延时约2us$ o7 h! j- G* g- N" D
void delayUs(), e+ H9 e( _8 O  F/ P# m+ n9 B& d
{; D2 B$ e6 D' s" [1 ~1 ]7 {& T4 P5 N
    _nop_();_nop_();
}% o) H$ L9 O' b* @6 L
//延时 a * 1ms
void delayMs(uint a)" M# n7 x$ ]6 v! j! n6 p
{
    uint i, j;/ G. b7 |7 G6 B4 [
    for(i = a; i > 0; i--)
        for(j = 100; j > 0; j--);  X4 F3 B  o3 c$ J3 N/ V1 r  }
}
! a2 W' R1 W' E) f8 Z5 Q) m
//检测LCD是否处于忙状态, 若忙返回1, 空闲返回0+ Z' C* D# f  X) {& f
bit checkBusy()
{: t2 j7 o, d* b/ E) D( Y
    bit busy;0 Z2 a2 s8 o; Y: P; X/ n+ ^8 n7 D" |
    RS = 0;
    RW = 1;, E' g$ s/ V. p+ M) i4 H
    E = 1;
    delayUs();
    busy = (bit)(LCD_DATA&0x80);, h+ r4 d8 y+ l+ e) {
    E = 0;1 l1 a, _9 g/ c% A
    return busy;
}
6 c# l5 q' l: f& W
//等待LCD到空闲7 P+ U4 ]7 E9 ]* |- D+ t
void wait()
{* Q1 k2 f* p/ l+ K8 D
    while(checkBusy());
}0 u1 c; m* Y& W

//写命令
void writeCmd(uchar cmd); h4 Z! O+ t- O) G* m+ A0 z; X# q
{, h% j& o/ ~1 x% x+ y
    wait();
    RS = 0;2 ~( q7 X- z% E9 @# N
    RW = 0;) @, h; H: J4 `3 J4 ~9 ?$ d  F
    E = 0;
    delayUs();' P. r5 N4 z& M# S( l
    LCD_DATA = cmd;; X/ ^+ }, p6 O
    delayUs();
    E = 1;
    delayUs();
    E = 0;% e# K; G7 C+ ]/ ]& F
}
8 o. K2 ~4 @+ ]% [/ X7 O- Y
//写数据
void writeData(uchar dat)  V+ `" u7 u  S, O: e( E2 g
{
    wait();
    RS = 1;
    RW = 0;. L/ {9 ~/ Q9 k6 {+ C# q+ g
    E = 0;" M$ \9 `2 s, `( F4 b
    delayUs();
    LCD_DATA = dat;0 D" C0 R; v2 [; m6 H
    delayUs();
    E = 1;/ Z( C1 \1 g; P4 ~. F. K$ ~& R- w# f1 a
    delayUs();! w2 o3 o9 q8 x
    E = 0;* i9 e, ?) V0 u
}5 W6 Z1 }2 H% @- H' L/ v
9 d" ]  {' R8 k' R
//初始化LCD
void init()
{" V. K5 P7 e4 M* W& r. c  W
    PSB = 1; //并口方式
    writeCmd(0x30); //基本指令, 扩充指令为34H
    delayMs(10);' t, Y; v8 I6 `+ ]; g" z3 o
    writeCmd(0x0c); //显示开, 关光标9 S7 G$ M6 W0 h# B& R- z0 c
    delayMs(10);
    writeCmd(0x01); //清屏
    delayMs(10);
}

void setPosition(uchar x, uchar y)
{! M( I9 G( U7 @: P
    uchar p;
    switch(x%4)' _% P1 @0 v! U1 i/ z7 |3 z6 q" A
    {2 Y$ r+ a: O* y- Z/ u
        case 0: p = 0x80; break; //第一行开始地址
        case 1: p = 0x90; break; //第二行
        case 2: p = 0x88; break; //第三行
        case 3: p = 0x98; break; //第四行
    }$ P3 ^, N* r6 e1 p' f- O0 m- ?' u% Z
    p += y;
    writeCmd(p);
}
void writeString(uchar * str)
{
    uchar i = 0;
    while(str != '\0')
    {
        writeData(str[i++]);
    }
}
- _- v9 o# ~8 C  h$ S  c- O& j
/***************************LCD12864***************************************/

void main()
{0 o- c( ], L) U0 @6 a
    //先关闭数码管, 使两个锁存器锁存, 因开了数码管, USB电压驱动不够, 将无法使LCD正常工作
    dula = wela = 0;
    init();
    setPosition(0, 0);
    writeString(datas1);$ b, v: n0 V9 f
    setPosition(1, 0);$ ~3 U) Z) Z9 E8 h
    writeString(datas2);
    setPosition(2, 0);- I/ ~' q6 d/ E3 |1 X. F) p
    writeString(datas3);
    setPosition(3, 0);
    writeString(datas4);
    while(1);
}

积分规则
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|EDABOSS电子论坛

GMT+8, 2024-4-19 19:39 , Processed in 0.041926 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表