"); //-->
一、1602管脚说明
1.Vss 电源地 ;
2.Vdd 电源正极 4.5~5.5V 通常使用5V;
3.Vl 对比度调节 电源调节范围0~5V。接正电源时对比度最弱,接地对比度最高,但是对比度过高时产生“鬼影”,因此通常使用一个10K电位器来调整对比度,或者直接接一个电阻到地;
4.Rs 数据/命令选择 高电平选择数据寄存器,低电平选择指令寄存器;
5.R/W 读/写选择 高电平读取数据,低电平写入数据;
6.E 模块使能端 写数据需要下降沿触发模块;
7~14.D0~D7 三态双向数据口 MCU I/O口资源紧张可以使用4位数据线D4~D7接口传送数据;
15.Blk 背光源地
16.Bla 背光源正极 需要背光串接一个限流电阻接Vdd,blk接地,实测该模块背光电流50mA左右。
二、试验接法
Vdd、Bla -- Vcc
Vss、Vl、Blk -- Gnd
Rs -- Pd0
R/W -- Pd1
E -- Pd2
D1~D7 -- Pb0~Pb7
三、测试程序
/*************************************************
LCD演示程序(ICCAVR)
学习 AVR单片机的LCD显示
MUC: ATMEGA16
D0~D7: PB0~PB7
RS--PD0
R/W--PD1
E--PD2
CLOCK: 8MHz
*************************************************/
#include <iom16v.h>
#define XTAL 8
#define RS 0
#define RW 1
#define E 2
#define lcd_data_port PORTB
#define lcd_data_dir DDRB
#define lcd_data_pin PINB
#define lcd_ctrl_port PORTD
#define lcd_ctrl_dir DDRD
#define lcd_ctrl_pin PIND
#define delay() delay_us(80)
#define set_bit(x,y) (x|=(1<<y))
#define clr_bit(x,y) (x&=~(1<<y))
#define get_bit(x,y) (x&(1<<y))
#define WDR() asm("wdr") // Watchdog_Reset()
#define SEI() asm("sei") // Enable_Interrupt()
#define CLI() asm("cli") // Disable_Interrupt()
#define NOP() asm("nop") // Null_Operation()
#define SLEEP() asm("sleep") // Enter_Sleepmode()
//微秒级延时程序
void delay_us(int time)
{
unsigned int i=1;
do
{
time--;
while(i!=0)
{
i--;
}
i=1;
}
while (time>1);
}
// 毫秒级延时程序
void delay_ms(unsigned int time)
{
while(time!=0)
{
delay_us(1000);
time--;
}
}
void lcd_port_init(void)
{
lcd_data_dir=0; //设置数据输入模式
lcd_data_port=0; //初始化数据
lcd_ctrl_dir|=(1<<RS)|(1<<RW)|(1<<E); //设置控制信号输出模式
lcd_ctrl_port|=(1<<RS)|(1<<RW)|(1<<E); //设置控制信号高电平
}
/*****************************************************
LCD初始化函数
******************************************************/
const unsigned char init_tabel[]={0x38,0x0c,0x01,0x06};
void lcd_init(void)
{
unsigned char i;
lcd_port_init();
for(i=0;i<4;i++)
{
write_lcd(init_tabel[i],0);
}
}
/************************************************
从LCD读取数据或地址
data_type:数据类型
1表示数据,0表示指令
************************************************/
unsigned char read_lcd(unsigned char data_type)
{
unsigned char i;
lcd_data_dir=0;
lcd_data_port=0; //设置为输入
if (data_type==0) //根据数据类型选择命令写与数据写
clr_bit(lcd_ctrl_port,RS); //RS=0
else
set_bit(lcd_ctrl_port,RS); //RS=1
set_bit(lcd_ctrl_port,RW); //R/W=1,读LCD状态
set_bit(lcd_ctrl_port,E); //E=1
delay(); //延时80us
i=lcd_data_pin&0x7f ; //i=PINB&0x7f ;
clr_bit(lcd_ctrl_port,E); //E=0
delay(); //延时80us
return i;
}
/***********************************************
写数据或指令到LCD
data:数据或指令字节
data_type:数据类型
1表示数据,0表示指令
***********************************************/
void write_lcd(unsigned char data,unsigned char data_type)
{
lcd_data_dir=0; //
lcd_data_port=0; //设置输入
clr_bit(lcd_ctrl_port,RS); //RS=0
set_bit(lcd_ctrl_port,RW); //R/W=1,读LCD状态
set_bit(lcd_ctrl_port,E); //E=1
delay(); //延时80us
while ((lcd_data_pin&0x80)==0x80);//检查LCD是否空闲
clr_bit(lcd_ctrl_port,E); //E=0
if (data_type==0) //根据数据类型选择命令写与数据写
clr_bit(lcd_ctrl_port,RS); //RS=0
else
set_bit(lcd_ctrl_port,RS); //RS=1
clr_bit(lcd_ctrl_port,RW); //R/W=0,写入LCD
lcd_data_dir=0xff; //
lcd_data_port=data; //写出数据
set_bit(lcd_ctrl_port,E); //E=1
delay();
clr_bit(lcd_ctrl_port,E); //E=0
delay();
lcd_data_dir=0; //
lcd_data_port=0; //
}
/*********************************
清除LCD显示函数
*********************************/
void lcd_clear(void)
{
write_lcd(0x01,0);
}
/*****************************************************
将光标转移到DDRAM指定位置处
x:0~39,y:0~1
*****************************************************/
void lcd_gotoxy(unsigned char x,unsigned char y)
{
unsigned char adder;
if (y==1)
adder=0xc0+x;// 定位 1602 第二行
else
adder=0x80+x;// 定位 1602 第一行
write_lcd(adder,0);
}
/*********************************
单字符输出函数
*********************************/
void lcd_putc(char c)
{
if (c == '\n')
if (read_lcd(0)>15) //如果当前位置已在第二行,
write_lcd(02,0); //则从0开始
else
write_lcd(0xc0,0); //换行
else
write_lcd(c,1); //写字符到LCD
}
/*********************************
字符串输出函数
*********************************/
void lcd_puts(char *s)
{
while (*s)
lcd_putc(*s++);
}
void lcd_puts_P(char const *s)
{
while (*s)
lcd_putc(*s++);
}
//void lcd_puts_P(char __flash *s)
// {
// while (*s)
// lcd_putc(*s++);
// }
/*****************************************************
从指定DDRAM/CGRAM位置读取数据
*****************************************************/
unsigned char lcd_read(unsigned char adder)
{
write_lcd(adder,0);
return read_lcd(1);
}
/************************************************
LCD字符移位函数
n:移动的次数
p:移动方向,'l'或'L'表示左移,'r'或'R'表示右移
*************************************************/
void lcd_shift(unsigned char n,unsigned char p)
{
unsigned char i,j=1;
switch (p)
{
case 'r':i=0x1c;break;
case 'R':i=0x1c;break;
case 'l':i=0x18;break;
case 'L':i=0x18;break;
default:return;
}
while (j<=n)
{
j++;
write_lcd(i,0);
}
}
/*****************************************************
写数据到指定DDRAM/CGRAM位置
*****************************************************/
void lcd_write(unsigned char adder,unsigned char data)
{
write_lcd(02,0);
write_lcd(adder,0);
write_lcd(data,1);
}
/*****************************************************
写数据到DDRAM当前位置
*****************************************************/
void lcd_write_data(unsigned char data)
{
write_lcd(read_lcd(0)|0x80,0);
write_lcd(data,1);
write_lcd((read_lcd(0)-1)|0x80,0);
}
void main(void)
{
MCUCR=0;
lcd_init();
while(1)
{
lcd_gotoxy(2,0);
lcd_puts("TEL:");
lcd_gotoxy(2,1);
lcd_puts("who am i ?");
delay_ms(1000);
lcd_clear();
lcd_gotoxy(1,0);
lcd_puts("http://www.");
lcd_gotoxy(1,1);
lcd_puts("xingyan.com.cn");
delay_ms(1000);
lcd_clear();
}
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。