程序的关键是一个从输入的字符串中截取从起始位置开始的长度为16的部分字符串的子程序,然后把截取的字符串送到1602的指定行中显示。
下图为Proteus仿真结果。
下面是程序列表:
/****************************************************************************
*/
#include <reg52.h> //调用头文件(单片机内部的寄存器定义)
#include <string.h>
/******本段为硬件I/O口定义********/
sbit LCD_RW = P3 ^ 5;
sbit LCD_RS = P3 ^ 4;
sbit LCD_E = P3 ^ 3;
#define LCD_DATA P1 //LCD DATA
#define LCD_BUSY 0x80 // 用于检测LCD的BUSY标识(本程序中用的延时,未检测)
//LCD显示内容,定义到代码段
unsigned char code LcdBuf1[]= {"\"I have a dream\", By Martin Luther King, Jr. "};
unsigned char code LcdBuf2[]= {"I have a dream that one day this nation will rise up and live out the true meaning of its creed: \"We hold these truths to be self-evident: that all men are created equal.\" "};
//函数声明
void lcd_init(void);
void display_string(unsigned char x,unsigned char y,unsigned char *s);
void disp_selec(unsigned char bit_selec,unsigned char seg);
char * get_part_str(int start_pos,const char *s);
/**************************************************
** 函数名称: get_part_str
** 入口参数:start_pos(unsigned int型)
** 入口参数:*s(const char *型)
** 出口参数:char *s
** 功能描述: 从输入的字符串中截取从起始位置开始的长度为16的部分字符串
****************************************************/
char * get_part_str(int start_pos,const char *s)
{
char result[16]={" "};
char retstr[16]={" "};
strncpy(&result,s,16);
while (s != NULL && *s != '\0' && start_pos != 0)
{
s++;
start_pos--;
}
strncpy(retstr,s,16);
if(strlen(s)<16)
{
strcat(retstr,&result);
}
return &retstr;
}
/**************************************************
** 函数名称: dellay
** 入口参数:h(unsigned int型)
** 出口参数:无
** 功能描述: 短暂延时,使用11.0592晶体,约0.01MS
****************************************************/
void dellay(unsigned int h)
{
while(h--); //0.01MS
}
/************主程序**************/
main()
{
int i;
char* str1;
char* str2;
lcd_init();
while(1) //单片机待机
{
for (i=0;i<strlen(LcdBuf2);i++)
{
str1=get_part_str(i%strlen(LcdBuf1),LcdBuf1);//从输入的字符串LcdBuf1中截取从起始位置开始的长度为16的部分字符串
display_string(0,0,str1); //显示第一行,从第0个位置开始
str2=get_part_str(i,LcdBuf2);//从输入的字符串LcdBuf2中截取从起始位置开始的长度为16的部分字符串
display_string(0,1,str2); //显示第二行,从第0个位置开始
dellay(100000); //短暂延时,代替检测忙状态
}
}
}
/**************************************************
** 函数名称: WriteDataLcd
** 入口参数:wdata(unsigned char型)
** 出口参数:无
** 功能描述: 写数据到LCD
****************************************************/
void WriteDataLcd(unsigned char wdata)
{
LCD_DATA=wdata;
LCD_RS=1;
LCD_RW=0;
LCD_E=0;
dellay(100); //短暂延时,代替检测忙状态
LCD_E=1;
}
/**************************************************
** 函数名称: WriteCommandLcd
** 入口参数:wdata(unsigned char型)
** 出口参数:无
** 功能描述: 写命令到LCD
****************************************************/
void WriteCommandLcd(unsigned char wdata)
{
LCD_DATA=wdata;
LCD_RS=0;
LCD_RW=0;
LCD_E=0;
dellay(100); //短暂延时,代替检测忙状态
LCD_E=1;
}
//LCD初始化
void lcd_init(void)
{
LCD_DATA=0;
WriteCommandLcd(0x38);
dellay(1000);
WriteCommandLcd(0x38); //显示模式设置
WriteCommandLcd(0x08); //关闭显示
WriteCommandLcd(0x01); //显示清屏
WriteCommandLcd(0x06); //显示光标移动设置
WriteCommandLcd(0x0c); //显示开及光标移动设置
}
/**************************************************
** 函数名称: display_xy
** 入口参数:x(unsigned char型),y(unsigned char型)
** 出口参数:无
** 功能描述: 设置光标位置, x是列号,y是行号
****************************************************/
void display_xy(unsigned char x,unsigned char y)
{
if(y==1)
x+=0x40;
x+=0x80;
WriteCommandLcd(x);
}
/********************************************************************
** 函数名称: display_char
** 入口参数:x(unsigned char型),y(unsigned char型),dat(unsigned char型)
** 出口参数:无
** 功能描述: 在具体位置显示单个字符,x是列号,y是行号
*********************************************************************/
void display_char(unsigned char x,unsigned char y,unsigned char dat)
{
display_xy(x,y);
WriteDataLcd(dat);
}
/*********************************************************************
** 函数名称: display_string
** 入口参数:x(unsigned char型),y(unsigned char型),s(指针型)
** 出口参数:无
** 功能描述: 在具体位置显示字符串,以/0结束,x是列号,y是行号
**********************************************************************/
void display_string(unsigned char x,unsigned char y,unsigned char *s)
{
display_xy(x,y);
while(*s)
{
WriteDataLcd(*s);
s++;
}
}
文章评论(0条评论)
登录后参与讨论