高手老手們,誰能幫我完善一下這個單片機計算器程序呀c51!我這只能算了10以內的,要能算10以外的加算法該怎么辦呀!幫下忙呀!
#include <reg52.h>
#include <intrins.h>
sbit RS=0xB0^6;
sbit RW=0xa0^5;
sbit E=0xa0^6;
#define LCM_RW RW //定義引腳
#define LCM_RS RS
#define LCM_E E
#define LCM_Data P0
#define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
unsigned char n=0;
unsigned char one[17];
unsigned char two[17];
unsigned char code jianma[16]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
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);
void disp(void)
{
DisplayListChar(0,0,one);
}
//寫數據
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) / ysC為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]!='\0') //若到達字串尾則退出
{
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--);
};
}
void dlms(void)
{
unsigned int j;
for(j=500;j>0;j--)
{}
}
unsigned char kbscan(void)
{unsigned char sccode,recode;
P1=0xf0;
if((P1&0xf0)!=0xf0)
{ dlms();
if((P1&0xf0)!=0xf0)
{sccode=0xfe;
while((sccode&0x10)!=0)
{
P1=sccode;
if((P1&0xf0)!=0xf0)
{recode=P1&0xf0;
sccode=sccode&0x0f;
wait: P1=0xf0;
if((P1&0xf0)!=0xf0)
goto wait;
else
return(sccode+recode);
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return(0) ;
}
void delay (unsigned char m) //控制頻率延時,基本延時為1ms
{
unsigned i=m;
while(--i);
}
void delayms(unsigned char a) //毫秒延時子程序
{
while(--a); //采用while(--a) 不要采用while(a--);
}
unsigned char panduanshuzi(unsigned char k)
{ unsigned char i;
switch(k)
{case 0xee:
i=1;break;
case 0xde:
i=2;break;
case 0xbe:
i=3;break;
case 0x7e:
i=4;break;
case 0xed:
i=5;break;
case 0xdd:
i=6;break;
case 0xbd:
i=7;break;
case 0x7d:
i=8;break;
case 0xeb:
i=9;break;
case 0xd7:
i=0;break;
default:i=10;
}
return(i);
}
unsigned char panduanfuhao(unsigned char m)
{ unsigned char i;
switch(m)
{case 0xdb:
i='+';break;
case 0xbb:
i='-';break;
case 0x7b:
i='*';break;
case 0xe7:
i='/';break;
default:i=0;
}
return(i);
}
main()
{unsigned char a,b,c,d,k,clr;
unsigned int a1,b1,c1,d1,e,e1,e2;
start: Delay400Ms(); //啟動等待,等LCM進入工作狀態
LCMInit(); //LCM初始化
Delay5Ms();
a=0;
b=0;
c=0;
d=0;
e=0;
a1=0;
b1=0;
c1=0;
d1=0;
e1=0;
e2=0;
k=0;
while(1)
{k=kbscan();
if(k!=0)
{a=k;
a1=panduanshuzi(a);
if(a1!=10)
{
one[0]=a1+0x30;
one[1]='\0';
DisplayListChar(0,0,one);
};
fuhao: b=kbscan();
if(b==0)
goto fuhao;
b1=panduanfuhao(b);
if(b1!=0)
{one[1]=b1;
one[2]='\0';
DisplayListChar(0,0,one);
}
secdata: c=kbscan();
if(c==0)
goto secdata;
c1=panduanshuzi(c);
if(c1!=10)
{one[2]=c1+0x30;
one[3]='\0';
DisplayListChar(0,0,one); };
equ: d=kbscan();
if (d!=0xb7)
goto equ;
one[3]='=';
switch(b1)
{case '+':
{e=a1+c1;
one[4]=' ';}
break;
case '-':
{if(a1>=c1)
{e=a1-c1;
one[4]=' ';}
else {e=c1-a1;
one[4]='-';}};break;
case '*':
{
e=a1*c1;
one[4]=' ';}break;
case '/':
{
e=a1/c1;
one[4]=' ';}break;
default:e=0;}
e1=e/10;
e2=e%10;
e1=e1+0x30;
e2=e2+0x30;
one[5]=e1;
one[6]=e2;
one[7]='\0';
DisplayListChar(0,0,one);
clr1:clr=kbscan();
if(clr!=0x77)
goto clr1;
else
{ //啟動等待,等LCM進入工作狀態
LCMInit(); //LCM初始化
Delay5Ms();
break;}
}
}
}
http://m.raoushi.com 里面也有一個計算機程序好像也不大好用。
相同位數的數相加取余為該位數字,除10為下一位數字
好長看不懂
很好 ,很強大 拷了。
從網上找的沒有實踐過;
/*--------------------------------------
計算器源程序
Calculator progarm V1.0
MCU STC89C52RC XAL 12MHz
Build by Gavin Hu, 2007.11.23
--------------------------------------*/
#include <reg51.h>
//
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define MAX_NUM 99999992.0
#define MIN_NUM -9999992.0
sbit BUZZ=P3^7;
uchar dec_flag;
void delay(uint);
void display(uchar*);
uchar key_scan(uint);
uchar add_number(uchar*,uchar);
float str2float(uchar*);
uchar float2str(uchar*,float);
float calcu(float,float,uchar);
void err_sound(void);
/*--------------------------------------
main function
--------------------------------------*/
void main(void)
{
uchar kk,mm,err,lk,d1ok,ec;
uchar dispram[9];
float d1,d2;
err=0;
d1ok=0;
ec=0;
mm=0;
dec_flag=0;
d1=0.0;
d2=0.0;
float2str(dispram,d1);
BUZZ=0;
for (kk=10;kk;kk--) display(dispram);
BUZZ=1;
while (!err)
{
display(dispram);
kk=key_scan(((uint)(P3)<<8)|P1);
if (kk!=0xff)
{
BUZZ=0;
display(dispram);
BUZZ=1;
switch (kk)
{
case 0: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,7);
lk=0; ec=0; break;
case 1: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,8);
lk=0; ec=0; break;
case 2: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,9);
lk=0; ec=0; break;
case 3: if (!d1ok) {d1=str2float(dispram); d1ok=1;}
else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);}
kk=float2str(dispram,d1);
if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;}
lk=1; mm=4; ec=0; break;
case 4: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,4);
lk=0; ec=0; break;
case 5: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,5);
lk=0; ec=0; break;
case 6: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,6);
lk=0; ec=0; break;
case 7: if (!d1ok) {d1=str2float(dispram); d1ok=1;}
else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);}
kk=float2str(dispram,d1);
if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;}
lk=1; mm=3; ec=0; break;
case 8: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,1);
lk=0; ec=0; break;
case 9: if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,2);
lk=0; ec=0; break;
case 10:if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,3);
lk=0; ec=0; break;
case 11:if (!d1ok) {d1=str2float(dispram); d1ok=1;}
else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);}
kk=float2str(dispram,d1);
if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;}
lk=1; mm=2; ec=0; break;
case 12:if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,0);
lk=0; ec=0; break;
case 13:if (lk) {float2str(dispram,0.0); dec_flag=0;}
add_number(dispram,10);
lk=0; ec=0; break;
case 14:if (!d1ok) {d1=str2float(dispram); d1ok=1;}
else if (lk!=1) {d2=str2float(dispram); d1=calcu(d1,d2,mm);}
kk=float2str(dispram,d1);
if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;}
lk=1; mm=1; ec=0; break;
case 15:if (ec==0)
{
if (!d1ok) d1=str2float(dispram);
else {d2=str2float(dispram); d1=calcu(d1,d2,mm); ec=1;}
}
else {d1=calcu(d1,d2,mm);}
kk=float2str(dispram,d1);
if ((d1==0xffffffff)||(kk==0xff)) {err=1; break;}
lk=2; d1ok=0; break;
}
while ((P1&P3)!=0xff) display(dispram);
}
}
dispram[0]=14;
for (kk=1;kk<8;kk++) dispram[kk]=17;
dispram[8]=255;
err_sound();
while (1)
{
display(dispram);
kk=key_scan(((uint)(P3)<<8)|P1);
if (kk!=0xff)
{
err_sound();
while ((P1&P3)!=0xff) display(dispram);
}
}
}
/*--------------------------------------
Delay function
Parameter: unsigned int dt
Delay time=dt(ms)
--------------------------------------*/
void delay(unsigned int dt)
{
register unsigned char bt,ct;
for (; dt; dt--)
for (ct=2;ct;ct--)
for (bt=250; --bt; );
}
/*--------------------------------------
8 LED digital tubes display function
Parameter: sting pointer to display
--------------------------------------*/
void display(uchar*disp_ram)
{
unsigned char i;
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
for (i=0;i<8;i++)
{
if (disp_ram[8]==i) P0 =table[disp_ram]&0x7f;
else P0 =table[disp_ram];
P2 =0x01<<i;
delay(2);
P0 =0xff;
P2 =0;
}
}
/*--------------------------------------
Key scan function
Parameter key port state word
Return key number,255 no key press
--------------------------------------*/
uchar key_scan(uint key_port)
{
unsigned char i;
for (i=0;i<16;i++)
{
if (!(key_port&0x0001)) return i;
key_port >>=1;
key_port |=0x8000;
}
return 0xff;
}
/*--------------------------------------
Add number (input figures) function
Parameter:pointer for result,new number
Retrun:0 fail,other ok
--------------------------------------*/
uchar add_number(uchar*ch,uchar num)
{
uchar i;
if (ch[0]!=17) return 0;
if (num==10)
if (!dec_flag)
{dec_flag=1;return 2;}
else return 0;
if ((!dec_flag)&&(ch[7]==0)&&(ch[6]==17)) {ch[7]=num;return 1;}
for (i=0;i<7;i++) ch=ch[i+1];
ch[7]=num;
ch[8]-=dec_flag;
return 1;
}
/*--------------------------------------
String to float function
Parameter:pointer of string
Return result, 0xffffffff fail
--------------------------------------*/
float str2float(uchar*ch)
{
uchar i,ng;
float dt,ft;
ng=0;
dt=0.0;
ft=1.0;
i=ch[8];
do {
if (ch>9)
{
if (ch==16) ng=1;
break;
}
dt+=ch*ft;
ft*=10.0;
} while (i--);
ft=0.1;
for (i=ch[8]+1;i<8;i++)
{
dt+=ch*ft;
ft/=10.0;
}
if (ng) dt*=-1.0;
if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xffffffff;
else return dt;
}
接下一個
由于太大只能分兩次法了
/*--------------------------------------
Float to string function
Parameter:pointer for result,data to convert
Retrun:0 ok,255 fail
--------------------------------------*/
uchar float2str(uchar*ch,float dt)
{
uchar i,ng;
float f;
if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xff;
ng=0;
if (dt<0.0) {dt*=-1.0; ng=1;}
f=10000000.0;
for (i=0;i<7;i++)
{
if ((dt/f)>=1.0) break;
else f/=10.0;
}
for (i=0;i<8;i++)
{
ch=(uchar)(dt/f);
dt -=f*ch;
if (f==1.0) {ch[8]=i;}
f/=10.0;
}
if (ch[0]>9) return 0xff;
if (ng)
{
for (i=7;i;i--) ch=ch[i-1];
ch[0]=16;
ch[8]++;
}
while ((ch[7]==0)&&(ch[8]<7))
{
for (i=7;i;i--)
{
ch=ch[i-1];
}
ch[0]=17;
ch[8]++;
}
if ((ch[6]==16)&&(ch[7]==0)) ch[6]=17;
return 0;
}
/*--------------------------------------
Calculate function
Parameter:data1,data2,mathod
Return result
--------------------------------------*/
float calcu(float a,float b,uchar m)
{
float dt;
switch (m)
{
case 1: dt=a+b; break;
case 2: dt=a-b; break;
case 3: dt=a*b; break;
case 4: if (b==0.0) return 0xffffffff;
else dt=a/b; break;
}
if ((dt>MAX_NUM)||(dt<MIN_NUM)) return 0xffffffff;
else return dt;
}
/*--------------------------------------
Err sound function
--------------------------------------*/
void err_sound(void)
{
uchar i;
BUZZ=0;
delay(500);
for (i=0;i<5;i++)
{
BUZZ=!BUZZ;
delay(100);
}
}
沒電路圖啊。。。。
| 歡迎光臨 (http://m.raoushi.com/bbs/) | Powered by Discuz! X3.1 |