lhy_radio的笔记 https://bbs.21ic.com/?319974 [收藏] [复制] [RSS]

日志

终于搞定LCD1620……

已有 1608 次阅读2008-4-28 21:51 |个人分类:单片机学习|系统分类:单片机

这个头文件,搞了好久都没成功!都快到心灰意冷的边缘了,突然灵光一闪:会不会是mega8的Flash不行了?这片mega8陪伴了我好几年,也应该退休了。抱着试试看的想法换了一片新的mega8,一切ok!自己觉得奇怪,之前在烧程序时,并没有报错啊?

调试过程总结一下:
1)由于找不到的1620资料,不知道它的操作时序。看到一些帖子说
16201602没区别,还是有点将信将疑。后面用网友编写的1602程序试验,才知道它们俩没啥区别。
2)关于是否检测LCD处于空闲,觉得还是最好在写指令和写数据时都加上。不检测,会导致显示结果不正常。
3)由于连线很多14根(加上背光就是16根),如果有一根除了问题就会影响到显示。所以我是用万用表一根线一根线量了之后才通电试验的。
4)看到很多帖子都建议在初始化LCD前延时几十毫秒。本例中并没有延时,显示也正常。
5)总的说来,不是很难。在遇到问题时只要能够仔细分析,就能找出原因和解决方法。自己前几天在试程序时就是显示结果不对,一直在检查自己的程序,没想到原来是单片机的Flash到寿命了……那个郁闷啊…………

头文件中有五个函数:


1.unsigned char AskBusy(void)          询问LCD1620是否空闲, 返回值"1"空闲, "0"为忙;
2.WriteData(char data)                        写数据到LCD1620;
3.WriteCommand(char command)     写指令到LCD1620;                         
4.PutOneCharLCD(x,y,*Disp)             在LCD1620上显示一个字符, x,y定义位置
5.PutStringLCD(a,b,*DispString)      
在LCD1620上显示一个字符串,
a,b定义初始位置.
                                                                                       
6.LCD_Init()                                           初始化LCD


在使用此头文件之前,必须有以下宏定义:


#define DataPortPullup PORTx                
#define DataPortDirection DDRx            
#define
ReadLCDPin PINx                      
                                                                                                

#define CtrlPortPullup PORTx                  

#define CtrlPortDirection DDRx               
#define RS_Bit Px?                           
#define RW_Bit Px?                            
#define E_Bit Px? 

其中“x”代表B,C,D(mega8中无A口),"?"代表“0~1”

完整头文件如下(解释搞了一大堆,也学学用英语……):

/*******************************************************/
/*     Project     :1620 Display Headfile              */
/*     Date        :2008,3,11                          */
/*     Author      :lhy                                */
/*     Version     :v1.1                               */
/*     Rework      :lhy                                */
/*     Rework Date :2008.4.28                          */
/*                                                     */
/*     Comments    :                                   */
/*     1  Deion                          */
/*         1.unsigned char AskBusy(void)       */
/*           --Calls this Fun to ask if LCD is busy,   */
/*           1--free,0--busy;                          */
/*         2.WriteData(char data)              */
/*           --Write data to LCD                       */
/*         3.WriteCommand(char command)        */
/*           --write command to LCD                    */
/*         4.PutOneCharLCD(x,y,*Disp)          */
/*           --Put one char to LCD.                    */
/*         5.PutStringLCD(a,b,*DispString)     */
/*           --Put String to LCD. Max length 32bits.   */
/*                                                     */
/*     2 How to use                                    */
/*         Before use this HeadFile,                   */
/*       need to define as below:                      */
/*         #define DataPortPullup PORTx                */
/*         #define DataPortDirection DDRx              */
/*         #define ReadLCDPin PINx                     */
/*         #define CtrlPortPullup PORTx                */
/*         #define CtrlPortDirection DDRx              */
/*         #define RS_Bit Px?                          */
/*         #define RW_Bit Px?                          */
/*         #define E_Bit Px?                           */
/*             'x' -> A,B,C,D...                       */
/*             '?' -> 0,1,2,3,4,5,6,7                  */
/*         And set control port output,like this:      */
/*         CtrlPortDirection |=                        */
/*             (1<<E_Bit) | (1<<RS_Bit) | (1<<RW_Bit); */
/*     3 Add the  "LCD_Init(void)"             */
/*         Before this Fun, you must set control port  */
/*       output.                                       */
/*******************************************************/

#ifndef _LCD1620_h
#define _LCD1620_h

//Calls this Fun to ask if LCD is busy,1--free,0--busy
unsigned char AskBusy(void)
{
  DataPortDirection = 0x00;
  DataPortPullup = 0xff;//enable pullup res
  CtrlPortPullup |= (1<<RW_Bit);//Set RW
  CtrlPortPullup &= ~(1<<RS_Bit);//Clear RS
  CtrlPortPullup |= (1<<E_Bit);//set enable pin
  if((ReadLCDPin & (1<<7))==0)
    return 1;//lcd is free
  else
    return 0;//lcd is busy
}

//wait until LCD was free
void WaitForFree(void)
{
  unsigned char BusyBit;
  do
   {
   BusyBit = AskBusy();
   }
  while(BusyBit !=1);
  CtrlPortPullup &= (~1<<E_Bit);//Clear enable pin
}

//Write data to LCD
void WriteData(char data)
{
  WaitForFree();
  CtrlPortPullup &= ~(1<<RW_Bit);//Clear RW
  CtrlPortPullup |= (1<<RS_Bit);//Set RS
 
  DataPortDirection = 0xff;
  DataPortPullup = data;
  CtrlPortPullup |= (1<<E_Bit);//set E
  CtrlPortPullup &= ~(1<<E_Bit);//Clear E
}

//write command to LCD
void WriteCommand(char command)
{
  WaitForFree();
  CtrlPortPullup &= ~(1<<RS_Bit);//Clear RS
  CtrlPortPullup &= ~(1<<RW_Bit);//Clear RW
  DataPortDirection |= 0xff;
  DataPortPullup = command;
 
  CtrlPortPullup |= (1<<E_Bit);//set E
  CtrlPortPullup &= ~(1<<E_Bit);//Clear E
}

//Write one char to LCD.
void PutOneCharLCD(unsigned char x,unsigned char y,unsigned char *Disp)
{
  unsigned char Location;
  if(x == 0)
    {
    Location = y | (1<<7);
    }
  else if(x == 1)
    {
    Location = y | (1<<6) |(1<<7);
    }
  WriteCommand(Location);
  WriteData(*Disp);
}

//Write String to LCD. Max length 32bits(determined by the location of the first byte).
void PutStringLCD(unsigned char a,unsigned char b,unsigned char *DispString)
{
  do
    {
    PutOneCharLCD(a,b,DispString);
    b ++;
    DispString ++;
    }
  while((b <= 15) && (*DispString));
 
  if(*DispString)
    {
    a ++;//Jump to 2nd row.
    b = 0;
    do
      {
      PutOneCharLCD(a,b,DispString);
      b ++;
      DispString ++;
      }
    while((b <= 15) && (*DispString));
    }
}

//Initialize the LCD1620
void LCD_Init(void)
{
  WriteCommand(0x38);//16X2,5X7 lattice,8 bit for transmit
  WriteCommand(0x08);//Close the display and cursor
  WriteCommand(0x0f);//Set cursor and enable dispaly
  WriteCommand(0x06);
  WriteCommand(0x01);//Clear the screen
}

#endif

把此头文件包含到主程序中:

/*******************************************************/
/*     Project   :1620 Display                 */
/*     Compiler  :ICCAVR 6.03A                         */
/*     Date      :2008,4,28                           */
/*     Author    :lhy                                  */
/*     Chip type :Atmega8                              */
/*     Comments  :                                     */
/*******************************************************/

#i nclude "iom8v.h"

#define DataPortPullup PORTD
#define DataPortDirection DDRD
#define ReadLCDPin PIND
#define CtrlPortPullup PORTC
#define CtrlPortDirection DDRC
#define RS_Bit PC0
#define RW_Bit PC1
#define E_Bit PC2

#i nclude "LCD1620.h"

void main()
{
  OSCCAL=0XA5;
  CtrlPortDirection |= ((1<<E_Bit)|(1<<RS_Bit)|(1<<RW_Bit));
  LCD_Init();
  PutStringLCD(0,0,"Li Heng Yuan is a good boy!!");
}

就可以显示了!!    

  

来个全景:

两张都是用手机拍的,效果有点差~~~~~


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (2 个评论)

回复 lhy_radio 2008-4-28 21:56
CtrlPortDirection |= ((1<
回复 D 2009-8-13 07:08
你很强啊