这是一个用89S52和1602显示屏做的简单计算器,求实现该功能的程序(C语言),很急
发布网友
发布时间:2022-04-30 06:03
我来回答
共2个回答
热心网友
时间:2023-10-19 05:22
#include <intrins.h>
#define PORT P0
#define uint unsigned int
#define uchar unsigned char
uint shuzu[4];
uchar dis_buf,a,x;
unsigned long date,date1,date2;
void display();
void display1();
void calculate();
uchar a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
uchar code key_code[]={0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77}; //3*4矩阵接键,分别显示1234567890AB
sbit EN=P2^7; //1602使能控制线
sbit RS=P2^6; //1602数据/指令选择控制线
sbit RW=P2^5; //1602读写控制线
/**延时处理程序,单位ms**/
void delayms (uint ms)
{
uint i;
while(ms--)
{
//for(i=0;i<112;i++) //11.0592M晶体
for(i=0;i<120;i++) //12M晶体
{;}
}
}
//*****lcd1602驱动******//
/**1602忙状态检测**/
void lcdbusy()
{
do{
EN=0;
RS=0;
RW=1;
PORT=0xff;
EN=1;
_nop_();
}
while(PORT&0x80);
EN=0;
}
/**1602写命令函数**/
void lcdwcmd(uchar cmd)
{
lcdbusy();
RS=0;
RW=0;
EN=1;
PORT=cmd;
EN=0;
}
/**1602写数据函数**/
void lcdwdata(uchar dat)
{
lcdbusy();
RS=1;
RW=0;
EN=1;
PORT=dat;
EN=0;
}
/**LCD数据指针位置程序**/
void lcdpos(bit x, uchar y)
{
if(x)lcdwcmd(y|0xc0); //x=1,第二行显示;x=0,第一行显示 0<=x<16
else lcdwcmd(y|0x80); //数据指针=80+地址码(00H~27H,40H~67H)
}
/**1602初使化**/
void lcdint()
{
lcdwcmd(0x38); //设置LCD为16X2显示,5X7点阵,八位数据接口
lcdwcmd(0x0c); //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
lcdwcmd(0x06); //LCD开显示及光标设置(光标不闪烁,不显示"_")
lcdwcmd(0x01); //清除LCD的显示内容
}
/**按键扫描程序**/
void keyscan()
{
uchar scan1,scan2,keycode,j,key;
P1=0xf0;
scan1=P1;
if(scan1!=0xf0)
{
delayms(10);
scan1=P1;
if(scan1!=0xf0)
{
P1=0xff;
P1=0x0f;
scan2=P1;
keycode=scan1|scan2;
for(j=0;j<12;j++)
{
if(keycode==key_code[j])
{
key=j;
dis_buf=key; //键值入显示缓存
dis_buf=dis_buf&0x0f;
if(dis_buf>9) //转换为ASCII码
dis_buf=dis_buf+0x37;
else
dis_buf=dis_buf+0x30;
P1=0xf0; //判断是否按键已经按下
while(P1!=0xf0);
}
}
}
else dis_buf=240; // 没有按键按下的时候给dis_buf为240
}
}
/**主函数**/
void main()
{
lcdint();
while(1)
{
keyscan();
if(dis_buf!=240) // 当有键按下的时候
{
x=x+1; // 每按下一次键更新一次显示
calculate();
switch(x) // 数据的更新
{
case 2: a0=dis_buf;a1=0x20; break;
case 3: a1=a0;a0=dis_buf; break;
}
display();
dis_buf=240; // 执行完一次键值后重新给键值240
}
}
}
void calculate()
{ uchar i;
if(dis_buf==0x41) //当按键的码值是0x40(键盘上的a键)
{
lcdpos(1,0); // 则在下面一行的开始显示“+”
lcdwdata(0x2b);
display1(); // 上一组数据全部搬到上面一行显示
if(a1==0x20) a1=0x30; //如果加数是一位数则十位默认为0
date1=(a0-0x30)+(a1-0x30)*10; //计算第一个数的数值
a0=0x20;a1=0x20;
x=1;
}
if(dis_buf==0x42) // 当按键的码值是0x42(键盘上的b键)
{
lcdpos(1,0); // 则在下面一行的开始显示“=”
lcdwdata(0x3d);
if(a1==0x20) a1=0x30; //如果被加数是一位数则十位默认为0
date2=(a0-0x30)+(a1-0x30)*10; //计算第二个数的数值
date=date1+date2; // 两个数相加
shuzu[0]=date%1000/100+0x30; //百位
shuzu[1]=date%100/10+0x30; //十位
shuzu[2]=date%10+0x30; //个
lcdpos(1,1); // 把加得的数显示在“+”后面
for(i=0;i<=2;i++)
lcdwdata(shuzu[i]);
x=0;
}
}
/**显示程序1(在1602下面一行显示)**/
void display()
{
lcdpos(1,15);
lcdwdata(a0);
lcdpos(1,14);
lcdwdata(a1);
}
/**显示程序2(在上面一行显示)**/
void display1()
{
lcdpos(0,15);
lcdwdata(a0);
lcdpos(0,14);
lcdwdata(a1);
}
热心网友
时间:2023-10-19 05:22
kjhbkklllggtggggggggggggggggggddd
热心网友
时间:2023-10-19 05:22
#include <intrins.h>
#define PORT P0
#define uint unsigned int
#define uchar unsigned char
uint shuzu[4];
uchar dis_buf,a,x;
unsigned long date,date1,date2;
void display();
void display1();
void calculate();
uchar a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
uchar code key_code[]={0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77}; //3*4矩阵接键,分别显示1234567890AB
sbit EN=P2^7; //1602使能控制线
sbit RS=P2^6; //1602数据/指令选择控制线
sbit RW=P2^5; //1602读写控制线
/**延时处理程序,单位ms**/
void delayms (uint ms)
{
uint i;
while(ms--)
{
//for(i=0;i<112;i++) //11.0592M晶体
for(i=0;i<120;i++) //12M晶体
{;}
}
}
//*****lcd1602驱动******//
/**1602忙状态检测**/
void lcdbusy()
{
do{
EN=0;
RS=0;
RW=1;
PORT=0xff;
EN=1;
_nop_();
}
while(PORT&0x80);
EN=0;
}
/**1602写命令函数**/
void lcdwcmd(uchar cmd)
{
lcdbusy();
RS=0;
RW=0;
EN=1;
PORT=cmd;
EN=0;
}
/**1602写数据函数**/
void lcdwdata(uchar dat)
{
lcdbusy();
RS=1;
RW=0;
EN=1;
PORT=dat;
EN=0;
}
/**LCD数据指针位置程序**/
void lcdpos(bit x, uchar y)
{
if(x)lcdwcmd(y|0xc0); //x=1,第二行显示;x=0,第一行显示 0<=x<16
else lcdwcmd(y|0x80); //数据指针=80+地址码(00H~27H,40H~67H)
}
/**1602初使化**/
void lcdint()
{
lcdwcmd(0x38); //设置LCD为16X2显示,5X7点阵,八位数据接口
lcdwcmd(0x0c); //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
lcdwcmd(0x06); //LCD开显示及光标设置(光标不闪烁,不显示"_")
lcdwcmd(0x01); //清除LCD的显示内容
}
/**按键扫描程序**/
void keyscan()
{
uchar scan1,scan2,keycode,j,key;
P1=0xf0;
scan1=P1;
if(scan1!=0xf0)
{
delayms(10);
scan1=P1;
if(scan1!=0xf0)
{
P1=0xff;
P1=0x0f;
scan2=P1;
keycode=scan1|scan2;
for(j=0;j<12;j++)
{
if(keycode==key_code[j])
{
key=j;
dis_buf=key; //键值入显示缓存
dis_buf=dis_buf&0x0f;
if(dis_buf>9) //转换为ASCII码
dis_buf=dis_buf+0x37;
else
dis_buf=dis_buf+0x30;
P1=0xf0; //判断是否按键已经按下
while(P1!=0xf0);
}
}
}
else dis_buf=240; // 没有按键按下的时候给dis_buf为240
}
}
/**主函数**/
void main()
{
lcdint();
while(1)
{
keyscan();
if(dis_buf!=240) // 当有键按下的时候
{
x=x+1; // 每按下一次键更新一次显示
calculate();
switch(x) // 数据的更新
{
case 2: a0=dis_buf;a1=0x20; break;
case 3: a1=a0;a0=dis_buf; break;
}
display();
dis_buf=240; // 执行完一次键值后重新给键值240
}
}
}
void calculate()
{ uchar i;
if(dis_buf==0x41) //当按键的码值是0x40(键盘上的a键)
{
lcdpos(1,0); // 则在下面一行的开始显示“+”
lcdwdata(0x2b);
display1(); // 上一组数据全部搬到上面一行显示
if(a1==0x20) a1=0x30; //如果加数是一位数则十位默认为0
date1=(a0-0x30)+(a1-0x30)*10; //计算第一个数的数值
a0=0x20;a1=0x20;
x=1;
}
if(dis_buf==0x42) // 当按键的码值是0x42(键盘上的b键)
{
lcdpos(1,0); // 则在下面一行的开始显示“=”
lcdwdata(0x3d);
if(a1==0x20) a1=0x30; //如果被加数是一位数则十位默认为0
date2=(a0-0x30)+(a1-0x30)*10; //计算第二个数的数值
date=date1+date2; // 两个数相加
shuzu[0]=date%1000/100+0x30; //百位
shuzu[1]=date%100/10+0x30; //十位
shuzu[2]=date%10+0x30; //个
lcdpos(1,1); // 把加得的数显示在“+”后面
for(i=0;i<=2;i++)
lcdwdata(shuzu[i]);
x=0;
}
}
/**显示程序1(在1602下面一行显示)**/
void display()
{
lcdpos(1,15);
lcdwdata(a0);
lcdpos(1,14);
lcdwdata(a1);
}
/**显示程序2(在上面一行显示)**/
void display1()
{
lcdpos(0,15);
lcdwdata(a0);
lcdpos(0,14);
lcdwdata(a1);
}
热心网友
时间:2023-10-19 05:22
kjhbkklllggtggggggggggggggggggddd