elephant00 发表于 2021-8-17 17:14

1602的lcd_write_command(0x80+0x40);这句程序不起作用是怎么回事?

lcd_write_command(0x80+0x40);这句程序为什么不起作用,在液晶上只显示第一行的hello

#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit lcd_E=P2^7;
sbit lcd_RS=P2^6;
sbit lcd_RW=P2^5;
uchar code table[]="hello";
uchar code table1[]="nihao";
uchar i;
void delay(uint z)
{
      uint y;
      for(;z>0;z--)
                for(y=110;y>0;y--);
}
void lcd_write_command(uchar com)
{
      lcd_RS=0;
      lcd_RW=0;
      P0=com;
      lcd_E=1;
      lcd_E=0;
      delay(1);      
}
void lcd_write_data(uchar dat)
{
      lcd_RS=1;
      lcd_RW=0;
      P0=dat;
      lcd_E=1;
      lcd_E=0;
      delay(20);      
}
void init()
{
      lcd_E=0;
      lcd_write_command(0x38);
      lcd_write_command(0x0c);
      lcd_write_command(0x06);
      lcd_write_command(0x80);
      delay(20);
}
void main()
{
      init();
      for(i=0;i<5;i++)
      {
                lcd_write_data(table);
                delay(20);
      }
      lcd_write_command(0x80+0x40);
      for(i=0;i<5;i++)
      {
                lcd_write_data(table1);
                delay(20);
      }
      while(1);
}

rankey 发表于 2021-8-17 17:58

/*---------------------------------------------------------------------
                  hardwar1602.h文件 硬件抽取层
作者:rankey   创建日期:2019.4.8    最后修改日期:2019.4.8
版本:1.0
如果没有定义 HARDWAR1602_H
先定义 HARDWAR1602_H,那么下一次编译到这个头文件的时候上一句条件不成立,
下面的内容就不会再编译了
-----------------------------------------------------------------------*/
#ifndef __HARDWAR1602_H__
#define __HARDWAR1602_H__
#include <reg51.H>
/*1602端口定义 */
#defineLCD_DATA       P0      //LCD的数据口
#defineLCD1602_4PINS         //使用4线制
sbit   LCD1602_en = P2^5;       //液晶的使能端
sbit   LCD1602_RS = P2^6;       //液晶的数据/命令选择端
sbit   LCD1602_rw = P2^7;       //读写选择端
#ifndefLCD1602_4PINS
sbit   LCD_BUSY   = LCD_DATA^7;//LCD忙信号位 STA7为0 则读写状态使能
#else
// sbit   LCD_BUSY   = LCD_DATA^7;   
#endif
#endif



/*---------------------------------------------------------------------
                         LCD1602.H文件 LCD1602的一些命令定义
作者:rankey   创建日期:2019.4.8    最后修改日期:2019.4.8
版本:1.0
----------------------------------------------------------------------*/
#ifndef __LCD1602_H__
#define __LCD1602_H__
#defineucharunsigned char
#defineuint   unsigned int
//输入方式设置
#define LCD_AC_AUTO_INCREMENT   0x06         //数据读、写操作后,AC自动增一
#define LCD_AC_AUTO_DECREASE      0x04         //数据读、写操作后,AC自动减一
#define LCD_MOVE_ENABLE         0x05         //数据读、写操作,画面平移
#define LCD_MOVE_DISENABLE      0x04         //数据读、写操作,画面不动
//设置显示、光标及闪烁开、关
#define LCD_DISPLAY_ON            0x0C         //显示开
#define LCD_DISPLAY_OFF         0x08         //显示关
#define LCD_CURSOR_ON             0x0A         //光标显示
#define LCD_CURSOR_OFF            0x08         //光标不显示
#define LCD_CURSOR_BLINK_ON       0x09         //光标闪烁
#define LCD_CURSOR_BLINK_OFF      0x08         //光标不闪烁
//光标、画面移动,不影响DDRAM
#define LCD_LEFT_MOVE             0x18         //LCD显示左移一位
#define LCD_RIGHT_MOVE            0x1C         //LCD显示右移一位
#define LCD_CURSOR_LEFT_MOVE      0x10         //光标左移一位
#define LCD_CURSOR_RIGHT_MOVE   0x14         //光标右移一位
//工作方式设置
#define LCD_DISPLAY_DOUBLE_LINE   0x38         //两行显示
#define LCD_DISPLAY_SINGLE_LINE   0x30         //单行显示
//void delayms(uchar);//延时函数
void lcd1602_init(void);//1602初始化函数
void lcd_write_data(uchar);
void lcd_write_CMD(uchar);
void lcd_check(void);
void lcd_display(uchar x,uchar y,uchar *db);
void LCD_cls(void);   //LCD清屏
void delay1ms();       //延时1ms
void delay(unsigned char );//调用delay1ms(),实现延时若干ms,
//uchar BCD_Decimal(uchar bcd);

externuchar DEC;
//externucharcodedisp_table1;
externuint i;
extern uchar i_T_flag;
extern uint i_sec;
extern uint i_test;
#endif


#include "hardware1602.h"
#include "LCD1602.h"
uchar DEC={0,0,0,0,0};
uint i=0x0000;
uint i_test=0x0000;
#ifndefLCD1602_4PINS
void lcd1602_init()
{
lcd_write_CMD(0x38);   //8位数据,双行显示,5*7点阵   
delay(10);   //延时10ms,首次写指令时应给LCD一段较长的反应时间
lcd_write_CMD(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
delay(3);   //延时3ms 
lcd_write_CMD(LCD_DISPLAY_ON|LCD_CURSOR_OFF); //开启显示屏,不显示光标
delay(3);
lcd_write_CMD(LCD_DISPLAY_DOUBLE_LINE);//双行显示
delay(3);
LCD_cls();   //LCD清屏
}
#else
void lcd1602_init()
{
lcd_write_CMD(0x32);//将8位总线转为4位总线
delay(10);
lcd_write_CMD(0x28);//在四位线下的初始化
delay(5);
lcd_write_CMD(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
lcd_write_CMD(0x0c);//开显示不显示光标
delay(5);
lcd_write_CMD(0x06);//写一个指针加1
delay(5);
lcd_write_CMD(0x01);// LCD清屏
delay(5);
lcd_write_CMD(0x80);//设置数据指针起点

}
#endif
/**写命令操作*/
#ifndefLCD1602_4PINS   //当没有定义这个LCD1602_4PINS时,即采用8线制
void lcd_write_CMD(uchar CMD_Data)
{
    lcd_check();
    LCD1602_en=0;
    LCD1602_RS=0;         //选择写命令模式
   LCD1602_rw=0;         //写,低电平有效write嘛!
LCD_DATA=CMD_Data;   //输入指令码
//   delay1ms();         //稍作延时,等待数据稳定
   LCD1602_en=1;      //使能给高脉冲,因初始化时,已经将LCD-EN置低
//   delay1ms();
   LCD1602_en=0;      //使能端置0,完成高脉冲,发送数据
}
#else
void lcd_write_CMD(uchar CMD_Data)
{
   LCD1602_en= 0;//使能
   LCD1602_RS= 0;//选择写入命令模式
   LCD1602_rw = 0;//选择写使能
   LCD_DATA&=0x0f;// 清0 高4位
   LCD_DATA|= (CMD_Data&0xf0); //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
//   delay1ms();
   LCD1602_en = 1;//写入时序
    delay1ms();
   LCD1602_en = 0;

   
   CMD_Data= CMD_Data<<4;    //低四位移到高四位
    LCD_DATA &=0X0f;          //清高四位
    LCD_DATA |=CMD_Data&0xf0; //写低四位
//    delay1ms();
    LCD1602_en = 1;//写入时序
   delay1ms();
   LCD1602_en = 0;
   }

#endif
/*****************************************************
写数据操作
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:Data_U8(为字符常量)
***************************************************/
#ifndefLCD1602_4PINS
void lcd_write_data(uchar Data_U8)// 输出一个字节数据到LCD
{
   lcd_check();
   LCD1602_RS=1;       //写数据模式
   LCD1602_rw=0;       //选择写数据模式低电平有效
   LCD1602_en=0;      //E置低电平(根据表8-6,写指令时,E为高脉冲,
                         // 就是让E从0到1发生正跳变,所以应先置"0"
LCD_DATA=Data_U8;    //输入数据值   
//   delay(2);          //稍作延时,等待数据稳定
   LCD1602_en=1;       //使能给高脉冲,因初始化时,已经将LCD-EN置低
//   delay(2);   
   LCD1602_en=0;      //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
#else
void lcd_write_data(uchar Data_U8)// 输出一个字节数据到LCD
{
LCD1602_en = 0;   //使能
LCD1602_RS = 1;   //选择写入数据
LCD1602_rw = 0;   //选择写入
LCD_DATA &=0x0f;//清0高4位
LCD_DATA |= Data_U8&0xf0; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
// delay1ms();
LCD1602_en = 1;//写入时序
delay1ms();
LCD1602_en = 0;

Data_U8=Data_U8 << 4;//低4位移入高4位
LCD_DATA &=0X0f;      //清高四位
LCD_DATA |= Data_U8&0xf0; //写入低四位
// delay1ms();
LCD1602_en = 1;//写入时序
delay1ms();
LCD1602_en = 0;

}
#endif
/***********************************************************
对控制器读写前,执行读/写检测,确保STA7为0 即读写操作使能置0
检测LCD状态,看它是不是还在忙呢
根据规定,RS为低电平,RW为高电平时,可以读状态
***********************************************************/
#ifndefLCD1602_4PINS
void lcd_check()
{
while(1)
{   
   LCD1602_en=0;
   LCD1602_RS=0;   //选择读状态
   LCD1602_rw=1;   //读数据状态,RW为1
LCD_DATA=0xff;//数据口的所有引脚都拉高
delay1ms();
LCD1602_en=1;   //E=1,才允许读写
   if(!LCD_BUSY)break;//若状态字STA的最高位为0,按位与运算后,跳出while
}
   LCD1602_en=0;      //读完了要关闭使能,防止液晶输出数据干扰总线
}
#endif
/**LCD1602的显示部分操作**/
void lcd_display(uchar x,uchar y,uchar *db)// //输出一个字符串到LCD的指定坐标
{
uchar adr;//字符显示的地址
if(y==0)    //若显示在第1行      
{
   adr=x;
}
else      //显示在第2行
{
   adr=0x40+x;
}
   lcd_write_CMD(adr|0x80);   //设置数据地址指针,显示位置的确定方法规定为"80H+地址码adr"
   while(*db!='\0')            //只要没有写到字符串结束标志,就继续写
   {
   lcd_write_data(*db++);   //逐个显示字符串
   }
}
/***** LCD清屏******/
#ifndefLCD1602_4PINS //若没有宏定义LCD1602_4PINS,就执行LCD_cls();否则跳过
void LCD_cls(void)         
{
lcd_check();
LCD1602_RS=0;
LCD1602_rw=0;
LCD_DATA=0xff;//数据口的所有引脚都拉高
LCD1602_en=1;
LCD1602_en=0;
lcd_write_CMD(0x01); //显示清0,数据指针清0 清屏
}
#endif
/*****************************************************
函数功能:延时
***************************************************/
void delay1ms()
{
   unsigned char i,j;
for(i=0;i<5;i++)
   for(j=0;j<2;j++)
    ;   
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(unsigned char n)
{
   unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}



页: [1]
查看完整版本: 1602的lcd_write_command(0x80+0x40);这句程序不起作用是怎么回事?