|
楼主 |
发表于 2007-9-10 00:19:19
|
显示全部楼层
//lcd1602.h 头文件
//定义595与LCD的接口
#define LCD_RS 0x08 //595输出Q4
#define LCD_EN 0x04 //595输出Q5
#define LCD_DATA 0xf0 //595输出Q0 Q1 Q2 Q3
//定义595与MCU的接口
#define SER PORTB.0
#define SRCLK PORTB.4
#define RCLK PORTB.5
void LCD1602_init (void);
void LCD1602_en_write (void);
void LCD1602_clear (void);
void LCD1602_write_char (unsigned char command,unsigned char data);
void LCD1602_set_xy (unsigned char x, unsigned char y);
void LCD1602_write_string (unsigned char X,unsigned char Y,unsigned char *s);
void WriteSIOByte (unsigned char lcd,unsigned char relays);
#include <mega8.h>
#include <delay.h>
/**********************************************************
光标命令
LCD1602_write_char(1,0x0e); //光标开
LCD1602_write_char(1,0x0d); //光标所在字符闪烁
LCD1602_write_char(1,0x0c); //光标关
**********************************************************/
extern unsigned char relay;
static unsigned char LCD_PORT;
void LCD1602_init(void)
{
LCD_PORT &= 0x0f;
LCD_PORT |= 0x20; //等效LCD_DATA=0x20;
WriteSIOByte(LCD_PORT,relay);
LCD1602_en_write();
//delay_us(50); //如果晶振频率太高,则可相应提高延时
LCD1602_write_char(1,0x28); //4bit test
LCD1602_write_char(1,0x0c); //显示开
LCD1602_write_char(1,0x01); //显示清屏
LCD1602_write_char(1,0x06); //显示光标移动设置
}
void LCD1602_en_write(void) //EN端产生一个高电平脉冲,写LCD
{
LCD_PORT |= LCD_EN;
WriteSIOByte(LCD_PORT,relay);
//delay_us(30); //如果晶振频率太高,则可相应提高延时
LCD_PORT &= ~LCD_EN;
WriteSIOByte(LCD_PORT,relay);
}
/************************************************************************/
/* LCD1602清屏 */
/************************************************************************/
void LCD1602_clear(void)
{
LCD1602_write_char(1,0x01);
delay_ms(5);
}
/*-----------------------------------------------------------------------
LCD1602_write_char : 英文字符串显示函数
输入参数:*s :英文字符串指针;
X、Y : 显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0x80-0x8F
LCD第一行显示寄存器地址:0xC0-0xCF
-----------------------------------------------------------------------*/
void LCD1602_write_char(unsigned char command,unsigned char data)
{
unsigned char datah,datal;
datah = data;
datal = data<<4 ;
if (command == 0) //data
{
LCD_PORT |= LCD_RS; //RS=1
WriteSIOByte(LCD_PORT,relay);
}
else //command
{
LCD_PORT &= ~LCD_RS; //RS=0
WriteSIOByte(LCD_PORT,relay);
}
LCD_PORT &= 0x0f;
WriteSIOByte(LCD_PORT,relay);
LCD_PORT |= datah&0xf0;
WriteSIOByte(LCD_PORT,relay); //send high 4bit
LCD1602_en_write();
LCD_PORT &= 0x0f;
WriteSIOByte(LCD_PORT,relay);
LCD_PORT |= datal&0xf0;
WriteSIOByte(LCD_PORT,relay); //send low 4bit
LCD1602_en_write();
}
/*-----------------------------------------------------------------------
LCD_set_xy : 设置LCD显示的起始位置
输入参数:x、y : 显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0x80-0x8F
LCD第一行显示寄存器地址:0xC0-0xCF
-----------------------------------------------------------------------*/
void LCD1602_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0)
address = 0x80 + x;
else
address = 0xc0 + x;
LCD1602_write_char( 1,address );
}
/*-----------------------------------------------------------------------
LCD1602_write_string : 英文字符串显示函数
输入参数:*s :英文字符串指针;
X、Y : 显示字符串的位置
-----------------------------------------------------------------------*/
void LCD1602_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
LCD1602_set_xy( X, Y );
while (*s)
{
LCD1602_write_char( 0, *s );
s++;
}
}
void WriteSIOByte(unsigned char lcd,unsigned char relays)
{
unsigned char i;
for (i=0;i<8;i++)
{
SRCLK=0;//拉低74HC595时钟
SER=relays&0x01;//发送74HC595一位串行数据
relays=relays>>1;//右移一位数据
SRCLK=1;//拉高74HC595时钟
#asm("nop");//延时
}
for (i=0;i<8;i++)
{
SRCLK=0;//拉低74HC595时钟
SER=lcd&0x01;//发送74HC595一位串行数据
lcd=lcd>>1;//右移一位数据
SRCLK=1;//拉高74HC595时钟
#asm("nop");//延时
}
SER=1;//释放数据总线
//以下3条指令若在多字节时,应该移入多字节全发送完后在执行此3条指令
RCLK=0;
#asm("nop");//延时
RCLK=1;//打入并行数据
} |
|