title
收藏本站
联系站长
关于本站
首页 信息发布 产品宣传 论坛交流 学习文章 技术人生 项目源码 技术资料 人才收录
 今天是: 2010年7月10日 星期 六
欢迎光临!单片机群号:25930265(新) 71062262 21829895 64584393 26583231(只限加一群)  
热门文章推荐


当前位置:首页>>>单片机学习文章>> 基于C51的简易计算器设计1602显示
基于C51的简易计算器设计1602显示
作者:wwww90给他留言 [原创] 字体:
发表于:
2009-08-19 16:27:41

这几天在搞这个   希望对大家有帮助 

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCM_RW=P3^1; //定义引脚
sbit LCM_RS=P3^2;
sbit LCM_E=P3^0;
#define LCM_Data P2
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
unsigned long xnn(unsigned char n);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
void Delay5Ms(void);
void Delay400Ms(void);
unsigned char TAB1[16]={"123+456-789*00=/"};
unsigned char TAB2[16]={0x77,0x7b,0x7d,0x7e,0xb7,0xbb,0xbd,0xbe,0xd7,0xdb,0xdd,0xde,0xe7,0xeb,0xed,0xee};
unsigned char XX[2][5]={{""},{""}};
unsigned char YY[5]={""};
void main(void)
{unsigned char n,m,a,b,c,x,y;
unsigned char sc1,sc2,fuhao,r,sw1,sw2,rr,rrr;
unsigned long s1,s2,jieguo;
P0=0x00;
AA:
Delay400Ms(); //启动等待,等LCM讲入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻(可不要)
rrr=1;
rr=0;
c=0;
x=0;
sc1=sc2=0;
s1=s2=0;
sw1=sw2=0;
while(1)
 {
 P1=0xf0;
 m=(P1&0xf0);
 P1=0x0f;
 n=(P1&0x0f);
 y=n|m;
 if(x!=y)a=1;

 while(a)
  {P1=0x0f;
  n=(P1&0x0f);
  P1=0xf0;
  m=(P1&0xf0);
  if((n!=0x0f)||(m!=0xf0))
   {x=n|m;
    for(b=0;b<16;b++)
     {if(x==TAB2[b])
      {if(b==13)goto AA;
      a=0;
      c++;
      
      if(b==3||b==7||b==11||b==15)
       {sc1=1;
       sw1=sc2;
       sc2=0;
       fuhao=b;
       }
      else if(b!=14)sc2++;
      break;
      }
     }
   }
  
  }
 if(b!=14&&b!=20)
  {DisplayOneChar(c-1,0,TAB1[b]);
  if((b!=3)&&(b!=7)&&(b!=11)&&(b!=15)) 
   XX[sc1][sc2-1]=TAB1[b];
  b=20;
  }
 else if(b==14)
  {sw2=sc2;
  for(r=0;r<sw1;r++)s1+=(XX[0][r]-'0')*xnn(sw1-r-1);
  for(r=0;r<sw2;r++)s2+=(XX[1][r]-'0')*xnn(sw2-r-1);  
   
  
  switch(fuhao)
   {case(3):{jieguo=s1+s2;break;}
   case(7):{jieguo=s1-s2;break;}
   case(11):{jieguo=s1*s2;break;}
   case(15):{jieguo=s1/s2;break;}
   }      
  
  YY[0]=(jieguo/10000)+'0';
  YY[1]=(jieguo%10000/1000)+'0';
  YY[2]=(jieguo%1000/100)+'0';
  YY[3]=(jieguo%100/10)+'0';
  YY[4]=(jieguo%10)+'0'; 
  /* DisplayListChar(0,1,XX[0]);
     DisplayOneChar(7,1,'0'+sw1);
  DisplayListChar(8,1,XX[1]);
  DisplayOneChar(15,1,'0'+sw2);  */
  DisplayOneChar(0,1,TAB1[14]);
  
  for(r=0;r<5;r++)
   {if(YY[r]!='0')rr=1;
   if(rr)DisplayOneChar(rrr++,1,YY[r]);
   
   }
  if(!rr)DisplayOneChar(1,1,'0');
  b=20;
  }
 Delay5Ms();
 Delay5Ms();
 Delay5Ms();
 Delay5Ms();
 }
  
  
}

 

//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}

//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS=0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
unsigned char ListLength;

ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}

//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
unsigned long xnn(unsigned char n)
{unsigned char i;
unsigned long x=1;
for(i=1;i<=n;i++)
  {x*=10;
  }
return(x);
 
}


(本文引自www.mcujl.com/article.asp?conID=436)


---------------------------------------------------------------------------------------------------
[打印文章] [关闭本页] [返回顶部]
本网站部分资料转自网上,如有侵权请来信告明,我们会尽快删除  | 网站地图
Copyright @ 2007-2010 深圳单片机交流网.版权所有
网站创办者:詹长亮,周发辉,李林盛
网站支持:zcl843@163.com QQ:380476830 13723787271詹长亮