电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

89C2051+1602 的滚动字幕机

程序的关键是一个从输入的字符串中截取从起始位置开始的长度为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++;
  }
}

博主
zxie
zxie's Blog
zxie
点击跳转