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的中文资料:
驱动程序如下:
#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);
}
}
}
/******************************************************************************/
用户485338 2009-8-17 17:11
用户485338 2009-8-17 17:11
用户543467 2009-5-21 21:59
用户197994 2009-3-26 19:24