原创 基于STM32的1602 LCD驱动程序

2008-7-31 00:54 7620 11 12 分类: MCU/ 嵌入式

1602采用标准的16脚接口,其中:


1脚:VSS为地电源

第2脚:VDD接5V正电源

第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。


7~14脚:D0~D7为8位双向数据线。


15~16脚:空脚。


 


下面是LCD 1602的中文资料:


 


doc


 


驱动程序如下:


 


#include <stm32f10x_lib.h>            


#define DELAY_2N     0


/*------------------------- LED像素定义 ------------------------*/


#define LineLen     16                  /* 宽              */
#define NumLines     2                  /* 高                   */


                                                           */


#define PIN_E                 (   1 << 8)  //能使端,由高到低,则执行命令
#define PIN_RW                (   1 << 15)  //读写信号线
#define PIN_RS                (   1 << 7)  //寄存器选择



#define PINS_DATA             (0xF0 <<  0)  //数据接口


const unsigned int SWAP_DATA[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
                                        0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};


/* 外围LED时钟能使                              */
#define LCD_CLOCK_EN          RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE, ENABLE);


/* 设置能使脚为零或者一                                                  */
#define LCD_E(x)              GPIOA->ODR = (GPIOA->ODR & ~PIN_E)  | (x ? PIN_E : 0);


/* 设置RW脚为零或者一                                                    */
#define LCD_RW(x)             GPIOD->ODR = (GPIOD->ODR & ~PIN_RW) | (x ? PIN_RW : 0);


/* 设置RS脚为零或者一                                                    */
#define LCD_RS(x)             GPIOD->ODR = (GPIOD->ODR & ~PIN_RS) | (x ? PIN_RS : 0);


/* 读数据                                                          */
#define LCD_DATA_IN           SWAP_DATA[(((GPIOE->IDR & PINS_DATA) >> 8) & 0x0F)]


/* 写数据                                                */
#define LCD_DATA_OUT(x)       GPIOE->ODR = (GPIOE->ODR & ~PINS_DATA) | (((SWAP_DATA[x]) << 4));


/* IO口初始化                                            */
#define LCD_ALL_DIR_OUT       GPIOA->CRL = (GPIOA->CRL & 0xFFF00000) | 0x00033333; \
                              GPIOA->CRH = (GPIOA->CRH & 0xFFFF0000) | 0x00003333; \
         GPIOD->CRL = (GPIOD->CRL & 0x00000000) | 0x33333333; \
                              GPIOD->CRH = (GPIOD->CRH & 0x00000000) | 0x33333333; \
         GPIOE->CRL = (GPIOE->CRL & 0x00000000) | 0x33333333; \
                              GPIOE->CRH = (GPIOE->CRH & 0x00000000) | 0x33333333;


 #define LCD_DATA_DIR_IN       GPIOE->CRL = (GPIOE->CRL & 0x00000000) | 0x44444444;
 #define LCD_DATA_DIR_OUT      GPIOE->CRL = (GPIOE->CRL & 0x00000000) | 0x33333333;
/******************************************************************************/


const char UserFont[8][8] = {
  { 0x77,0x00,0x00,0x00,0x00,0x00,0x02,0x00 },
  { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 },
  { 0x18,0x18,0x18,0x18,0x23,0x18,0x18,0x18 },
  { 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C },
  { 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E },
  { 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F },
  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54 }
};


/*******************************************************************************
*      延时函数                                                                *
*   参数     :    cnt:    延时周期                                             *
*   无返回                                                                    *
*******************************************************************************/


static void delay (int cnt)
{
  cnt <<= DELAY_2N;


  while (cnt--);
}



/*******************************************************************************
*                     读LCD控制                                                *
*   参数       :      无                                                       *
*   返回       :                         忙信号和地址指针                      *
*******************************************************************************/


static unsigned char lcd_read_status (void)
{
  unsigned char status;


  LCD_DATA_DIR_IN
  LCD_RS(0)
  LCD_RW(1)
  delay(10);
  LCD_E(1)
  delay(10);
  status  = LCD_DATA_IN << 4;
  LCD_E(0)
  delay(10);
  LCD_E(1)
  delay(10);
  status |= LCD_DATA_IN;
  LCD_E(0)
  LCD_DATA_DIR_OUT
  return (status);
}


 


static unsigned char wait_while_busy (void)
{
  unsigned char status;


  do  {
    status = lcd_read_status();
  }  while (status & 0x80);             /* Wait for busy flag                 */


  return (status);
}



/*******************************************************************************
*                写LCD控制                                                     *
*   参数:    c:      写命令                                                    *
*   返回:         无                                                           *
*******************************************************************************/


void lcd_write_8bit (unsigned char c)
{
  LCD_RW(0)
  LCD_E(1)
  LCD_DATA_OUT(c&0x0F)
  delay(10);
  LCD_E(0)
  delay(10);
}



/*******************************************************************************
*                       写命令控制                                             *
*   参数:    c:      写控制                                 *
*   返回:      无                                                              *
*******************************************************************************/


void lcd_write_cmd (unsigned char c)
{
  wait_while_busy();


  LCD_RS(0)
  lcd_write_8bit (c>>8);
  lcd_write_8bit (c);
}



/*******************************************************************************
* Write data to LCD controller                                                 *
*   Parameter:    c:      data to be written                                   *
*   Return:                                                                    *
*******************************************************************************/


static void lcd_write_data (unsigned char c)
{
  wait_while_busy();


  LCD_RS(1)
  lcd_write_8bit (c>>8);
  lcd_write_8bit (c);
}



/*******************************************************************************
*          在当前光标处输入                                   *
*   参数:    c:      将被输出的字符                              *
*   返回:                                                                    *
*******************************************************************************/


void lcd_putchar (char c)
{
  lcd_write_data (c);
}



/*******************************************************************************
*          LCD初始化                                  *
*   参数:                                 *
*   返回:                                                                    *
*******************************************************************************/


void lcd_init (void)
{
  int i;
  char const *p;


  LCD_CLOCK_EN                       


  LCD_ALL_DIR_OUT


  delay (15000);
  LCD_RS(0)
  lcd_write_8bit (0x3);              
  delay (4100);
  lcd_write_8bit (0x3);
  delay (100);
  lcd_write_8bit (0x3);
  lcd_write_8bit (0x2);


  lcd_write_cmd (0x28);              
  lcd_write_cmd (0x0C);              
  lcd_write_cmd (0x06);              
  lcd_write_cmd(0x40);               
  p = &UserFont[0][0];
  for (i = 0; i < sizeof(UserFont); i++, p++)
    lcd_putchar (*p);


  lcd_write_cmd(0x80);                
}


 


/*******************************************************************************
* 设置在LCD显示上的光标位置                                     *
*   参数:    行上的位置:                                       *
*                 行:                                           *
*   返回:          无                                                          *
*******************************************************************************/


void set_cursor (int column, int line)
{
  unsigned char address;


  address = (line * 40) + column;
  address = 0x80 + (address & 0x7F);
  lcd_write_cmd(address);               /* Set DDRAM address counter to 0     */
}


/*******************************************************************************
*            清徐LCD显示                                                 *
*   Parameter:                                                                 *
*   Return:                                                                    *
*******************************************************************************/


void lcd_clear (void)
{
  lcd_write_cmd(0x01);                  /* Display clear                      */
  set_cursor (0, 0);
}



/*******************************************************************************
*             在LCD上显示字符串                                              *
*   参数:    string: 指向输出字符串                            *
*   返回:                                                                    *
*******************************************************************************/


void lcd_print (char *string)
{
  while (*string)  {
    lcd_putchar (*string++);
  }
}



/*******************************************************************************
*                       显示图案                                          *
*   参数:     pos_x: 水平起始点               *
*                  pos_y: 垂直位置                        *
*                  value: 图案有效大小            *
*   返回:                                                                    *
*******************************************************************************/


void lcd_bargraph (int pos_x, int pos_y, int value) {
  int i;


  set_cursor (pos_x, pos_y);
  for (i = 0; i < 16; i++)  {
    if (value > 5) {
      lcd_putchar (0x05);
      value -= 5;
    } else {
      lcd_putchar (value);
      while (i++ < 16) lcd_putchar (0);
    }
  }
}


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

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户485338 2009-8-17 17:11

找了半天只有这个能用

用户485338 2009-8-17 17:11

谢谢啦,用啥编的呀

用户543467 2009-5-21 21:59

main()在哪里啊?

用户197994 2009-3-26 19:24

你这个软件很好用啊 就是不能打开文件,如果能打开文本文件(3000个字节就可以了)发送的话就更好了。
相关推荐阅读
daiqiumiao_806246054 2011-01-06 13:57
linux下yum代理设置
    我们在安装好linux后,经常会使用yum来更新系统,但是系统默认的代理是国外的,国内一般的网络不能访问,这里讲解具体做法,把代理换成国内的。attachment download      ...
daiqiumiao_806246054 2010-12-30 09:48
【转】ORACLE 10g下载地址
Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Microsoft Windows (32-bit...
daiqiumiao_806246054 2010-11-29 11:06
找工作的进来看
如下是我所有的开放性问题回答,希望对大家有帮助!1.      When choosing your first job/employer, what will you consider and wh...
daiqiumiao_806246054 2010-11-29 09:47
中长期规划---螺旋式上升方式修改完善职业之路
一、中长期职业发展的自我准备1、心态上随时做好准备 机会是给有准备的人的------“有准备”是你在做准备的过程中让“别人”认为你“有准备”!别人是包括你现在的老板和别的老板,以及你身边的人!他们对你...
daiqiumiao_806246054 2010-03-17 21:26
移动
分集方式传输损耗和距离关系光纤网络G网...
daiqiumiao_806246054 2010-03-17 09:40
GSM
特点  使用直观  GSM系统有几项重要特点:防盗拷能力佳、网络容量大、手机号码资源丰富、通话清晰、稳定性强不易受干扰、信息灵敏、通话死角少、手机耗电量低。  技术特点  1.频谱效率。由于采用了高效...
EE直播间
更多
我要评论
1
11
关闭 站长推荐上一条 /3 下一条