📄 lcd_24064.c
字号:
/***************************************************************\
|* 12864LCD显示程序 采用C8051F020控制 *|
|* 制作人:熊涛 *|
|* 时间:2007年8月12日 *|
|* 接口定义:P5接数据 DB7~DB0 *|
|* P3.3 P3.5 P3.7 接控制线 *|
|* 具体见定义 *|
\***************************************************************/
#include "c8051f020.h"
#include <string.h>
#include "zk.h" //存入CGRAM中的字库 32个汉字
#define uchar unsigned char
#define uint unsigned int
#define DATA_IO P5 //数据线接P5
sbit OUT=P1^6;
sbit KEY=P3^7;
//控制线接P3口 数据线接P5口
//sbit CE = P3^1; // 读\写使能
//CE直接接地
sbit RD = P3^3; // 写 控制
sbit CD = P3^5; // 数据\指令 选择 1为指令,0为数据
sbit WR = P3^7; // 读 控制
//函数声明
void System_Init (void);
void Port_Init (void);
uchar Read_State (void);
void Write_Cmd_Non (uchar cmd);
void Write_Cmd_Single (uchar data1,uchar cmd);
void Write_Cmd_Double (uchar data1,uchar data2,uchar cmd);
void Lcd_Init (void);
//字符的属性
uchar code sentence_dat[30]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0 };
/************************************************\
|* 延时子函数 *|
|* 入口参数: count 延时时间变量 *|
|* 出口参数: 空 *|
|* 调用函数: 空 *|
|* 说明: 系统时钟使用外部晶振22.1184MHz *|
|* *|
\************************************************/
void Delay(uchar count)
{
uchar k;
while(count--)
for(k=0;k<10;k++);
}
/************************************************\
|* 系统时钟配置子函数 *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: 空 *|
|* 说明: 系统时钟使用外部晶振22.1184MHz *|
|* 禁用看门狗 *|
\************************************************/
void System_Init(void)
{
uchar count;
WDTCN=0xde; //禁用看门狗
WDTCN=0xad;
OSCXCN=0x67;
for ( count=0; count<255; count++ ) ;
while(!(OSCXCN & 0x80 ) ); //等待晶体振荡器稳定
OSCICN=0x88; //选择外部时钟源 允许时钟丢失检测 检测到时钟丢失将复位
CKCON=0x00; //T0 12分频
}
/************************************************\
|* 端口配置子函数 *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: 空 *|
|* 说明: *|
|* *|
\************************************************/
void Port_Init (void)
{
XBR0=0x00; //
XBR1=0x00;
XBR2=0xc0; //允许交叉开关 禁止弱上拉
P0MDOUT=0xff; //1 为推挽 0为漏极开路
P1MDIN=0xff; //0 配置为模拟输入 1 配置为数字输入
P1MDOUT=0xff; //1 为推挽 0为漏极开路
P2MDOUT=0xff; //1 为推挽 0为漏极开路
P3MDOUT=0xff; //1 为推挽 0为漏极开路
P3IF=0; //端口3中断标志
P74OUT=0xff; //P4~P7设置为推挽方式
}
/************************************************\
|* 读状态字子函数 *|
|* 入口参数: 空 *|
|* 出口参数: r_state 当前状态字 *|
|* 调用函数: Delay() *|
|* 说明: *|
|* *|
\************************************************/
uchar Read_State (void)
{
uchar r_state;
DATA_IO=0xff;
CD=1;
RD=0;
WR=1;
Delay(1); //根据资料,读写信号的建立需要一定的时间(几十纳秒)
r_state=DATA_IO;
RD=1;
return (r_state);
}
/************************************************\
|* 写数据子函数 *|
|* 入口参数: W_data 待写入的数据 *|
|* 出口参数: 空 *|
|* 调用函数: Read_State () *|
|* Delay() *|
|* 说明: *|
|* *|
\************************************************/
void Write_Data (uchar W_data)
{
while( ( Read_State () & 0x03 ) != 0x03 ) ; //等待数据指令读写状态准备好
CD=0;
WR=0;
RD=1;
Delay(1); //根据资料,读写信号的建立需要一定的时间(几十纳秒)
DATA_IO=W_data;
Delay(1);
WR=1;
CD=1;
}
/************************************************\
|* 写命令子函数1---无参数指令 *|
|* 入口参数: cmd 待写入的命令 *|
|* 出口参数: 空 *|
|* 调用函数: Read_State () *|
|* Delay() *|
|* 说明: *|
|* *|
\************************************************/
void Write_Cmd_Non (uchar cmd)
{
while( ( Read_State () & 0x03 ) != 0x03 ) ; //等待数据指令读写状态准备好
CD=1;
WR=0;
RD=1;
Delay(1); //根据资料,读写信号的建立需要一定的时间(几十纳秒)
DATA_IO=cmd;
Delay(1);
WR=1;
}
/************************************************\
|* 写命令子函数2---单参数指令 *|
|* 入口参数: data1 待写入的参数 *|
|* cmd 待写入的命令 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Data () *|
|* Write_Cmd_Non () *|
|* 说明: *|
|* *|
\************************************************/
void Write_Cmd_Single (uchar data1,uchar cmd)
{
Write_Data (data1);
Write_Cmd_Non (cmd);
}
/************************************************\
|* 写命令子函数3---双参数指令 *|
|* 入口参数: data1 待写入的参数1 *|
|* data2 待写入的参数2 *|
|* cmd 待写入的命令 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Data () *|
|* Write_Cmd_Non () *|
|* 说明: *|
|* *|
\************************************************/
void Write_Cmd_Double (uchar data1,uchar data2,uchar cmd)
{
Write_Data (data1);
Write_Data (data2);
Write_Cmd_Non (cmd);
}
/************************************************\
|* LCD初始化子函数 *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Cmd_Double () *|
|* Write_Cmd_Non () *|
|* 说明: *|
|* *|
\************************************************/
void Lcd_Init (void)
{
Write_Cmd_Double ( 0x00,0x00,0x40 ); //设置文本显示区首地址为0x0000
Write_Cmd_Double ( 0x1e,0x00,0x41 ); //设置文本显示区宽度为30字节(30*8=240)
Write_Cmd_Double ( 0x00,0x08,0x42 ); //设置图形显示区首地址为0x0800
Write_Cmd_Double ( 0x1e,0x00,0x43 ); //设置图形显示区宽度为30字节
Write_Cmd_Non ( 0xa7 ); //光标形状为8点(列)*N行,N的值为0-7H(参数中低半字节)
Write_Cmd_Non ( 0x80 ); //显示方式设置(使用内部CGROM,逻辑或合成)
Write_Cmd_Non ( 0x9c ); //设置显示开关,开文本显示 显示开关(开文本和图形显示方式,禁止光标显示和闪烁)
}
/************************************************\
|* LCD清屏子函数 *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Cmd_Double () *|
|* Write_Cmd_Non () *|
|* Read_State () *|
|* Write_Data () *|
|* 说明: *|
|* *|
\************************************************/
void Lcd_Clr (void)
{
uint count;
Write_Cmd_Double ( 0x00,0x00,0x24 ); //设置显示RAM的地址为0x0000
Write_Cmd_Non ( 0xb0 ); //设为自动写状态
for (count=0;count<0x2000;count++)
{
while( ( Read_State () & 0x0c ) != 0x0c ) ;
Write_Data (0x00);
}
Write_Cmd_Non ( 0xb2 ); //退出自动写状态
Write_Cmd_Double ( 0x00,0x00,0x24 ); //设置显示RAM的地址为0x0000
}
/************************************************\
|* 字符串显示子函数 *|
|* 入口参数: add 待写入的地址 (0~239) *|
|* sentence[] 待写入的字符串 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Cmd_Double () *|
|* Write_Cmd_Non () *|
|* Write_Cmd_Single () *|
|* strlen() *|
|* Write_Data () *|
|* 说明: *|
|* *|
\************************************************/
void Write_Eng(uchar add,uchar sentence[])
{
uchar count;
Write_Cmd_Non (0x94); //应用文本显示 关图形显示 光标显示和光标闪烁
Write_Cmd_Non (0x84); //启用CGROM和文本属性
Write_Cmd_Double ( add,0x00,0x24 ); //设置显示地址
for(count=0;count<strlen(sentence);count++)
{
Write_Cmd_Single ( sentence[count]-32,0xc0 );
}
Write_Cmd_Double ( add,0x08,0x24 ); //置显示地址 为文本属性
for(count=0;count<strlen(sentence);count++)
{
Write_Cmd_Single ( sentence_dat[count],0xc0 ); //正显闪烁
}
}
/************************************************\
|* 建立CGRAM字库子函数 *|
|* 可以建立128个8*8点阵(字符或图标等) *|
|* 字符代码规定在0x80~0xff *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Cmd_Double () *|
|* Write_Cmd_Non () *|
|* Read_State () *|
|* Write_Data () *|
|* 说明: *|
|* *|
\************************************************/
void Setup_Cgram ( void )
{
uint count;
Write_Cmd_Double ( 0x03,0x00,0x22 ); //设置CGRAM偏置地址03 对应的字符代码为0x80的点阵的RAM地址为0x1c00~0x1c07
Write_Cmd_Double ( 0x00,0x1c,0x24 ); //设置RAM地址为0x1c00 准备将字库(32*4)写入其中
Write_Cmd_Non ( 0xb0 ); //设为自动写状态
for(count=0;count<128*8;count++)
{
while( ( Read_State () & 0x0c ) != 0x0c ) ;
Write_Data ( DotTbl16[count] );
}
Write_Cmd_Non ( 0xb2 ); //退出自动写状态
}
/************************************************\
|* 写单个汉字子函数 *|
|* *|
|* *|
|* 入口参数: 空 *|
|* 出口参数: 空 *|
|* 调用函数: Write_Cmd_Double () *|
|* Write_Cmd_Non () *|
|* Read_State () *|
|* Write_Data () *|
|* 说明: *|
|* *|
\************************************************/
void write_word ( uchar add , uchar word_code )
{
Write_Cmd_Double ( add,0x00,0x24 );
Write_Cmd_Single ( word_code,0xc0 );
Write_Cmd_Single ( word_code+2,0xc0 );
Write_Cmd_Double ( add+30,0x00,0x24 );
Write_Cmd_Single ( word_code+1,0xc0 );
Write_Cmd_Single ( word_code+3,0xc0 );
}
void write_sentence (uchar add )
{
uchar count;
for(count=0;count<32;count++)
{
if ( (add%30+count*2)%30==0 ) add+=30;
write_word ( add+count*2 , 0x80+count*4);
}
}
void main( void )
{
System_Init ();
Port_Init ();
Lcd_Init ();
Lcd_Clr ();
Write_Eng(0 ,"Hello! I'm Elbe! QQ:6036725 ");
Setup_Cgram ();
write_sentence (30);
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -