单片机用键盘控制1602lcd 程序仿真通过了电路焊接应该也没问题 但是1602一点反应也没有 可能是哪里出问题

单片机用键盘控制1602lcd 程序仿真通过了电路焊接应该也没问题 但是1602一点反应也没有 可能是哪里出问题,第1张

背光不亮肯定是电路焊接的问题 ,仔细查看下1602的引脚图看一下是不是接错了。

也可以用万用表测一下1602的15,16引脚的电压是不是电源电压,还有可能就是你的GND没接好,多试一试,自己想想,不难的

你好:

LCD 1602的响应速度相对于单片机的速度来说是偏慢的。

举个简单的例子,把一桶油通过漏斗向一个瓶子里倒,倒油的速度,即流量必须维持在一定范围之内,倒得太快油会从漏斗顶部溢出来,这样就浪费掉了。我们通过眼睛可以判断并使油面保持在顶面以下,以漏斗的额定流量来倒油,这样效率最高。

而对于单片机来说,1602好比那个瓶子漏斗,写入1602中要显示的数据好比油,如果以单片机的高运行速度向1602写数据就很可能造成上面所说的溢出,比如连续写入abc,结果只显示出了a,这是因为1602的显示芯片每次都要花时间来处理输入的ascii码数据,并把它显示出来。而我们却不容易主动地去控制写入数据的速度,所以1602使用忙信号就有必要了,每次单片机只有检测到忙信号为0,即不忙时,才向1602发数据。比如要显示abc,则这样 *** 作,写a---判忙---写b---判忙---写c---判忙。这样就不会出错了。

这几年推出的lcd,像手机的屏响应速度就比较快,而1602这个古董我用示波器测过,大约40us左右的忙处理时间,而很多速度快的单片机的指令周期都是ns级的。也就是说单片机相当一段时间都在‘等’LCD。

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

void busy(void)

{ uchar temp=0x80; //初始化temp最高位为1,使得能够进入下面

//的while循环

P0=0xff;(P0就是8个数据口)

rs=0; //设置命令 *** 作

rw=1; //设置读 *** 作

en=1; //使能

delay(100);(这是设的延时函数,不用解释)

while(temp & 0x80) //判忙,一旦表达式为假,即temp最高位为0,

//则表示1602不忙,跳出while

{temp=P0;delay(20);} //把p0的的高位读入temp,延时

en=0; //关闭使能信号

}

每次读写 *** 作都要调用这个busy函数

51单片机对lcd1602一些基础程序

#include <intrinsh>

#define dataport P1

sbit RS=P2^ 6;

sbit RW=P2^5;

sbit EN=P2^4;

//========================

//=========================

void waitfor() //检测忙信号函数

{

dataport=0xff;

RS=0;RW=1;_nop_(); //选择指令寄存器 读 *** 作

EN=1;_nop_(); //使能 *** 作

while(dataport&0x80); //如果最高位是1 表示1602正忙 原地踏步 忙完后芯片会将高位拉低

EN=0;

}

//======================

void writedata(unsigned char dataw) //写数据到lcm

{

waitfor(); //测忙

RS=1;RW=0;_nop_(); //选择数据寄存器 写 *** 作

dataport=dataw;_nop_(); //将数据送到数据口

EN=1;_nop_();_nop_();EN=0; //使能

}

//==========================

void writecmd(unsigned char cmd) //写命令到lcm

{

waitfor();

RS=0;RW=0;_nop_();

dataport=cmd;_nop_();

EN=1;_nop_();_nop_();EN=0;

}

//===========================

void init(void) // 初始化函数

{

writecmd(0x38); //功能设定 8位数据传输 双行显示

writecmd(0x0c);//显示器开关

writecmd(0x01);//清屏

writecmd(0x06);//字符进入模式 每进入一个字符光标向右移动一格 原有字符不动

//我在刚开始学的时候不知道下一个字符显示在哪 是和AC值有关还是和光标位置有关

//最后摸索出来是只和光标定位有关 现在还是不知道Ac值有什么用

}

//=========================

void location(unsigned char x,unsigned char y) //确实坐标函数

{

unsigned char temp;

temp=x&0x0f; //只要x数据的后四位

if(y){temp=temp|0x40;} //第一行为0 第二行为1 如果y=1则地址加0x40

temp|=0x80; //DDRAM地址的命令DB7为一

writecmd(temp);

}

//==============================

void displyonechar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数

{

location(x,y);

writedata(dataw);

}

//=======================================

void displylistchar(unsigned char x,unsigned char y,unsigned char p) //显示字符串

{

while(p) //当一个字符型数组读完时P指的为零

{

displyonechar(x,y,(p++));

x++;

}

}

//=====================================================

void writecgram(unsigned char address,unsigned char p) //写CGRAM的数据

{

unsigned char i=8;

writecmd(address); //CGRAM里的地址 初始值0x40 每次加0x80

while(i--)

{

writedata(p);

p++;

}

}

//=====================================================

void displyonecharacter(unsigned char x,unsigned char y,unsigned char address,unsigned char p) //显示一个自定义字符

{

unsigned char i=8;

writecmd(address); //CGRAM里的地址 初始值0x40 每次加0x08

while(i--)

{

writedata(p);

p++;

}

//============================================================

location(x,y); //设定要显示的位置

writedata((address&=0x3f)/0x08); //要从CGRAM中读出数据在1602上显示 搞了半天发现CGRAM里的地址

} //和DDRAM里的地址有上面的转换关系

//========================================================

void displynumber(unsigned char x,unsigned char y,unsigned long num) //显示一个整数

{

unsigned int number[8];

int k,gh;

for(k=0;;k++)

{

(number+k)=(unsigned int)(num%10);//强制类型转换

num=num/10;

if(num==0)break;

}

for(gh=k;gh>=0;gh--)

{

displyonechar(x,y,((number+gh)+48));

x++;

}

}

//字型码

uchar code nin[]={0x08,0x0f,0x12,0x0f,0,0x1f,0x02,0x02};// "年"

uchar code yue[]={0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11};// "月"

uchar code ri[]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x11,0x1f};// "日"

显示汉字

displyonecharacter(0,0,0x40,nin);

displyonecharacter(1,0,0x80,yue);

displyonecharacter(1,0,0xc0,ri);

void busy_test()//检测lcd是否忙

{

    u8 st;            //忙状态标志 0:不忙,0x80:忙 

    if(f_init==0)     //如果某个东西没有初始化

    {

         return;      // 退出忙判断,不执行下面的代码

    }

    lcd=0xff;         // 先往数据端口赋高电平,便于读数据 

    rs=0;             // 读忙设置

    rw=1;//读

    do

    {

        e=1;          // 数据端口读写使能

        st=lcd;       // 读数据端口的值

        e=0;          // 禁止数据端口读写

    }

    while(st&0x80);   // 如果忙位BF为1,就一直读端口数据,直到为0才退出忙判断。

                      // BF:忙标志位,为数据端口的BIT7位。所以为0x80

}

没有时间看程序。

没显示可能有硬件的原因:

硬件连接问题,如果那个管脚没有连接,或者连接错误,或者电压不对。看LCD datasheet, 了解每个管脚应该怎么接。

如果确认硬件没问题,用软件把LCD全屏全部点亮,看看能不能成功。

1602的读写程序有些问题,缺了“忙”检测。给你一些1602的相关函数,供参考。

#define LCD1602_FLAG

#define LCD1602_PORT P1

#include<reg52h>

#include<stddefh>

#include"dtypeh"

sbit lcd1602_rs=P3^7;

sbit lcd1602_e=P3^5;

sbit lcd1602_rw=P3^6;

sbit lcd1602_busy=P1^7;

/

函数名称:lcd1602_CheckBusy()

函数功能:状态查询

/

void lcd1602_CheckBusy()

{

do

{

lcd1602_busy=1;

lcd1602_rs=0;

lcd1602_rw=1;

lcd1602_e=0;

lcd1602_e=1;

}

while(lcd1602_busy);

}

/

函数名称: lcd1602_WriteCmd()

函数功能:写命令

入口参数:命令字

出口参数:无

/

void lcd1602_WriteCmd(const INT8U cmd)

{

lcd1602_CheckBusy();

lcd1602_rs=0;

lcd1602_rw=0;

lcd1602_e=1;

LCD1602_PORT=cmd;

lcd1602_e=0;

}

/

函数名称:lcd1602_WriteData()

函数功能:写数据

入口参数:c--待写数据

出口参数:无

/

void lcd1602_WriteData(const INT8U c)

{

lcd1602_CheckBusy();

lcd1602_rs=1;

lcd1602_rw=0;

lcd1602_e=1;

LCD1602_PORT=c;

lcd1602_e=0;

}

/

函数名称:lcd1602_Init()

函数功能:初始化LCD

入口参数:无

出口参数:无

/

void lcd1602_Init()

{

lcd1602_WriteCmd(0x38); //显示模式为8位2行57点阵

lcd1602_WriteCmd(0x0f); //display enable,flag enable,flash enable,

lcd1602_WriteCmd(0x06); //flag move to right,screen don't move

lcd1602_WriteCmd(0x01); //clear screen

}

/

函数名称:lcd1602_Display()

函数功能: 字符显示

入口参数:ptr--字符或字符串指针

出口参数:无

说 明:用户可通过以下方式来调用:

1)lcd1602_Display("Hello,world!");

2) INT8U 存储类型 txt[]="要显示的字符串";

或者 INT8U 存储类型 txt[]={'t','x','t',,'\0'};

INT8U ptr;

ptr=&txt;

lcd1602_Display(ptr);

或 lcd1602_Display(txt);

或 lcd1602_Display(&txt);

/

void lcd1602_Display(const INT8U ptr)

{

INT8U data i=0;

INT8U data q;

q=ptr;

lcd1602_WriteCmd(0x80);

while(q!=NULL && (q!='\0') && i<16)

{

lcd1602_WriteData(q);

q++;

i++;

}

lcd1602_WriteCmd(0xc0);

while(q!=NULL && (q!='\0') && i>=16 && i<32)

{

lcd1602_WriteData(q);

q++;

i++;

}

}

您好,//以下几条指令是在CE使能端产生一个正脉冲,使LCD响应指令digitalWrite(Enable,LOW); //先强制为低电平

delayMicroseconds(1); //延时1微秒digitalWrite(Enable,HIGH); //然后跳到高delayMicroseconds(1); //延时1微秒digitalWrite(Enable,LOW); //再回到低电平delayMicroseconds(1); //再延时一下}

//LCD数据写入函数void LcdDataWrite(int value) {int i = 0;digitalWrite(DI, HIGH); digitalWrite(RW, LOW); //RW端允许接收数据for (i=DB[0]; i <= DB[7]; i++) { //意思同上一个函数 digitalWrite(i,value &01); value >>= 1;}digitalWrite(Enable,LOW); //意思同上一个函数delayMicroseconds(1);digitalWrite(Enable,HIGH);delayMicroseconds(1);digitalWrite(Enable,LOW);delayMicroseconds(1); }

void setup (void) {int i = 0;for (i=Enable; i <= DI; i++) { //设置端口状态 pinMode(i,OUTPUT);}

//以下是LCD开机初始化的指令,多次执行0x38是确保初始化的成功率delay(100);LcdCommandWrite(0x38); // 8线2行的LCD用0x38 delay(64); LcdCommandWrite(0x38); delay(50); LcdCommandWrite(0x38); delay(20); LcdCommandWrite(0x06); //设定输入方式,增量不移位 delay(20); LcdCommandWrite(0x0E); //忘了 delay(20); LcdCommandWrite(0x01); //忘了

delay(100); LcdCommandWrite(0x80); //开显示,光标不闪 delay(20); }

提醒一下: 一般CE使能端在1602中, 大部分是在脉冲的下降沿生效。

>

以上就是关于单片机用键盘控制1602lcd 程序仿真通过了电路焊接应该也没问题 但是1602一点反应也没有 可能是哪里出问题全部的内容,包括:单片机用键盘控制1602lcd 程序仿真通过了电路焊接应该也没问题 但是1602一点反应也没有 可能是哪里出问题、LCD 1602显示字符,编写程序的时候,为何要弄一个忙信号判断函数这个有什么作用、给个单片机液晶1602显示汉字的程序,谢谢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10092206.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存