📄 lcd2864_dispaly.c
字号:
//实验目的:用PICC熟悉12864LCD的中文使用
//使用12864LCD自带中文字库
//编程让LCD12864向上滚动显示诗词〈北京欢迎你〉
//硬件设置:
//关断LCD1602的所有跳线,接通LCD12864的所有跳线。
#include<p30f6014.h>
_FOSC(CSW_FSCM_OFF & XT_PLL4); //4倍频晶振,Failsafe 时钟关闭
_FWDT(WDT_OFF); //关闭看门狗定时器
_FBORPOR(PBOR_OFF & MCLR_EN); //掉电复位禁止,MCLR复位使能。
_FGS(CODE_PROT_OFF); //代码保护禁止
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define rs LATBbits.LATB4 //定义LCD的数据/命令控制口
#define rw LATBbits.LATB5 //定义LCD的读/写控制口
#define e LATBbits.LATB6 //定义LCD的使能口
#define psb LATBbits.LATB2 //8位/4位并口选择
#define rst LATBbits.LATB7 //定义复位口
#define nop() asm("nop") //定义nop()函数
const unsigned char sdgt[]={
//北京欢迎你
' ',' ',0xB1,0xB1,0xBE,0xA9,0xBB,0xB6,0xD3,0xAD,0xC4,0xE3,' ',' ',' '};
const unsigned char clear[]={
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
const unsigned char time[]={
//2008年10月12日
'2','0','0','8',0xC4,0xEA,'1','0',0xD4,0xC2,'1','2',0xC8,0xD5,' ',' '};
const unsigned char TAB[16][16]={
{//我家大门常打开
0xCE,0xD2,0xBC,0xD2,0xB4,0xF3,0xC3,0xC5,0xB3,0xA3,0xB4,0xF2,0xBF,0xAA,',' ,' '},
{//开放怀抱等你。
0xBF,0xAA,0xB7,0xC5,0xBB,0xB3,0xB1,0xA7,0xB5,0xC8,0xC4,0xE3,',',' ',' ' ,' '},
{//拥抱过后有了默契,
0xD3,0xB5,0xB1,0xA7,0xB9,0xFD,0xBA,0xF3,0xD3,0xD0,0xC1,0xCB,0xC4,0xAC,0xC6,0xF5},
{//你会爱上这里。
0xC4,0xE3,0xBB,0xE1,0xB0,0xAE,0xC9,0xCF,0xD5,0xE2,0xC0,0xEF,',', ' ', ' ' , ' '},
{//不管远近都是朋友,
0xB2,0xBB,0xB9,0xDC,0xD4,0xB6,0xBD,0xFC,0xB6,0xBC,0xCA,0xC7,0xC5,0xF3,0xD3,0xD1},
{//请不要客气,
0xC7,0xEB,0xB2,0xBB,0xD2,0xAA,0xBF,0xCD,0xC6,0xF8,',',' ',' ', ' ' , ' ' , ' '},
{//第几次来没关系。
0xB5,0xDA,0xBC,0xB8,0xB4,0xCE,0xC0,0xB4,0xC3,0xBB,0xB9,0xD8,0xCF,0xB5,',' ,' '},
{//我们欢迎你,
0xCE,0xD2,0xC3,0xC7,0xBB,0xB6,0xD3,0xAD,0xC4,0xE3,',',' ',' ', ' ' , ' ' , ' '},
{//北京欢迎你!
0xB1,0xB1,0xBE,0xA9,0xBB,0xB6,0xD3,0xAD,0xC4,0xE3,'!',' ',' ', ' ' , ' ' , ' '},
{//让温暖感动你,
0xC8,0xC3,0xCE,0xC2,0xC5,0xAF,0xB8,0xD0,0xB6,0xAF,0xC4,0xE3,',',' ',' ',' '},
{//流动中的魅力充满,
0xC1,0xF7,0xB6,0xAF,0xD6,0xD0,0xB5,0xC4,0xF7,0xC8,0xC1,0xA6,0xB3,0xE4,0xC2,0xFA},
{//着朝气北京欢迎你。
0xD7,0xC5,0xB3,0xAF,0xC6,0xF8,0xB1,0xB1,0xBE,0xA9,0xBB,0xB6,0xD3,0xAD,0xC4,0xE3},
{//在太阳下分享呼吸,
0xD4,0xDA,0xCC,0xAB,0xD1,0xF4,0xCF,0xC2,0xB7,0xD6,0xCF,0xED,0xBA,0xF4,0xCE,0xFC},
{//在黄土地刷新成绩
0xD4,0xDA,0xBB,0xC6,0xCD,0xC1,0xB5,0xD8,0xCB,0xA2,0xD0,0xC2,0xB3,0xC9,0xBC,0xA8},
{//我家种着万年青,
0xCE,0xD2,0xBC,0xD2,0xD6,0xD6,0xD7,0xC5,0xCD,0xF2,0xC4,0xEA,0xC7,0xE0,',',' '},
{//开放每段传奇..,
0xBF,0xAA,0xB7,0xC5,0xC3,0xBF,0xB6,0xCE,0xB4,0xAB,0xC6,0xE6,'.','.','.','.'},
};
unsigned int lcd_x; //定义LCD页地址寄存器
unsigned int lcd_y; //定义LCD列地址寄存器
void init(); //申明I/O口设置函数
void lcd_init(); //申明LCD初始化函数
void clear_p(); //申明清屏函数
void qushu(int counts,const unsigned char *ps); //申明查表获取显示数据
void send_d(unsigned char x); //申明送一字节数据显示函数
void send_i(unsigned char x); //申明送一字节控制命令函数
void chk_busy(); //申明检测LCD是否工作繁忙函数
void delay(); //申明延时函数,供各命令之间的延时和决定显示快慢用
//-------------------------------------------
//主程序
int main(void)
{
unsigned char i,j;
init(); //调用I/O口设置函数
lcd_init(); //调用LCD初始化函数
clear_p(); //调用清屏函数
while(1)
{
clear_p();
send_i(0x90); //设置显示位置:第二行
qushu(0x10,sdgt); //显示歌头行
send_i(0x88); //设置显示位置:第三行
qushu(0x10,time); //显示日期行
for(j=0;j<160;j++)
{delay();} //延时一定时间
clear_p(); //清屏
for(i=0;i<16;i++) //显示完所有信息需移动16次
{
send_i(0x80); //设置显示位置:显示第一行
qushu(0x10,TAB[i]);
send_i(0x90); //设置显示位置:清除第二行
qushu(0x10,clear);
delay();
send_i(0x90); //设置显示位置:显示第二行
qushu(0x10,TAB[i+1]);
send_i(0x88); //设置显示位置:清除第三行
qushu(0x10,clear);
delay();
send_i(0x88); //设置显示位置:显示第三行
qushu(0x10,TAB[i+2]);
send_i(0x98); //设置显示位置:清除第四行
qushu(0x10,clear);
delay();
send_i(0x98); //设置显示位置:显示第四行
qushu(0x10,TAB[i+3]);
delay();
for(j=0;j<16;j++) //控制移动频率
{delay();}
}
for(j=0;j<32;j++) //显示完一次,等待一定时间
{delay();}
}
}
//-------------------------------------------
//I/O口设置函数
void init()
{
TRISB=0X0000; //设置B口为输出
TRISD=0X0000; //设置D口为输出
}
//-------------------------------------------
//LCD初始化函数
void lcd_init()
{
rst=0; //复位LCD
delay(); //保证复位所需要的时间
rst=1; //恢复LCD正常工作
nop();
psb=1; //设置LCD为8位并口通信
send_i(0x30); //基本指令操作
send_i(0x01); //清除显示
send_i(0x06); //指定在写入或读取时,光标的移动方向
send_i(0x0c); //开显示,关光标,不闪烁
}
//有关显示设置函数
void wr_zb()
{
send_i(lcd_y);
send_i(lcd_x);
}
//-------------------------------------------
//清屏函数
void clear_p()
{
send_i(0x1); //清除所有显示
send_i(0x34); //扩展指令操作
send_i(0x30); //基本指令操作
}
//------------------------------------------
//查表函数
void qushu(int counts,const unsigned char *ps)
{
int i; //定义循环变量
for(i=counts;i>0;i--) //循环counts次
{
send_d(*ps); //查表取数并调用显示一个字节数据函数送显示
ps++; //取下一个数据
}
}
//-------------------------------------------
//显示一字节数据函数
void send_d(unsigned char x)
{
chk_busy(); //检测LCD是否工作繁忙
rs=1; //设置该字节数据是显示数据
rw=0; //设置该次操作为写
PORTD=x; //送数据口PORTD
e=1; //使能
nop();
nop();
nop();
e=0; //禁止
}
//--------------------------------------------
//送一字节命令代码函数
void send_i(unsigned char x)
{
chk_busy(); //检测LCD是否工作繁忙
rs=0; //设置该字节数据为控制命令
rw=0; //设置此次操作为写
PORTD=x; //送数据口PORTD
e=1; //使能
nop();
nop();
nop();
e=0; //禁止
}
//-------------------------------------------
//检测LCD是否工作繁忙
void chk_busy()
{
TRISD=0Xffff; //更改总线方向为输入
rs=0; //总线上为命令
delay();
rw=1; //读操作
delay();
while(PORTDbits.RD7)
{
delay();
delay();
e=1;
delay();
delay();
e=0;
}
e=0;
TRISD=0X0000; //总线还原为输出
}
//-------------------------------------------
//延时函数
void delay()
{
int i;
for(i=0;i<4000;i++)
{;}
}
//-------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -