专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AT89s52-LCD12864多页菜单按键选择操作

作者:佚名   来源:本站原创   点击数:  更新时间:2011年07月11日   【字体:

      这篇程序的代码还未理解清楚,再一次深刻发现自己的算法水平不行。今天学到的东西还行,就是那些C文件的一些知识。反正都是些优化的东西,以后肯定也用的着,过几天有兴趣的话,再去学习一下AVR单片机。

        程序代码:硬件上与前面一样,有点变化就是多了两个翻页的按键。到现在一整天的饭都还没吃,该去吃了,干这个果然不会困。


#include <reg52.h>
#include <intrins.h>

sbit RS = P2^4;
sbit RW = P2^5;
sbit E  = P2^6;
sbit PSB= P2^1; //串并口选择端  并高串低
#define DataPort P0   

sbit KEY_ADD=P3^3; //按键
sbit KEY_DEC=P3^4;

unsigned char curr,currold;//全局变量,当前箭头位置

unsigned char code user16x16[]={ //箭头图片
0x00,0x00,0x20,0x00,0x30,0x00,0x38,0x00,0x3C,0x00,0x3E,0x00,0x3F,0x00,0x3F,0x80,
0x3F,0xC0,0x3F,0x80,0x3F,0x00,0x3E,0x00,0x3C,0x00,0x38,0x00,0x30,0x00,0x20,0x00,
};

unsigned char code *MainMenu[]=
{
 {"  1.设置1"},
 {"  2.设置2"},
 {"  3.设置3"},
 {"  4.设置4"},
 {"  5.设置5"},
 {"  6.设置6"},
 {"  7.设置7"},
 {"  8.设置8"},
 {"  9.设置9"},
 {"  0.设置0"},
};

/***********************************************
                  延时函数
***********************************************/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}

void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     DelayUs2x(245);
  DelayUs2x(245);
 }
}

/***********************************************
                判忙函数
***********************************************/
void Check_Busy()
{  
    RS=0;  //写命令
    RW=1;  //读状态
    E=1;
    DataPort=0xff;
    while((DataPort&0x80)==0x80);//忙则等待
    E=0;
}

/***********************************************
                写入命令
***********************************************/
void Write_Cmd(unsigned char Cmd)
{
 Check_Busy();
 RS=0;  //写命令
 RW=0;  //write
 E=1;
 DataPort=Cmd;
 DelayUs2x(5);
 E=0;
 DelayUs2x(5);
}

/***********************************************
                 写入数据
***********************************************/
void Write_Data(unsigned char Data)
{
 Check_Busy();
 RS=1; //写数据
 RW=0; //write
 E=1;
 DataPort=Data;
 DelayUs2x(5);
 E=0;
 DelayUs2x(5);
}

/***********************************************
               液晶屏初始化
***********************************************/
void Init_ST7920()
{  
   DelayMs(40);           //大于40MS的延时程序
   PSB=1;                 //设置为8BIT并口工作模式
   DelayMs(1);            //延时
   Write_Cmd(0x30);       //选择基本指令集
   DelayUs2x(50);         //延时大于100us
   Write_Cmd(0x30);       //选择8bit数据流
   DelayUs2x(20);         //延时大于37us
   Write_Cmd(0x0c);       //开显示(无游标、不反白)
   DelayUs2x(50);         //延时大于100us
   Write_Cmd(0x01);       //清除显示,并且设定地址指针为00H
   DelayMs(15);           //延时大于10ms
   Write_Cmd(0x06);       //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动
   DelayUs2x(50);         //延时大于100us
}

/***********************************************
                用户自定义字符
***********************************************/
void CGRAM()
{ 
     int i;
     Write_Cmd(0x30); 
     Write_Cmd(0x40);
     for(i=0;i<16;i++)
       {
        Write_Data(user16x16[i*2]);
        Write_Data(user16x16[i*2+1]);
      }
}   

/***********************************************
               显示用户自定义字符
***********************************************/
void DisplayCGRAM(unsigned char x,unsigned char y)
{ 
 switch(y)
     {
   case 1: Write_Cmd(0x80+x);break;
   case 2: Write_Cmd(0x90+x);break;
   case 3: Write_Cmd(0x88+x);break;
   case 4: Write_Cmd(0x98+x);break;
      default:break;
  }
    Write_Data(00);
    Write_Data(00);
}         

/***********************************************
                  显示字符串
            x:横坐标值,范围0~8
            y:纵坐标值,范围1~4
***********************************************/
void LCD_PutString(unsigned char x,unsigned char y,unsigned char code *s)
{ 
 switch(y)
     {
   case 1: Write_Cmd(0x80+x);break;
   case 2: Write_Cmd(0x90+x);break;
   case 3: Write_Cmd(0x88+x);break;
   case 4: Write_Cmd(0x98+x);break;
      default:break;
  }
 while(*s>0)
   { 
      Write_Data(*s);
      s++;
      DelayUs2x(50);
   }
}

/***********************************************
                     清屏
***********************************************/
void ClrScreen()
{ 
   Write_Cmd(0x01);
   DelayMs(15);
}
    
/***********************************************
               调用显示更新
***********************************************/
void DisplayUpdata(void)
{   
    unsigned char num;
  ClrScreen();
 num=sizeof(MainMenu)/sizeof(MainMenu[0]);//判断数组中数值个数
 if((0+(curr/4)*4)<num)
      LCD_PutString(0,1,MainMenu[0+(curr/4)*4]);
 else //如果超出数组最大元素,则写空信息,不判断此信息可能会出现乱码 
   LCD_PutString(0,1,"");
 if((1+(curr/4)*4)<num)
   LCD_PutString(0,2,MainMenu[1+(curr/4)*4]);
 else
   LCD_PutString(0,2,"");
 if((2+(curr/4)*4)<num)
   LCD_PutString(0,3,MainMenu[2+(curr/4)*4]);
 else
   LCD_PutString(0,3,"");
 if((3+(curr/4)*4)<num)
   LCD_PutString(0,4,MainMenu[3+(curr/4)*4]);
 else
   LCD_PutString(0,4,"");
 DisplayCGRAM(0,curr%4+1); 
}

/***********************************************
                 MAIN
***********************************************/
void main()
{
   Init_ST7920(); 
   CGRAM(); //写入自定义字符 
   DisplayUpdata();
   while(1)
   {     
     if(curr!=currold) //光标位置变化,则更新显示
      {
       DisplayUpdata();
       currold=curr;
      } 
 
   if(!KEY_ADD)  
    {
     DelayMs(10);
     if(!KEY_ADD)     
    {
        while(!KEY_ADD);
      {
    if(curr<sizeof(MainMenu)/sizeof(MainMenu[0])-1)
     //判断数组中数值个数
     { curr++; }
      }
    }
 }

  if(!KEY_DEC) 
    {
     DelayMs(10);
     if(!KEY_DEC)     
    {
        while(!KEY_DEC);
      {
       if(curr>0)
     { curr--; }
    }
    }
 }  
  }
}

 

这篇程序还是没有涉及到变量,需要再去另外找一篇有涉及变量的程序。
关闭窗口

相关文章