历史上的今天
今天是:2025年08月12日(星期二)
2018年08月12日 | 51单片机三线串行驱动12864液晶
2018-08-12 来源:eefocus
以前写12864的液晶程序都是用的并行的方式,这种方式焊接起来很麻烦,而且占用的IO口比较多。
今天尝试使用串行方式来驱动该模块。
本程序是基于STC89C52的12864串行模式的程序,硬件电路连接只需要5根线,VCC GND RS RW E , 只需要三个个IO 口就可以显示,大大节省了资源。
12864液晶芯片是st7920。自带中文字库。
该程序功能:实现使用12864液晶显示字符、汉字(程序有详细的中文注释)。
已经调试通过,很好用。
下面是电路原理图

其时序图如下:

根据其时序图写出其代码如下:
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit CS = P2^7;//第4根线 RS
sbit SID = P2^6;//第5根线 RW
sbit SCK = P2^5;//第6根线 E
uchar code AC_TABLE[]={
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, //第一行汉字位置
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, //第二行汉字位置
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, //第三行汉字位置
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, //第四行汉字位置
};
/******************************** 函数名称 :SendByte 串口发送一个字节*****/
void SendByte(uchar Dbyte)
{
uchar i;
for(i=0;i<8;i++)
{
SCK = 0;
Dbyte=Dbyte<<1;
SID = CY;
SCK = 1;
SCK = 0;
}
}
/***********接收一个字节***/
uchar ReceiveByte(void)
{
uchar i,temp1,temp2;
temp1 = 0;
temp2 = 0;
for(i=0;i<8;i++)
{
temp1=temp1<<1;
SCK = 0;
SCK = 1;
SCK = 0;
if(SID) temp1++;
}
for(i=0;i<8;i++)
{
temp2=temp2<<1;
SCK = 0;
SCK = 1;
SCK = 0;
if(SID) temp2++;
}
return ((0xf0&temp1)+(0x0f&temp2));
}
void CheckBusy( void )
{
do SendByte(0xfc);
while(0x80&ReceiveByte());
}
void WriteCommand(uchar Cbyte )
{
CS = 1;
CheckBusy();
SendByte(0xf8);
SendByte(0xf0&Cbyte);
SendByte(0xf0&Cbyte<<4);
CS = 0;
}
void WriteData(uchar Dbyte )
{
CS = 1;
CheckBusy();
SendByte(0xfa);
SendByte(0xf0&Dbyte);
SendByte(0xf0&Dbyte<<4);
CS = 0;
}
uchar ReadData( void )
{
CheckBusy();
SendByte(0xfe);
return ReceiveByte();
}
void Delay(uint MS)
{
uchar us,usn;
while(MS!=0)
{
usn = 2;
while(usn!=0)
{
us = 0xf5;
while (us!=0)
{
us--;
};
usn--;
}
MS--;
}
}
void LcmInit( void )
{
WriteCommand(0x30);
WriteCommand(0x03);
WriteCommand(0x0C);
WriteCommand(0x01);
WriteCommand(0x06);
}
void LcmClearTXT( void )
{
uchar i;
WriteCommand(0x30);
WriteCommand(0x80);
for(i=0;i<64;i++)
WriteData(0x20);
}
void PutStr(uchar row,uchar col,uchar *puts)
{
WriteCommand(0x30);
WriteCommand(AC_TABLE[8*row+col]);
while(*puts != '\0')
{
if(col==8)
{
col='0';
row++;
}
if(row==4) row='0';
WriteCommand(AC_TABLE[8*row+col]);
WriteData(*puts);
puts++;
WriteData(*puts);
puts++;
col++;
}
}
void DisplayDots(uchar DotByte)
{
uchar i,j;
WriteCommand(0x34);
WriteCommand(0x36);
for(i=0;i<32;i++)
{
WriteCommand(0x80|i);
WriteCommand(0x80);
for(j=0;j<32;j++)
{
WriteData(DotByte);
}
DotByte=~DotByte;
}
}
void main( void )
{
Delay(100);
LcmInit();
LcmClearTXT();
while(1)
{
PutStr(0,0,"欢迎光临");
PutStr(1,0,"Rayu技术分享");
PutStr(2,0,"http://blog.rayu");
PutStr(3,0,"u.com/");
}
}
显示效果如下:

史海拾趣
|
本来打算把编译部分的内容总结一下,偶然看到一位网友的文章写得很全面,故此稍加整理,以作备忘。 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需 ...… 查看全部问答> |
|
移植ax88796 网卡驱动到vivi时遇到的问题,望大虾们帮帮忙!!! 在网上下了一个有tftp功能的vivi,但是要自己添加ax88796网卡的驱动,现将uboot-1.2.0中对应的ne2000的驱动copy到vivi下面,编译通过后,当在板子上运行的时候就出错了,后来通过prink的信息追踪到了下面的函数: static void dp83902a_poll(void ...… 查看全部问答> |
|
如果要初始化一个字符串有两种写法: 1:char *p = \"hello\"; 2:char *p; p = \"hello\"; 这两种写法有没有错的,是否有区别。 谭浩强c程序设计p238说是一样的,大家讨论一下吧 … 查看全部问答> |
|
USART3映射方式2(映射到PD8,PD9)时,要先开启AFIO功能,再初始化相关外设后,USART才有效。 以下代码是正确的: u32 backRcc = RCC->APB2ENR & (RCC_APB2Periph_GPIOB | ...… 查看全部问答> |
|
最近在做一个有关峰检测的电路,网上一搜就有,非常经典的就是那个LM311,刚好手头有啊!就按照datasheet搭了一个,测试后不行,然后我就怕是搭的不稳定就焊了一个电路,但是还是不行,我还是不死心,就按照结构图,运放+三极管用其他 ...… 查看全部问答> |
|
小弟在此求助两个控制器通讯问题,说明:使用XINTF进行通讯,FPGA发送16位数到dsp数据总线,dsp通过周期中断读取数据总线上的数据,现在的问题是这样:有些数可以准确无误的传输过去,但我不能很准确的把握规律,大概0x5000一下的数可以传,没什么 ...… 查看全部问答> |
|
我新安装的是MentorExpedition7.9.3, 打开Expedition PCB 后 ,打开一块板子,但是发现Expedition PCB 软件上面的CES是灰色的 ,不能使用,这是怎么回事啊???、、、、、哪位高手能帮忙解决一下啊?谢谢啦! ...… 查看全部问答> |
|
module key(clk,key_in,key_out); input clk; input[3:0]key_in;//按键输入 output[3:0]key_out; reg[3:0]dout1,dout2,dout3; reg[3:0]a; reg i; //assign key_out=a; always@(posedge clk)//按键消抖 begin ...… 查看全部问答> |




