所有人回答的都不对,其实是忘了将1602第5脚rw设置为0了,而郭天祥的板子是直接接地,所以不用设置,但是别的板子却不能照搬了。所以程序应改为
sbit lcdrw=P3^6;
void write_com(uchar com)
{
lcdrs=0;
lcdrw=0;//加这一条
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
lcdrw=0;//加这一条
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*=========================================================
以前在百度弄来的例子,STC不知道能不能用,
SMC1602A(16*2)模拟口线接线方式 连接线图:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
---------------------------------------------|
DB4-----P1.4 | RW-------P2.0 |
DB5-----P1.5 | RS -------P2.1 |
DB6-----P1.6 | E --------P2.2 |
DB7-----P1.7 | VLCD 接 1K 电阻到 GND|
---------------------------------------------------
[注:AT89S51 使用 12M 晶体震荡器]
=========================================================*/
#include
sbit LCM_RS=P2^0; //定义引脚
sbit LCM_E =P2^1;
#define LCM_Data P0
#define Busy 0x80 //用于检测 LCM 状态字中的 Busy 标识
void WriteDataLCM(unsigned char Data);
void WriteCommandLCM(unsigned char Command);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delayms(unsigned int n);
void dellay(unsigned int h);
unsigned char code blog_adr[] = {"la_ji_1602"};
unsigned char code email[] = {"lan_bu_la_ji_dx"};
void main(void)
{
//Delay400Ms(); //启动等待,等 LCM 讲入工作状态
LCMInit(); //LCM 初始化
DisplayListChar(3, 0, blog_adr);
DisplayListChar(0, 1, email);
while(1);
}
//写数据 RS="H",RW=L,D0~D7=数据,E=高脉冲
void WriteDataLCM(unsigned char Data)
{
LCM_RS = 1;
LCM_E = 0;
LCM_Data =(Data & 0xF0);
LCM_E = 1;
dellay(100); //短暂延时,代替检测忙状态
LCM_E = 0;
LCM_Data =(Data & 0x0F)<<4;
LCM_E = 1;
dellay(100);
LCM_E = 0;
}
//写指令 RS="L",RW=L,D0~D7=指令码,E=高脉冲
void WriteCommandLCM(unsigned char Command)
{
dellay(100); //短暂延时,代替检测忙状态
LCM_RS = 0;
LCM_E = 0;
LCM_Data =( Command & 0xF0);
LCM_E = 1;
dellay(100);
LCM_E = 0;
LCM_Data =( Command & 0x0F )<<4;
LCM_E = 1;
dellay(100);
LCM_E = 0;
}
//读数据 RS="H",RW=H,E=H
//读状态 RS="L",RW=H,E=H
//由于不要检测忙,所以读数据和读状态两个函数省略
void LCMInit(void) //LCM 初始化
{
LCM_Data = 0;
Delayms(15);
WriteCommandLCM(0x03); //三次显示模式设置,不检测忙信号
Delayms(5);
WriteCommandLCM(0x03);
Delayms(5);
WriteCommandLCM(0x03);
Delayms(5);
WriteCommandLCM(0x02);
Delayms(5);
WriteCommandLCM(0x28); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x06); // 显示光标移动设置
WriteCommandLCM(0x0C);
WriteCommandLCM(0x01);
Delayms(5);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制 X 不能大于 15,Y 不能大于 1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制 X 不能大于 15,Y 不能大于 1
while (DData[ListLength]>0x1f) //若到达字串尾则退出
{
if (X <= 0xF) //X 坐标应小于 0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++; X++;
}
}
}
void Delayms(unsigned int n)
{
unsigned int i,j;
for(j=n;j>0;j--)
for(i=112;i>0;i--);
}
/**************************************************
** 函数名称: dellay
** 入口参数:h(unsigned int型)
** 出口参数:无
** 功能描述: 短暂延时,约0.01MS
****************************************************/
void dellay(unsigned int h)
{
while(h--); //0.01MS
}
int()函数里面的 write_com(0x01); 就是 清屏
提出我的几个疑问 main函数中
for(num=0;num<11;num++)
{
write_data(table[num]);
delay(20);
}
你依次输入table[]字符,但输入地址还是初始化中给的一排一位(应该是这个吧,没用过这个开发板,我的不一样),因此不能正常显示,显示出来应该是一排一位是小黑快(但跟你说的第一排全是黑的情况不一样)
write_com(1); 是什么意思?也是清屏?
while(1);
{
write_data(0xff);
delay(20);
}
首先while(1); 这个分号不要(假如我没理解错)
再这是个死循环了,之后的for语句不会执行了
还有你最后加个while(1);
是为了只让主程序走一遍?
你1602的对比度调太低了,1602旁边有一个滑动变阻器(蓝色的小块,上面有个金黄的圆盘),你可以单片机带电用一字螺丝刀拧一拧,1602的显示就能ok
您好,我现在做设计现在很需要光盘里面的源代码和ppt作参考。网上找不到,您能抽空给我发一份吗?感激涕流啊。661025zp@163.com.再次感谢。