打印

[原创]液晶画面滚动起来!(含原理图)

[复制链接]
6302|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ahai0306|  楼主 | 2008-4-28 22:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以前的**写过1602液晶的显示程序,现在将液晶显示的画面移动起来,其实很简单,大家实验!(本实验经过本博客开发板实验)

/*
***************************************************************************
*     (C) Copyright 2007,单片机初学者园地
*                          All Rights reserved.
*项目名称:    51单片机学习开发系统           
*本文件名称:LCD1602.c   
* 完成作者 : 单片机初学者 QQ:50501160   ahai0306@sina.com
* 当前版本 : V1.0        
* 完成日期 : 2007年4月3日
* 描    述 :  
*                此程序实现,完成液晶的驱动程序,可以显示任意的ASCII字符
*             
*  我的博客:http://blog.**/ahai0306/
*  开发板介绍:http://blog.**/ahai0306/84416/message.aspx
*  淘宝网店铺地址:http://shop35284066.taobao.com/
*  我的论坛:http://dianzi.5d6d.com/?fromuser=mcu_51           
****************************************************************************
*/
#include  <reg52.h>     //调用头文件(单片机内部的寄存器定义)

/******本段为硬件I/O口定义********/
sbit  KEY0   = P0 ^ 0;  //KEY和发光管复用,请将跳线插到KEY端
sbit  KEY1   = P0 ^ 1;
sbit  KEY2   = P0 ^ 2;
sbit  KEY3   = P0 ^ 3;
sbit  DIG0   = P0 ^ 4;  //数码管位0
sbit  DIG1   = P0 ^ 5;  //数码管位1

sbit  BUZZ   = P3 ^ 3;  //蜂鸣器
sbit  LCD_RW = P3 ^ 6;  
sbit  LCD_RS = P3 ^ 7;  
sbit  LCD_E  = P3 ^ 4;

#define  LED_SEG    P1  //数码管
#define  LCD_DATA   P2   //LCD DATA
#define  LCD_BUSY   0x80  // 用于检测LCD的BUSY标识(本程序中用的延时,未检测)
//LCD显示内容,定义到代码段
 unsigned  char code LcdBuf1[]= {"welcom!"};
unsigned  char code LcdBuf2[]= {"MCU-STUDY-BOARD"};

//函数声明
void  lcd_init(void);
void  display_string(unsigned  char x,unsigned  char y,unsigned  char *s);
void  disp_selec(unsigned  char bit_selec,unsigned  char  seg);

void  WriteCommandLcd(unsigned  char wdata);


 /**************************************************
** 函数名称: dellay
** 入口参数:h(unsigned int型)
** 出口参数:无
** 功能描述: 短暂延时,使用11.0592晶体,约0.01MS
****************************************************/
void dellay(unsigned int  h)
{
  while(h--);    //0.01MS
}


/************主程序**************/
main()

    lcd_init();
 display_string(3,0,LcdBuf1);  //显示第一行,从第3个位置开始
 display_string(0,1,LcdBuf2);  //显示第二行,从第0个位置开始
 
   while(1)    //单片机待机
   { 

    dellay(23000);            //滚动的延时时间
   WriteCommandLcd(0x18);   //画面向左移动1位

    //WriteCommandLcd(0x1c);   //画面向右移动1位

    }



/**************************************************
** 函数名称: WriteDataLcd
** 入口参数:wdata(unsigned  char型)
** 出口参数:无
** 功能描述: 写数据到LCD
****************************************************/
void  WriteDataLcd(unsigned  char wdata)
{
   LCD_DATA=wdata;
   LCD_RS=1;
   LCD_RW=0;
   LCD_E=0;
   dellay(100);     //短暂延时,代替检测忙状态

   LCD_E=1;
}
/**************************************************
** 函数名称: WriteCommandLcd
** 入口参数:wdata(unsigned  char型)
** 出口参数:无
** 功能描述: 写命令到LCD
****************************************************/
void  WriteCommandLcd(unsigned  char wdata)
{
   LCD_DATA=wdata;
   LCD_RS=0;
   LCD_RW=0;
   LCD_E=0;
   dellay(100);      //短暂延时,代替检测忙状态
   LCD_E=1;
}

//LCD初始化
void  lcd_init(void)
{
     LCD_DATA=0;
     WriteCommandLcd(0x38);
     dellay(1000);
     WriteCommandLcd(0x38); //显示模式设置
    WriteCommandLcd(0x08); //关闭显示
    WriteCommandLcd(0x01); //显示清屏
    WriteCommandLcd(0x06); //显示光标移动设置
    WriteCommandLcd(0x0c); //显示开及光标移动设置
}
/**************************************************
** 函数名称: display_xy
** 入口参数:x(unsigned  char型),y(unsigned  char型)
** 出口参数:无
** 功能描述: 设置光标位置, x是列号,y是行号
****************************************************/
void  display_xy(unsigned  char x,unsigned  char y)

    if(y==1)
   x+=0x40;
  x+=0x80;
  WriteCommandLcd(x);
}
/********************************************************************
** 函数名称: display_char
** 入口参数:x(unsigned  char型),y(unsigned  char型),dat(unsigned  char型)
** 出口参数:无
** 功能描述: 在具体位置显示单个字符,x是列号,y是行号
*********************************************************************/
void  display_char(unsigned  char x,unsigned  char y,unsigned  char dat)
{
  display_xy(x,y);
  WriteDataLcd(dat);
}

/*********************************************************************
** 函数名称: display_string
** 入口参数:x(unsigned  char型),y(unsigned  char型),s(指针型)
** 出口参数:无
** 功能描述: 在具体位置显示字符串,以/0结束,x是列号,y是行号
**********************************************************************/
void  display_string(unsigned  char x,unsigned  char y,unsigned  char *s)
{
  display_xy(x,y);
  while(*s)
  {
   WriteDataLcd(*s);
   s++;
  }
}

增加硬件原理图:

相关链接:http://blog.**/ahai0306/

相关帖子

沙发
古道热肠| | 2008-4-29 10:52 | 只看该作者

函数描述写得还算详细,谢谢发表

使用特权

评论回复
板凳
yysmcu| | 2008-4-30 16:08 | 只看该作者

值得学习

使用特权

评论回复
地板
hotpower| | 2008-5-1 22:49 | 只看该作者

好象LCD_E时序有问题,虽然楼主的程序可能运行通过

实际1602和12864/12832/19232/...等时序都是一样的.
LCD_E实际是高电平有效的片选信号.
用movx指令如何实现???
   LCD_DATA=wdata;
   LCD_E=0;
   dellay(100);      //短暂延时,代替检测忙状态
   LCD_E=1;
???
实际为:
   LCD_E=1;
   LCD_DATA=wdata;
   LCD_E=0;
   dellay(72);      //短暂延时,代替检测忙状态

相关链接:https://bbs.21ic.com/club/bbs/ShowAnnounce.asp?id=2786376

使用特权

评论回复
5
ahai0306|  楼主 | 2008-5-1 23:39 | 只看该作者

楼上的好仔细,我也来仔细一下

我又看了一下时序图,请看一下,比较一下,12864和1602的区别就在这里
先看1602的时序图:


使用特权

评论回复
6
ahai0306|  楼主 | 2008-5-1 23:40 | 只看该作者

再看12864的

再看12864的:

使用特权

评论回复
7
ahai0306|  楼主 | 2008-5-1 23:43 | 只看该作者

再看我的12864函数

//向液晶发送数据
void SendLcdData (uint8 dat)
{
 NOP;NOP;
 while(CheckBusy());
 RS=1;
  RW=0;
  P2=dat;
  EN=1;
  NOP;NOP;
  EN=0;
}
原文:[原创]字库12864液晶ST7920驱动C文件!(含原理图)
http://blog.**/ahai0306/111182/message.aspx

相关链接:http://blog.**/ahai0306/111182/message.aspx

使用特权

评论回复
8
hotpower| | 2008-5-2 00:15 | 只看该作者

哈哈~~~时序图很明白~~~楼主的是模拟IO的思路~~~

  P2=dat;
  EN=1;
  NOP;NOP;
  EN=0;
???
实际应该为:
  EN=1;
  P2=dat;
  NOP;NOP;
  EN=0;

虽然楼上的程序没问题~~~因为P2的数据是"锁存"过的静态数据.
如果是"动态"的,结果该怎样???

相关链接:http://www.google.cn/search?hl=zh-CN&q=lcd+hotpower&meta=&aq=f

使用特权

评论回复
9
ahai0306|  楼主 | 2008-5-2 09:20 | 只看该作者

没明白楼上的意思

请教怎么样的‘动态’,请细讲一下

使用特权

评论回复
10
McuPlayer| | 2008-5-2 12:06 | 只看该作者

老Hot说的是IO和Bus

其实抓数据是靠的E的边沿,然后所有问题就清了

使用特权

评论回复
11
ahai0306|  楼主 | 2008-5-2 14:06 | 只看该作者

我理解边沿所存数据,

P2=dat;
  EN=1;
  NOP;NOP;
  EN=0;
???
实际应该为:
  EN=1;
  P2=dat;
  NOP;NOP;
  EN=0;

对于这个的区别,麻烦用总线的理论再讲一下,学习一下!

使用特权

评论回复
12
huangqi412| | 2008-5-2 14:38 | 只看该作者

看看

使用特权

评论回复
13
ahai0306|  楼主 | 2008-5-3 10:21 | 只看该作者

还没讨论完呢

在交流一下啊

使用特权

评论回复
14
hotpower| | 2008-5-3 11:13 | 只看该作者

能用即可,只是随便说说~~~

再厂家一般建议LCD的VCC/VDD即2脚应该在4.2V左右,一般提高5V串接一般二极管.

使用特权

评论回复
15
hwu81| | 2008-5-5 17:19 | 只看该作者

帖子的参考意义一般啊

    楼主采用的是16*2的字符型液晶显示屏吧?市场上该类型的LCD一般都支持光标闪烁、光标移动和显示画面滚动等功能,有对应的控制指令,LCD的生产厂商都可以提供驱动例程供参考。相反的,带光标控制功能或显示画面滚动功能的图形点阵液晶显示屏产品不多,厂商一般也没有提供相应的驱动,需要用户自己开发对应的功能程序。楼主若是能提供这些功能的实现例程,实用价值也许会更大些。

使用特权

评论回复
16
hotpower| | 2008-5-6 01:27 | 只看该作者

哈哈~~~鼓励原创~~~

使用特权

评论回复
17
ahai0306|  楼主 | 2008-5-8 12:26 | 只看该作者

次此帖对于高手来说,没有什么参考意义

回17楼:
对于刚玩单片机的初学者来说可是意义重大!
点阵的可以考虑
相关链接:http://blog.**/ahai0306

使用特权

评论回复
18
gyt| | 2008-5-8 15:01 | 只看该作者

挺好

使用特权

评论回复
19
ahai0306|  楼主 | 2008-5-8 16:53 | 只看该作者

配套的电路图中出现一个小小遗漏

此遗漏对液晶显示没有任何影响的,此功能是备用的,结果出了点问题,
大家找找,看哪里出现了问题啊?


51初学者看看我的博客:
里面有学习资料,廉价开发板!
http://blog.**/ahai0306/
相关链接:http://blog.**/ahai0306/

使用特权

评论回复
20
wjcy131421| | 2008-5-9 16:13 | 只看该作者

学习 ~!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

158

帖子

1

粉丝