for(j=0;j<57;j++)
;
}
//********液晶写入指令函数与写入数据函数************************
//每次读写指令,数据时必须判断D7是否等于0
//***************写指令寄存器***************************
voidLCMWriteC(ucharCOMData)
{ucharLCMStatus;
do
{
LCMStatus=(LCMReadCOM&busy);//判断D7是否等于1
}
while(LCMStatus!
=0);//D7等于1时继续等直到D7=0
LCMWriteCOM=COMData;//给读指令寄存器赋值(所需读写的指令)
}
//****************写数据寄存器无地址*********************
voidLCMWriteD(ucharLCMData)
{ucharLCMStatus;
do
{
LCMStatus=(LCMReadCOM&busy);//判断D7是否等于1
}
while(LCMStatus!
=0);//D7等于1时继续等直到D7=0
LCMWriteData=LCMData;//给写指令寄存器赋值(所需读写的数据)
}
//*********************LCD初始化******************************
voidLCDInit(void)
{
Delayms(15);
LCMWriteCOM=0x38;//不检测忙信号
Delayms(5);
LCMWriteCOM=0x38;//不检测忙信号
Delayms(5);
LCMWriteCOM=0x38;//不检测忙信号
Delayms(5);
LCMWriteC(0x38);//显示模式设置
LCMWriteC(0x08);//显示关闭
LCMWriteC(0x01);//显示清屏
LCMWriteC(0x06);//显示光标移动设置
LCMWriteC(0x0c);//显示开及光标设置
}
//*******************计算器**********************************
//fuhao=1按下加号fuhao=2按下减号fuhao=3按下乘号fuhao=4按下除号
//*********************键盘扫描程序第一行7,8,9,/*************************
voidkeyLine1()
{
//P1.0=0;0行有按钮按下
P1=0xfe;//P1八位的值为11111110,只有P1.0为低电平
if(P1!
=0xfe)//判断第一行是否有按钮按下
{
Delayms(20);//延时20ms消抖
if(P1!
=0xfe)//判断第一行是否有按钮按下
{
temp=P1&0xf0;
switch(temp)
{
case0xe0:
num=0;break;
case0xd0:
num=1;break;
case0xb0:
num=2;break;
case0x70:
num=3;break;
}
}
while(P1!
=0xfe);//死循环,直到我们松开按键为止
if(num==0||num==1||num==2)//如果按下的是'7','8'或'9判断按下的是哪个数
{
if(j!
=0)
{
LCMWriteC(0x01);//清屏
j=0;//只做一次清屏
}
if(flag==0)//没有按过符号键,前后按的是同一个数
{
a=a*10+table[num];//若开始按的是3,后来按的是2,则a=3*10+2=32
}
else//如果按过符号键,前后按的就是两个数
{
b=b*10+table[num];
}
}
else//如果按下的是'/'
{
flag=1;
fuhao=4;//4表示除号已按
}
i=table[num];
//显示所读到的数或符号0+i0x30为LCD中0字符对应的码
LCMWriteD(0x30+i);//若i=9则,在液晶显示屏上显示9
}
}
//**************键盘扫描程序第二行4,5,6,[*乘]**********************************
voidkeyLine2()
{
//P3.1=0;1行有按钮按下
P1=0xfd;
if(P1!
=0xfd)
{
Delayms(5);
if(P1!
=0xfd)
{
temp=P1&0xf0;
switch(temp)
{
case0xe0:
num=4;break;
case0xd0:
num=5;break;
case0xb0:
num=6;break;
case0x70:
num=7;break;
}
}
while(P1!
=0xfd);
if(num==4||num==5||num==6&&num!
=7)//如果按下的是'4','5'或'6'
{
if(j!
=0)
{
LCMWriteC(0x01);
j=0;
}
if(flag==0)//没有按过符号键
{
a=a*10+table[num];
}
else//如果按过符号键
{
b=b*10+table[num];
}
}
else//如果按下的是'/'
{
flag=1;
fuhao=3;//3表示乘号已按
}
i=table[num];
LCMWriteD(0x30+i);
}
}
//**************键盘扫描程序第三行1,2,3,-*************************************
voidkeyLine3()
{
//P3.1=0;1行有按钮按下
P1=0xfb;
if(P1!
=0xfb)
{
Delayms(5);//消抖
if(P1!
=0xfb)
{
temp=P1&0xf0;
switch(temp)
{
case0xe0:
num=8;break;
case0xd0:
num=9;break;
case0xb0:
num=10;break;
case0x70:
num=11;break;
}
}
while(P1!
=0xfb);
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
{
if(j!
=0)
{
LCMWriteC(0x01);
j=0;
}
if(flag==0)//没有按过符号键
{
a=a*10+table[num];
}
else//如果按过符号键
{
b=b*10+table[num];
}
}
elseif(num==11)//如果按下的是'-'
{
flag=1;
fuhao=2;//2表示减号已按
}
i=table[num];
LCMWriteD(0x30+i);
}
}
//*************键盘扫描程序第四行-清零,0,=,+************************************
voidkeyLine4()
{
P1=0xf7;
if(P1!
=0xf7)
{
Delayms(5);
if(P1!
=0xf7)
{
temp=P1&0xf0;
switch(temp)
{
case0xe0:
num=12;break;//清零
case0xd0:
num=13;break;//0
case0xb0:
num=14;break;//等于
case0x70:
num=15;break;//加号
}
}
while(P1!
=0xf7);
switch(num)
{
//按下的是"清零",讲计算器程序用到的参数初始化,并且将LCD也初始化
case12:
{LCMWriteC(0x01);a=0;b=0;flag=0;fuhao=0;}break;
case13:
//按下的是"0"
{
if(flag==0)//没有按过符号键
{
a=a*10+0;
LCMWriteD(0x30);//在液晶屏上显示0
P1=0;//D7=0,允许LCD读写数据
}
elseif(flag==1)//如果按过符号键
{
b=b*10+0;
LCMWriteD(0x30);//在液晶屏上显示0
}
}
break;
//fuhao=1代表按下加号fuhao=2代表按下减号fuhao=3代表按下乘号fuhao=4代表按下除号
//结果输出是从最后一位到最前面一位
case14:
{j=1;//之前按过等于号
if(fuhao==1)//按下加号键
{
LCMWriteC(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
LCMWriteC(0x04);//设置从后住前写数据,每写完一个数据,光标后退一格
c=a+b;//c是两个数相加的值结果显示是从最后一位开始写到屏幕上的从后往前写
while(c!
=0)//将C的每一位的值显示出来
{
LCMWriteD(0x30+c%10);
c=c/10;//读取c的每一位的数值
}
LCMWriteD(0x3d);//再写"="
//做完一次运算各个系数要清零
a=0;
b=0;
flag=0;
fuhao=0;
}
elseif(fuhao==2)//按下减号键
{
LCMWriteC(0x80+0x4f);//光标前进至第二行最后一个显示处
//设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
LCMWriteC(0x04);
if(a-b>0)//c是两个数相减的值结果显示是从最后一位开始写到屏幕上的从后往前写
c=a-b;
else
c=b-a;
while(c!
=0)
{
LCMWriteD(0x30+c%10);
c=c/10;
}
if(a-b<0)
LCMWriteD(0x2d);//写"-"号
LCMWriteD(0x3d);//再写"="
//做完一次运算各个系数要清零
a=0;
b=0;
flag=0;
fuhao=0;
}
elseif(fuhao==3)//按下乘号键
{
LCMWriteC(0x80+0x4f);//光标前进至第二行最后一个显示处
//设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
LCMWriteC(0x04);
//c是两个数的积结果显示是从最后一位开始写到屏幕上的从后往前写
c=a*b;
while(c!
=0)
{
LCMWriteD(0x30+c%10);
c=c/10;
}
LCMWriteD(0x3d);
//做完一次运算各个系数要清零
a=0;
b=0;
flag=0;
fuhao=0;
}
elseif(fuhao==4)
{
LCMWriteC(0x80+0x4f);//光标前进至第二行最后一个显示处
LCMWriteC(0x04);
//除法我们只保留三位小数,i为计数值,这个也可以根据自己的喜好更改
i=0;
/*除法我们只保留三位小数,所以先将(float)a/b的值乘以10003/2=1;(float)3/2=1.5*/
c=(long)(((float)a/b)*1000);
while(c!
=0)
{
LCMWriteD(0x30+c%10);
c=c/10;
i++;
if(i==3)
LCMWriteD(0x2e);//显示小数点
}
if(a/b<=0)
LCMWriteD(0x30);//显示0
LCMWriteD(0x3d);//显示等号
//做完一次运算各个系数要清零
a=0;
b=0;
flag=0;
fuhao=0;
}
}
break;
case15:
//按下加号
{
flag=1;
fuhao=1;
i=table[num];
LCMWriteD(0x30+i);
}
break;
}
}
}
//*********************键盘扫描程序*****************************************
voidkeyscan()
{
keyLine1();//扫描第一行
keyLine2();//扫描第二行
keyLine3();//扫描第三行
keyLine4();//扫描第四行
}
//**************键盘扫描参数初始化程序********************************
voidKeyInti()
{
i=0;//判断小数位数
j=0;//判断等号是否按下
a=0;//第一个参与运算的数
b=0;//第二个参与运算的数
c=0;
flag=0;//flag表示是否有符号键按下,
fuhao=0;//fuhao表征按下的是哪个符号
}
//**********************波形输出*********************************************
ucharFunctionChange=0;//这个是功能切换的参数
ucharxdata*adr;//总线中读取信息的指针
sbitchoose=P2^0;//用choose表示P2.0口
//用ifInti表示P2.0口ifInti用来控制输出波形时的LCD的初始化,ifInti=1不初始化ifInti=0初始化
sbitifInti=P2^1;
//************************锯齿波发生函数**************************************
voidsaw(void)
{
uchary;
for(y=0;y<255;y++)
{
*adr=y;//讲y的值赋给adr这个指针所指向的地址
}
}
//************************方波发生函数**************************************
voidsquare(void)
{
*adr=0X00;//输入低电平
Delayms(500);//延时
*adr=0xff;//输入高电平
Delayms(500);
}
//************************切换波形**************************************
voidChooseBo()
{
adr=&DAC0832;//将DAC0832代表的地址赋给adr这个地址DAC0832的地址内存储的是P0,P2口的数据值
if(choose==0)//判断P2.0
{
saw();//输出的为锯齿波
}
elseif(choose==1)//判断P2.0=1
{
square();//输出的为方波
}
}
//************************液晶显示波名**************************************
voidBoShow()
{
if(ifInti==0)
{
//液晶显示初始化为了防止前面写的数据没清除影响后面写到屏幕上的数据
LCDInit();
}
if(choose==0)//判断P2.0
{
//在液晶屏上显示"Saw"
LCMWriteD('S');
LCMWriteD('a');
LCMWriteD('w');
}
elseif(choose==1)//判断P2.0=1
{
//在液晶屏上显示"Square"
LCMWriteD('S');
LCMWriteD('q');
LCMWriteD('u');
LCMWriteD('a');
LCMWriteD('r');
LCMWriteD('e');
}
}
//****************电压表液晶显示**********************************************
voiddisplay(void)
{
//显示子函数
//液晶屏不能自动显示小数,我们要将其放大,读出每一位的数值,自己显示小数点
//将光标跳到液晶屏的第二行的第五位,电压表的电压值从液晶屏的第二行的第五位开始写
LCMWriteC(secondL+5);
LCMWriteD('=');//显示等于号
LCMWriteD(0x30+bai);//显示百位数(实际电压的个位)
LCMWriteD('.');//显示小数点
LCMWriteD(0x30+shi);//显示十位数(实际电压的小数点后第一位)
LCMWriteD(0x30+ge);//显示个位数(实际电压的小数点后第二位)
}
//***************************万年历********************************************
//万年历部分比较复杂,大致的过程就是从芯片里读取时间日期的信息值(BCD码的)
//装换成十进制数,然后按照位置显示出来
ucharaa,miao,shi,fen,ri,yue,nian,week,key1n,temp;
//DS1302时钟芯片与C51之间的引脚连接定义
sbitIO=P2^2;
sbitSCLK=P2^3;
sbitRST=P2^4;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H
ACC.0就是ACC的第0位。
Acc可以位寻址。
累加器ACC是一个8位的存储单元,是用来放数据的。
但是,这个存储单元有其特殊的地位,
是单片机中一个非常关键的