1602從右到左移動顯示字元實驗
#include <reg51.h>
#include "LCD1602.h"
/*******************主函式**********************************/
uchar string[]=" I LOVE YOU C51! "; //這裡是要顯示的字元
void main(void)
{
uchar *cp;
cp=string;
LCD_init();
while(1)
LCD_send_command(LCD_CLEAR_SCREEN);
delay_ms(2);
LCD_disp_string(0,0,cp);
delay_ms(100);
cp++;
if(*cp=="\0")
cp=string; //到達字元的尾部時,改變指標,重新指向字串的頭部
}
/*********************************************************/
/**************LCD1602的初始化***************************/
void LCD_init(void)
LCD_send_command(LCD_DISPLAY_DOUBLE_LINE);
LCD_send_command(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
LCD_send_command(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
/********************************************************/
void LCD_check_busy(void) //檢測LCD狀態,看它是不是還在忙呢
do
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCDIO=0xff;
LCD_EN=1;
while(LCD_BUSY==1);
/************LCD1602寫命令*******************************/
void LCD_send_command(uchar command)
LCD_check_busy();
LCD_RS=LOW;
LCD_RW=LOW;
LCD_EN=HIGH;
LCDIO=command;
LCD_EN=LOW;
/*****************LCD1602寫資料**************************/
void LCD_send_data(uchar dat)
LCD_RS=HIGH;
LCDIO=dat;
/********************************************************
void LCD_write_char(uchar x,uchar y,uchar dat)
unsigned char address;
if (y == LINE1)
address = LINE1_HEAD + x;
else
address = LINE2_HEAD + x;
LCD_send_command(address);
LCD_send_data(dat);
******************LCD1602顯示字串*********************/
void LCD_disp_string(uchar x,uchar y,uchar *Data)
if(y==LINE1)
if(x<LINE_LENGTH)
LCD_send_command(LINE1_HEAD+x);
for(;x<LINE_LENGTH&&*Data!="\0";x++)
LCD_send_data(*(Data++));
if(*Data!="\0")
x=0;
y=LINE2;
if(y==LINE2)
LCD_send_command(LINE2_HEAD+x);
/****************************************************************/
/********************延時函式***********************************/
/***************************************************************/
void delay_ms(uint n)
uint i,j;
for(i=n;i>0;i--)
for(j=0;j<1140;j++)
;
/*********************************************************************/
/**************************************LCD1602標頭檔案*********************************/
#ifndef _LCD1602_H_
#define _LCD1602_H_
//輸入方式設定
#define LCD_AC_AUTO_INCREMENT 0x06 //資料讀、寫操作後,AC自動增一
#define LCD_AC_AUTO_DECREASE 0x04 //資料讀、寫操作後,AC自動減一
#define LCD_MOVE_ENABLE 0x05 //資料讀、寫操作,畫面平移
#define LCD_MOVE_DISENABLE 0x04 //資料讀、寫操作,畫面不動
#define LCD_GO_HOME 0x02 //AC=0,游標、畫面回HOME位
//設定顯示、游標及閃爍開、關
#define LCD_DISPLAY_ON 0x0C //顯示開
#define LCD_DISPLAY_OFF 0x08 //顯示關
#define LCD_CURSOR_ON 0x0A //游標顯示
#define LCD_CURSOR_OFF 0x08 //游標不顯示
#define LCD_CURSOR_BLINK_ON 0x09 //游標閃爍
#define LCD_CURSOR_BLINK_OFF 0x08 //游標不閃爍
//游標、畫面移動,不影響DDRAM
#define LCD_LEFT_MOVE 0x18 //LCD顯示左移一位
#define LCD_RIGHT_MOVE 0x1C //LCD顯示右移一位
#define LCD_CURSOR_LEFT_MOVE 0x10 //游標左移一位
#define LCD_CURSOR_RIGHT_MOVE 0x14 //游標右移一位
//工作方式設定
#define LCD_DISPLAY_DOUBLE_LINE 0x38 //兩行顯示
#define LCD_DISPLAY_SINGLE_LINE 0x30 //單行顯示
#define LCD_CLEAR_SCREEN 0X01 //清屏
/***********************LCD1602地址相關******************************/
#define LINE1_HEAD 0x80 // 第一行DDRAM起始地址
#define LINE2_HEAD 0xc0 // 第二行DDRAM起始地址
#define LINE1 0 //第一行
#define LINE2 1 //第二行
#define LINE_LENGTH 16 //每行的最大字元長度
/***********************LCD1602接線引腳定義**************************/
#define LCDIO P0 //定義P2口與LCD1602的資料口相接
sbit LCD_RS=P2^2;
sbit LCD_RW=P2^3;
sbit LCD_EN=P2^4;
sbit LCD_BUSY=LCDIO^7;
/**********************另外相關的定*********************************/
#define HIGH 1
#define LOW 0
#define TURE 1
#define FALSE 0
#define uchar unsigned char
#define uint unsigned int
/*************************以下是函式的申明部*************************/
void LCD_init(void); //LCD1602初始化
void LCD_send_command(uchar command); //
void LCD_send_data(uchar dat);
void LCD_write_char(uchar x,uchar y,uchar dat);
void LCD_disp_string(uchar x,uchar y,char *Data);
void delay_ms(uint n);
void LCD_check_busy(void);
#endif
/******************************************************************/
供對比與參考
1602從右到左移動顯示字元實驗
#include <reg51.h>
#include "LCD1602.h"
/*******************主函式**********************************/
uchar string[]=" I LOVE YOU C51! "; //這裡是要顯示的字元
void main(void)
{
uchar *cp;
cp=string;
LCD_init();
while(1)
{
LCD_send_command(LCD_CLEAR_SCREEN);
delay_ms(2);
LCD_disp_string(0,0,cp);
delay_ms(100);
cp++;
if(*cp=="\0")
{
cp=string; //到達字元的尾部時,改變指標,重新指向字串的頭部
}
}
}
/*********************************************************/
/**************LCD1602的初始化***************************/
void LCD_init(void)
{
LCD_send_command(LCD_DISPLAY_DOUBLE_LINE);
LCD_send_command(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
LCD_send_command(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
LCD_send_command(LCD_CLEAR_SCREEN);
}
/********************************************************/
void LCD_check_busy(void) //檢測LCD狀態,看它是不是還在忙呢
{
do
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCDIO=0xff;
LCD_EN=1;
}
while(LCD_BUSY==1);
LCD_EN=0;
}
/************LCD1602寫命令*******************************/
void LCD_send_command(uchar command)
{
LCD_check_busy();
LCD_RS=LOW;
LCD_RW=LOW;
LCD_EN=HIGH;
LCDIO=command;
LCD_EN=LOW;
}
/********************************************************/
/*****************LCD1602寫資料**************************/
void LCD_send_data(uchar dat)
{
LCD_check_busy();
LCD_RS=HIGH;
LCD_RW=LOW;
LCD_EN=HIGH;
LCDIO=dat;
LCD_EN=LOW;
}
/********************************************************
void LCD_write_char(uchar x,uchar y,uchar dat)
{
unsigned char address;
if (y == LINE1)
address = LINE1_HEAD + x;
else
address = LINE2_HEAD + x;
LCD_send_command(address);
LCD_send_data(dat);
}
******************LCD1602顯示字串*********************/
void LCD_disp_string(uchar x,uchar y,uchar *Data)
{
if(y==LINE1)
{
if(x<LINE_LENGTH)
{
LCD_send_command(LINE1_HEAD+x);
for(;x<LINE_LENGTH&&*Data!="\0";x++)
{
LCD_send_data(*(Data++));
}
if(*Data!="\0")
{
x=0;
y=LINE2;
}
}
}
if(y==LINE2)
{
LCD_send_command(LINE2_HEAD+x);
for(;x<LINE_LENGTH&&*Data!="\0";x++)
{
LCD_send_data(*(Data++));
}
}
}
/****************************************************************/
/********************延時函式***********************************/
/***************************************************************/
void delay_ms(uint n)
{
uint i,j;
for(i=n;i>0;i--)
for(j=0;j<1140;j++)
;
}
/*********************************************************************/
/**************************************LCD1602標頭檔案*********************************/
#ifndef _LCD1602_H_
#define _LCD1602_H_
//輸入方式設定
#define LCD_AC_AUTO_INCREMENT 0x06 //資料讀、寫操作後,AC自動增一
#define LCD_AC_AUTO_DECREASE 0x04 //資料讀、寫操作後,AC自動減一
#define LCD_MOVE_ENABLE 0x05 //資料讀、寫操作,畫面平移
#define LCD_MOVE_DISENABLE 0x04 //資料讀、寫操作,畫面不動
#define LCD_GO_HOME 0x02 //AC=0,游標、畫面回HOME位
//設定顯示、游標及閃爍開、關
#define LCD_DISPLAY_ON 0x0C //顯示開
#define LCD_DISPLAY_OFF 0x08 //顯示關
#define LCD_CURSOR_ON 0x0A //游標顯示
#define LCD_CURSOR_OFF 0x08 //游標不顯示
#define LCD_CURSOR_BLINK_ON 0x09 //游標閃爍
#define LCD_CURSOR_BLINK_OFF 0x08 //游標不閃爍
//游標、畫面移動,不影響DDRAM
#define LCD_LEFT_MOVE 0x18 //LCD顯示左移一位
#define LCD_RIGHT_MOVE 0x1C //LCD顯示右移一位
#define LCD_CURSOR_LEFT_MOVE 0x10 //游標左移一位
#define LCD_CURSOR_RIGHT_MOVE 0x14 //游標右移一位
//工作方式設定
#define LCD_DISPLAY_DOUBLE_LINE 0x38 //兩行顯示
#define LCD_DISPLAY_SINGLE_LINE 0x30 //單行顯示
#define LCD_CLEAR_SCREEN 0X01 //清屏
/***********************LCD1602地址相關******************************/
#define LINE1_HEAD 0x80 // 第一行DDRAM起始地址
#define LINE2_HEAD 0xc0 // 第二行DDRAM起始地址
#define LINE1 0 //第一行
#define LINE2 1 //第二行
#define LINE_LENGTH 16 //每行的最大字元長度
/***********************LCD1602接線引腳定義**************************/
#define LCDIO P0 //定義P2口與LCD1602的資料口相接
sbit LCD_RS=P2^2;
sbit LCD_RW=P2^3;
sbit LCD_EN=P2^4;
sbit LCD_BUSY=LCDIO^7;
/**********************另外相關的定*********************************/
#define HIGH 1
#define LOW 0
#define TURE 1
#define FALSE 0
#define uchar unsigned char
#define uint unsigned int
/*************************以下是函式的申明部*************************/
void LCD_init(void); //LCD1602初始化
void LCD_send_command(uchar command); //
void LCD_send_data(uchar dat);
void LCD_write_char(uchar x,uchar y,uchar dat);
void LCD_disp_string(uchar x,uchar y,char *Data);
void delay_ms(uint n);
void LCD_check_busy(void);
#endif
/******************************************************************/
供對比與參考