原创 LCD1602 4线并口通信源程序

2007-11-15 16:30 3856 7 8 分类: MCU/ 嵌入式

 


终于搞定了这个程序,哈哈


/****************************************************************/                                                                            
/*  LCD1602 4线并口通信源程序  EDN51实验板实验成功                                                
/*  显示内容 cat_li's blog                      
/*     QQ 15942526
/* 连接方式:   DB4-DB7接P0.4-P0.7;
/*    RS:P1.0;
/*    RW:P1.1;
/*    EN:P1.2;
/*  作者: 好心情
/*  Date: 2007-11-15                                          
/****************************************************************/  
#include <reg51.h>
#define unchar unsigned char  //unchar 定义一下方便使用
/****************************************************************/
#define  LCD_IO P0    //DB4-DB7接P0.4-P0.7
 
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;  
sbit LCD_EN=P1^2; 
/****************************************************************/
void lcd_check_BF(void);   //读状态,忙检测 
void lcd_en_command(unchar command,bit bcheck); // 写指令
void lcd_en(void); //写使能,产生高脉冲,写入数据
void lcd_en_dat(unchar dat,bit bcheck);  //写数据
void lcd_set_add( unchar x, unchar y );  //设定地址
void lcd_write_char( unchar x,unchar y,unchar dat); //写字符
void lcd_write_string(unchar X,unchar Y,unchar *s); //写字符串
void lcd_init(void); //初始化
void delay_nms(unsigned int n);


/*************************LCD PART*******************************/



/***********************读状态忙检测*****************************/
/* 忙检测,无返回值 RS选指令寄存器,RW置为读状态,EN高电平读指令 */
/****************************************************************/
void check_BF(void)
{
 unchar read;
 LCD_RS = 0;
 LCD_RW = 1;
 LCD_IO = 0xff; // 将LCD_IO置为读状态
 LCD_EN = 1; 
 do
 {     
  read = LCD_IO ; 


 }while(read & 0x80); //如果BF位为1则继续读,否则退出
  LCD_EN = 0;   
}


/****************************写使能******************************/
/* 写使能,在EN脚产生高脉冲
/****************************************************************/
void lcd_en(void)
{
 LCD_EN=1;     
   LCD_EN=0; 
}



/****************************写指令******************************/
/* 写指令,RS=0选指令寄存器,RW=0选写模式,bcheck判断是否忙检测
/****************************************************************/ 
void LCD_en_command(unchar command,bit bcheck)
{  
   if(bcheck)  //根据bcheck判断是否忙检测
 {
  check_BF();
 }


   LCD_RS=0;  
   LCD_RW=0; 
 LCD_IO = (command & 0xf0);  // 写指令的高4位 
   lcd_en();
  
 LCD_IO = (command & 0x0f)<<4;//写指令的第四位   
   lcd_en();
}



/****************************写数据******************************/
/* 写数据,RS=1选数据寄存器,RW=0写模式
/****************************************************************/
void LCD_en_dat(unchar dat,bit bcheck)
{   
   if(bcheck)
 {
  check_BF();
 }


 LCD_RS=1;    // 设置写模式和数据寄存器
 LCD_RW=0;


 LCD_IO = (dat & 0xf0);  //高四位
 lcd_en();
 
 LCD_IO = (dat & 0x0f)<<4;//第四位
   lcd_en();
}



/****************************地址设置****************************/
/* 地址设置 x="0" 第一行 x="1" 第二行;y 设置每行从首地址开始的偏移量
/****************************************************************/
void LCD_set_add( unchar x, unchar y )
{
   unchar address;
   if (x ==0)
   {
     address = 0x80 + y;
   }
   else
 {
       address = 0xC0 + y;
 }
   lcd_en_command(address,1);
}


/*****************************写字符*****************************/
/* 写字符 x y 为字符的位置地址,dat为要写入的字符
/****************************************************************/
void lcd_write_char( unchar x,unchar y,unchar dat)
{
   lcd_set_add(x,y);  // 设置地址
   lcd_en_dat(dat,1); // 写数据
}



/****************************写字符串****************************/
/* 写字符串 x y 为字符的位置地址,*s为要写入的字符串的首地址
/****************************************************************/
void lcd_write_string(unchar X,unchar Y,unchar *s)
{
    lcd_set_add( X,Y );  // 设置地址
    /* 字符串最后一位为自动加入的"\n",对应的ASCII值为0,其他为非零
 在这里利用s指向的内容值判断字符串是否结束*/
 while (*s)        
    {       
       lcd_en_dat(*s,1);  
     s ++; //指向下一个字符地址
    }
}
/*****************************初始化******************************/
void lcd_init(void)
{   
 delay_nms(15); 
   lcd_en_command(0x28,0);
   delay_nms(5);   
   lcd_en_command(0x28,0);
   delay_nms(5);
   lcd_en_command(0x28,0);
   delay_nms(5);
   lcd_en_command(0x28,1);   
   lcd_en_command(0x08,1); //关显示
 lcd_en_command(0x01,1); //清屏     
   lcd_en_command(0x0C,1); //开显示光标设置
   
}
/******************************延时*******************************/
void delay_nms(unsigned int n)     
{
    unsigned int i="0",j=0;
    for (i=n;i>0;i--)
     for (j=0;j<1140;j++); 
}
/*****************************************************************/



/*****************************************************************/


 


/*****************************************************************/
void main(void)
{
  lcd_init();
  while(1 )   
  {
    lcd_en_command(0x01,1);
 delay_nms(120);
   
    lcd_write_string(0,1,"cat_li's  blog");
    lcd_write_string(1,2,"QQ 15942526");
    delay_nms(120);         
  }
}

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户523749 2010-6-27 13:12

I LOVE THIS LABVIEW ALL SERIES

lg05128018_230568758 2007-12-3 16:18

好啊

相关推荐阅读
用户42640 2012-03-28 09:28
评论:@小野兽的小草窝 博客中提到的“【博客 大赛】虚焊,你伤不起~~”
这个确实很重要,不起眼的问题会折腾人很久 ...
用户42640 2010-11-05 14:14
怎样用Realview MDK生成bin文件?
怎样用Realview MDK生成bin文件?       使用RVCT的fromelf.exe工具进行转换。也就是说首先将源文件编译链接成*.axf的文件,然后使用fromelf.exe工具将*....
用户42640 2010-10-28 21:35
新塘M051中文技术参考手册
  今天无意中在网上看到的,这个要比研讨会上光盘上提供的那个中文版详细很多,看了一下,就是英文手册的完整翻译版 需要的朋友可以到这里下载:http://www.wang1jin.com/bbs/vie...
用户42640 2010-10-26 16:50
保护三极管基础
这次出现的问题是使用了ULN2003,由于直接用它的输入级接入模块的输入端,因此出现了问题。 由于电缆上存在分布电感和分布电容,因此很容易出现耦合,在ISO7637的实验中,存在高频脉冲250V,20...
用户42640 2010-08-10 09:04
广岛无冤魂
1945年8月6日,美国的B-29“空中堡垒”轰炸机向日本广岛投下代号为”男孩”(Boy)的原子弹,实施了人类首次核轰炸。 总听到有些人(尤其是中国人)说,战争是日本军国主义者全面发动的,日本人民是受...
用户42640 2010-07-15 16:59
RT-Thread学习笔记--- 初步认识RT-Thread
最近对RT-Thread很感兴趣,准备学习一下,硬件使用安富莱开发板2.0。软件使用keil MDK   RT-Thread的目录结构 其中Bsp是针对各个具体的平台,可以认为是用户代码。为了方...
EE直播间
更多
我要评论
1
7
关闭 站长推荐上一条 /3 下一条