51单片机计算器 ADDA.docx

上传人:b****6 文档编号:7973238 上传时间:2023-01-27 格式:DOCX 页数:28 大小:23.51KB
下载 相关 举报
51单片机计算器 ADDA.docx_第1页
第1页 / 共28页
51单片机计算器 ADDA.docx_第2页
第2页 / 共28页
51单片机计算器 ADDA.docx_第3页
第3页 / 共28页
51单片机计算器 ADDA.docx_第4页
第4页 / 共28页
51单片机计算器 ADDA.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

51单片机计算器 ADDA.docx

《51单片机计算器 ADDA.docx》由会员分享,可在线阅读,更多相关《51单片机计算器 ADDA.docx(28页珍藏版)》请在冰豆网上搜索。

51单片机计算器 ADDA.docx

51单片机计算器ADDA

说明:

该源程序包括键盘计算器,AD总线DA总线Music播放串口收发液晶显示;

程序段均用

/*****************************************************************************/

隔开;为方便大家使用已将各程序段分开,共参考。

若需建立全部功能则分别建立各自.H文件,将它们全加入工程。

另附仿真Proteus图。

各延时程序

/*****************************************************************************/

#include

#include

#include"delay.h"

#defineucharunsignedchar

#defineuintunsignedint

voiddelay_nus(uintx)

{

while(x--);

}

voiddelay_nms(uintz)//毫秒级延时函数

{

uinti,j;

for(i=0;i

for(j=0;j<120;j++);

}

voidled_delay10ms(ucharn)

{

unsignedchara,b,c;

for(c=n;c>0;c--)

for(a=125;a>0;a--)

for(b=200;b>0;b--);

}

voidmusic_delay(uintz)//延时165MS,即十六分音符

{uintx,y;

for(x=z;x>0;x--)

for(y=19000;y>0;y--);

}

voidmusic_delay1(uintz)//延时1MS

{uintx,y;

for(x=z;x>0;x--)

for(y=112;y>0;y--);

}

/*****************************************************************************/

#include//包括一个52标准内核的头文件

#include

#include//包含有左右循环移位子函数的库

#include"adc.h"

#include"LCD1602.h"

#include"delay.h"

#defineucharunsignedchar//宏定义,定义一下方便使用

#defineuintunsignedint

#defineIN0XBYTE[0X0000]

ucharbai,shi,ge,ii=0,jieguo;

ucharxdata*ad_adr;

//=================================================

//ADC0809模数转换

//=================================================

voidADC0809_main(void)

{

ucharcun;

ad_adr=&IN0;

*ad_adr=ii;

delay_nus(1000);

jieguo=*ad_adr;//读取转换结果

jieguo=jieguo*500/255;//A/D分辨率为8位(255),转换出0-5v的实数值

cun=(unsignedchar)jieguo;

bai=(cun/100);//得到百位数

shi=cun%100/10;//得到十位数

ge=cun%10;

LCD_write_str(1,0,"value:

");

write_com(0xC0+9);

write_dat(0x30+bai);

write_dat(0x2e);//显示小数点

write_dat(0x30+shi);

write_dat(0x30+ge);

write_dat('V');

}

/*****************************************************************************/

#include

#include

#include

#include"delay.h"

#include"dac.h"

#defineucharunsignedchar

#defineuintunsignedint

#defineDAC0832XBYTE[0x7fff]

//========================================================================

//DAC0832转换函数

//========================================================================

voidDAC0832_shanjiaobo()

{

uchari,k;

for(i=0;i<100;i++)

{

for(k=0;k<255;k++)

{//k<=255,没有达到我要的三角波,而是先是一个三角波,然后是锯齿波

DAC0832=k;

}

for(k=255;k>0;k--)

{

DAC0832=k;

}

}

}

voidDAC0832_fangbo()

{

uchari;

for(i=0;i<100;i++)

{

DAC0832=0X00;//输入低电平

delay_nus(500);//延时

DAC0832=0xff;

delay_nus(500);

}

}

voiddac0832_main()

{

DAC0832_fangbo();

DAC0832_shanjiaobo();

}

/*****************************************************************************/

#include

#include"delay.h"

#include"LCD1602.h"

#include"KEY.h"

#defineucharunsignedchar

#defineuintunsignedint

ucharnum;//存放按键标识

uchardenghao=0,flag=0,fuhao,key;//denghao存放是否按下等号键,flag存放是否按下符号键,fuhao存放按下是什么符号,key存放按键ASCII码值

longa,b,c;//加数a、b结果为c

ucharcodetable[]={//键盘显示编码,加上0x30,为对应的ASCII码0x2f-0x30

7,8,9,0x2f-0x30,//1、2、3、+;0x2a-0x30

4,5,6,0x2a-0x30,//4、5、6、-;0x2d-0x30

1,2,3,0x2d-0x30,//7、8、9、*;0x2b-0x30

0x2f-0x30,0x2a-0x30,0,0x2b-0x30};//0、=、CE、/;0x01-0x30,0,0x3d-0x30,0x2f-0x30};//0、=、CE、/;

voidkeyscan()

{

uchartemp;

KEY_8=0xfe;//11111110

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

delay_nms(20);

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=KEY_8;

switch(temp)

{

case0xee:

num=0;break;//11101110

case0xde:

num=1;break;//11011110

case0xbe:

num=2;break;//10111110

case0x7e:

num=3;break;//01111110

}

while(temp!

=0xf0)//等待按键释放

{

temp=KEY_8;

temp=temp&0xf0;

}

}

if(num==0||num==1||num==2)//判断是按下1,2,3

{

if(flag==0)//如果没有按符号键,符号前的数值为a

a=a*10+table[num];

elseif(flag==1)//如果按了符号键,符号后的数值为b

b=b*10+table[num];

if(denghao==1)//如果之前按了'='号,再按键时清屏,进行下一次计算

{

denghao=0;

LCD_init();

LCD_write_str(0,0,"JIsuanqitest");

write_com(0x80+0x40);//清屏

}

}

elseif(num==3)//判断是否按下+

{

flag=1;

fuhao=4;

}

key=table[num];//显示按下的键

write_dat(0x30+key);

}

KEY_8=0xfd;//11111101

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

delay_nms(20);;

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=KEY_8;

switch(temp)

{

case0xed:

num=4;break;//11101101

case0xdd:

num=5;break;//11011101

case0xbd:

num=6;break;//10111101

case0x7d:

num=7;break;//01111101

}

while(temp!

=0xf0)//等待按键释放

{

temp=KEY_8;

temp=temp&0xf0;

}

}

if(num==4||num==5||num==6)//判断是按下4,5,6

{

if(denghao==1)//如果之前按了'='号,再按键时清屏,进行下一次计算

{

denghao=0;

LCD_init();

LCD_write_str(0,0,"JIsuanqitest");

write_com(0x80+0x40);//清屏

}

if(flag==0)//如果没有按符号键,符号前的数值为a

a=a*10+table[num];

elseif(flag==1)//如果按了符号键,符号后的数值为b

b=b*10+table[num];

}

elseif(num==7)//判断是否按下-

{

flag=1;

fuhao=3;

}

key=table[num];//显示按下的键

write_dat(0x30+key);

}

KEY_8=0xfb;//11111011

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

delay_nms(20);

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=KEY_8;

switch(temp)

{

case0xeb:

num=8;break;//11101011

case0xdb:

num=9;break;//11011011

case0xbb:

num=10;break;//10111011

case0x7b:

num=11;break;//01111011

}

while(temp!

=0xf0)

{

temp=KEY_8;

temp=temp&0xf0;

}

}

if(num==8||num==9||num==10)//判断是按下7,8,9

{

if(denghao==1)//如果之前按了'='号,再按键时清屏,进行下一次计算

{

denghao=0;

LCD_init();

LCD_write_str(0,0,"JIsuanqitest");

write_com(0x80+0x40);//清屏

}

if(flag==0)

a=a*10+table[num];//如果没有按符号键,符号前的数值为a

elseif(flag==1)

b=b*10+table[num];//如果按了符号键,符号后的数值为b

}

elseif(num==11)//判断是否按下*

{

flag=1;

fuhao=2;

}

key=table[num];

write_dat(0x30+key);

}

KEY_8=0xf7;//11110111

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

delay_nms(20);

temp=KEY_8;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=KEY_8;

switch(temp)

{

case0xe7:

num=12;break;//11100111

case0xd7:

num=13;break;//11010111

case0xb7:

num=14;break;//10110111

case0x77:

num=15;break;//01110111

}

while(temp!

=0xf0)

{

temp=KEY_8;

temp=temp&0xf0;

}

}

switch(num)

{

case13:

//按0键

{

if(denghao==1)//如果之前按了'='号,再按键时清屏,进行下一次计算

{

denghao=0;

LCD_init();

LCD_write_str(0,0,"JIsuanqitest");

write_com(0x80+0x40);//清屏

}

if(flag==0)

a=a*10;

elseif(flag==1)

b=b*10;

write_dat(0x30);

}

break;

case14:

//按=键(+、-、*、/、)

{

denghao=1;

if(fuhao==1)//如果符号键是+,执行+运算

{

write_com(0x80+0x4f);//使结果从屏幕最右下角显示出来

write_com(0x04);//从右到左显示

c=a+b;

while(c!

=0)

{

write_dat(0x30+c%10);

c=c/10;

}

write_dat(0x3d);//显示等号=

fuhao=0;

a=0;

b=0;

flag=0;

}

if(fuhao==2)//如果符号键是-,执行-运算

{

write_com(0x80+0x4f);//使结果从屏幕最右下角显示出来

write_com(0x04);

if(a>=b)

{

c=a-b;

while(c!

=0)

{

write_dat(0x30+c%10);

c=c/10;

}

}

elseif(a

{

c=b-a;

while(c!

=0)

{

write_dat(0x30+c%10);

c=c/10;

}

write_dat(0x2d);//显示负号

}

write_dat(0x3d);//显示等号=

a=0;

b=0;

flag=0;

fuhao=0;

}

if(fuhao==3)//如果符号键是*,执行*运算

{

write_com(0x80+0x4f);//使结果从屏幕右下角显示出来

write_com(0x04);

c=a*b;

while(c!

=0)

{

write_dat(0x30+c%10);

c=c/10;

}

write_dat(0x3d);//显示等号=

a=0;

b=0;

flag=0;

fuhao=0;

}

if(fuhao==4)//如果符号键是/,执行/运算

{

key=0;//小数位数

write_com(0x80+0x4f);

write_com(0x04);

if(b!

=0)c=(long)(((float)a/b)*10000);//结果保留4位小数

elseLCD_write_str(1,15,"rorre");//显示错位

while(c!

=0)

{

write_dat(0x30+c%10);

c=c/10;

key++;

if(key==4)//显示完六位小数后,显示小数点

write_dat(0x2e);//显示小数点

}

if(a/b<=0)

{

write_dat(0x30);//显示0

}

write_dat(0x3d);//显示等号

a=0;

b=0;

flag=0;

fuhao=0;

}

}

break;

case12:

{

LCD_init();

LCD_write_str(0,0,"JIsuanqitest");

write_com(0x80+0x40);//清屏

a=0;

b=0;

flag=0;

fuhao=0;

}

break;

case15:

{

flag=1;

fuhao=1;

write_dat(0x30+table[num]);

}

break;

}

}

}

voidjisuanqi_main()

{

keyscan();

}

voidint1()interrupt2

{

EX1=0;//关外部中断1

//music_delay1

(1);//去抖

EX1=1;//开外部中断1

}

/*****************************************************************************/

#include

#include"LCD1602.h"

#include"delay.h"

voidwrite_num(ucharnum)//写数据线命令(四线模式数据要分两次写)

{

LCD_date&=0x0F;//清高四位端口

LCD_date|=(num&0xF0);//写高四位数据

LCD_EN=1;//EN=1

delay_nus(5);

LCD_EN=0;//EN=0

LCD_date&=0x0F;//清高四位端口

LCD_date|=((num&0x0F)<<4);//写低四位数据

LCD_EN=1;//EN=1

delay_nus(5);

LCD_EN=0;//EN=0

}

voidwrite_com(ucharcom)//写指令

{

//check_busy();//读忙

LCD_RS=0;

//LCD_RW=0;//写入

write_num(com);

}

voidwrite_dat(uchardat)//写函数

{

//check_busy();//读忙

LCD_RS=1;

//LCD_RW=0;//写入

write_num(dat);

}

voidLCD_init(void)//LCD初始化

{

delay_nms(15);//原来1602初始化成4位数据线之前必需先初始化成8位

write_com(0x33);//(此时命令发送方式是8位格式,但数据线只需接4位),

delay_nms(5);//然后再改到4位线宽,这样初始化才稳定

write_com(0x32);

delay_nms(5);

write_com(0x28);//四线模式设置

write_com(0x0f);//显示开--对应开关显示控制指令

write_com(0x01);//清屏--对应清屏指令

delay_nms(5);

}

voidLCD_set_addr(ucharx,uchary)//写地址函数

{

if(x)

write_com(0xc0+y);//第二行显示

else

write_com(0x80+y);//第一行显示

}

voidLCD_write_char(ucharx,uchary,ucharzifu)//写字符函数

{

LCD_set_addr(x,y);

write_dat(zifu);

}

voidLCD_write_str(uc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1