历史上的今天
返回首页

历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2021年12月30日 | 基于51单片机的多功能计算器,支持二八十进制小数负数计算

2021-12-30 来源:eefocus

硬件设计


工作原理

利用矩阵键盘进行按键的输入,通过对矩阵键盘的扫描,获取用户的输入,并实时的显示在1602液晶上,每次获取到输入时,根据软件设计的相应方法对输入进行处理、运算,输入结束后(以“=“为标志),将最终的运算结果输出的液晶上。

在这里插入图片描述

仿真图1: (LCD1602显示,支持负数和进制运算及有限的连续运算,连续运算时候无法识别优先级,不支持小数;)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

仿真图2: LCD1602显示,支持负数和小数及开根号,不支持连续运算;

在这里插入图片描述
在这里插入图片描述

程序设计1

#include

#include

#include

#include

#include

#include


#define u8  unsigned char

#define u16  unsigned char

sbit LCDEN=P3^4;

sbit RS=P3^5;

sbit RW=P3^6;

sbit BF=P0^7; 

sbit change_m=P3^7;


u8 code keyval[]="789/456*123-c0=+"; //按键对应的符号 

u8 data1[10];

u8 k=0;

char  m[8]={0};

double sum=0;

int flag;

void WrDatLCD(unsigned char DatVal);

void WrComLCD(unsigned char ComVal);

void delay(u16 x)   //延时x毫秒

{

u16 i,j;

for(i=0;i for(j=0;j<115;j++)

;

}

int convertBinaryToDecimal(long n)

{

int decimalNumber = 0, i = 0, remainder;

while (n != 0)

{

remainder = n % 10;

n /= 10;

decimalNumber += remainder * pow(2, i);

++i;

}

return decimalNumber;

}


int convertBinaryToDecimal8(long n)

{

int decimalNumber = 0, i = 0, remainder;

while (n != 0)

{

remainder = n % 10;

n /= 10;

decimalNumber += remainder * pow(8, i);

++i;

}

return decimalNumber;

}






u8 keypad4_4()//按键扫描函数:要去抖,若有按键按下,返回对应的按键值(0-15),没有按键按下返回16

{

u8 i,row,temp;

u8 key=16;//按键号,初值设置为16,目的是:没有按键按下时返回16;

          //若不设初值(默认值为0),没有按键按下时,将返回0,会误认为0被按下  

row=0xef; //从第一列开始      

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

{

P1=0xff;  

P1=row; //第i列信号,对应列为低,其他全为高

row=_crol_(row,1);   //生成下一列信号

temp=P1; //读入扫描信号

temp=temp&0x0f; //屏蔽高4位列信号,只保留低4位行信号 

if(temp!=0x0f)//有按键被按下,因为第i列某行有按键按下,则低4位中有一位为低  

  {  

delay(20);  //延时去抖

temp=P1;  

temp=temp&0x0f;  

if(temp!=0x0f)   //再次确认有按键被按下

  {  

        switch(temp)  //根据低4位行信号,判断哪个按键被按下

            {  

            case 0x0e:key=0+i;break; //第i列第1行按键被按下 

                case 0x0d:key=4+i;break; //第i列第2行按键被按下  

                case 0x0b:key=8+i;break; //第i列第3行按键被按下

case 0x07:key=12+i;      //第i列第4行按键被按下 

            }

do

{

temp=P1;      //再次扫描按键

  temp=temp&0x0f;  

  }while(temp!=0x0f); //等待按键释放   

  }  

     }

if(change_m == 0)

{

delay(50);

if(change_m == 0)

{

flag++;

if(flag == 3)

{

flag = 0;

}

} while(!change_m);

}




 

}  

return(key);//扫面结束,返回按键值

}


unsigned char DectectBusyBit(void)//状态判断函数(忙/闲?)

{   

bit result;

P0 = 0xff; //读状态前先置高电平,防止误判

RS = 0;

delay(5);

    RW = 1;

LCDEN = 1;

delay(5);

result=BF; //若LCM忙,则反复测试,在此处原地踏步;当LCM闲时,才往下继续

LCDEN = 0;

return result;       

}


void WrComLCD(unsigned char ComVal)//写命令函数

{

while(DectectBusyBit()==1);         //先检测LCM是否空闲

RS = 0;

delay(1);

    RW = 0;

LCDEN = 1;

P0 = ComVal;

delay(1);

LCDEN = 0;

}


void WrDatLCD(unsigned char DatVal)//写数据函数

{

while(DectectBusyBit()==1); 

RS = 1;

delay(1);

    RW = 0;

LCDEN = 1;

P0 = DatVal;

delay(1);

LCDEN = 0;

}


void LCD_Init(void)//1602初始化函数

WrComLCD(0x38);     // 功能设定:16*2行、5*7点阵、8位数据接口

WrComLCD(0x38);

WrComLCD(0x38);    

//多次重复设定功能指令,因为LCD启动后并不知道使用的是4位数据接口还是8位的,所以开始时总是默认为4位

WrComLCD(0x01);    // 清屏 

WrComLCD(0x06);    // 光标自增、屏幕不动  

delay(1);       // 延时,等待上面的指令生效,下面再显示,防止出现乱码

WrComLCD(0x0c);    // 开显示

}

 

void compute(){

u8 i,j=0,k,n=0;

char data3[3]={0};

int sum1,data2[4]={0};

int a,b,c,d,o;

int getValue[6]={0};

sum=0;


for(i=0;data1[i]!='';i++){

  if(data1[i]!='+' && data1[i]!='-' && data1[i]!='*' && data1[i]!='/'){

  data2[j] =data2[j]*10+(data1[i]-'0');


  }

  else{

  data3[n++] = data1[i];

  j++;

  } 

}

a=data2[0];

b=data2[1];

c=data2[2];

d=data2[3];

if(flag == 1)  //如果二进制

{

a=convertBinaryToDecimal(a);

b=convertBinaryToDecimal(b);

c=convertBinaryToDecimal(c);

d=convertBinaryToDecimal(d);

}

if(flag == 2)  //如果8进制

{

a=convertBinaryToDecimal8(a);

b=convertBinaryToDecimal8(b);

c=convertBinaryToDecimal8(c);

d=convertBinaryToDecimal8(d);

}


for(i=0;i if(i==0){

if(data3[0]=='+')  sum = a + b;

if(data3[0]=='-')  sum = a - b;

if(data3[0]=='*')  sum = a * b;

if(data3[0]=='/')  sum = a / (double)b; 

}

if(i==1){

if(data3[1]=='+')  sum = sum+c;

if(data3[1]=='-')  sum = sum-c;

if(data3[1]=='*')  sum = sum*c;

if(data3[1]=='/')  sum = sum/((float)c); 

}

if(i==2){

if(data3[2]=='+')  sum = sum+d;

if(data3[2]=='-')  sum = sum-d;

if(data3[2]=='*')  sum = sum*d;

if(data3[2]=='/')  sum = sum/((float)d); 

}


}


文件仅供参考:


链接:https://pan.baidu.com/s/1ZAxAbTe_oD_cuTvvKWxU5A

提取码:x102

推荐阅读

史海拾趣

Cortina Systems Inc公司的发展小趣事

由于Cortina Systems Inc公司的具体发展历程和相关故事的详细资料可能涉及公司内部的敏感信息,且具体的故事可能随着时间和市场环境的变化而有所不同,因此,我无法直接为您提供5个关于Cortina Systems Inc公司在电子行业里发展起来的具体故事。不过,我可以基于公开资料为您概述Cortina Systems Inc公司在电子行业的一些重要发展节点和事件,您可以根据这些信息进行进一步的了解和研究。

  1. 并购集通科技,拓宽业务领域

在某一时期,Cortina Systems Inc.通过并购集通科技,实现了业务领域的拓宽。集通科技是一家专注于为中小型企业和家庭网络用户提供嵌入式网络处理器、三合一整合服务(Triple Play)和网络存储解决方案的私人公司。通过这次并购,Cortina成功地将集通在中小型企业和家庭网络技术方面的优势与其通信网络基础设施环境相结合,为下一代网络使用者社群网络、多媒体传输和数字家庭连接能力的发展奠定了坚实基础。

  1. 与思科紧密合作,推动技术标准发展

在技术标准制定方面,Cortina Systems Inc.与思科展开了紧密的合作。双方共同推出了Interlaken技术规范,这一规范被视为网络处理论坛(NPF)可升级的SPI规范的竞争对手。尽管NPF与光联网论坛(OIF)合并后,Cortina与思科并未将Interlaken提交至OIF,但这一合作仍然为行业内的技术标准发展注入了新的活力。

  1. 推出双模ONU网关解决方案,满足中国市场独特需求

随着全球通信市场的不断发展,Cortina Systems Inc.针对中国市场推出了双模ONU网关解决方案。这一解决方案的推出,旨在满足中国市场对于混合式接入方式的特殊需求。在中国,三大运营商引导的接入方式既包括EPON也包括GPON,这使得双模ONU成为市场趋势。Cortina通过这一解决方案,成功地为中国市场提供了独特的、适应本土需求的通信解决方案。

  1. 技术创新能力突出,不断推出新产品

作为电子行业的领导者之一,Cortina Systems Inc.一直以其突出的技术创新能力而著称。公司不断投入研发,推出了一系列具有创新性和竞争力的新产品。这些产品不仅提升了公司的市场竞争力,也为整个电子行业的发展带来了新的机遇和挑战。

  1. 拓展全球市场,提升品牌影响力

随着业务的发展和产品线的完善,Cortina Systems Inc.逐渐将目光投向了全球市场。公司通过参加各种国际展览和会议,积极与全球合作伙伴建立联系,拓展业务领域。同时,公司还加强了品牌建设和市场推广力度,提升了在全球市场的知名度和影响力。

这些事件和节点只是Cortina Systems Inc.在电子行业发展历程中的一部分。要了解更多关于该公司的具体故事和详细发展历程,建议您查阅相关新闻报道、行业分析报告或公司官方发布的信息。通过这些资料,您可以更深入地了解Cortina Systems Inc.在电子行业中的崛起和发展。

Applied Engineering Products (AEP)公司的发展小趣事

在环保意识日益增强的今天,AEP公司积极响应国家号召,致力于绿色环保和可持续发展。公司投入大量资金研发环保型电子元器件,减少生产过程中的废弃物排放。同时,公司还建立了完善的废旧产品回收机制,对废旧产品进行环保处理,实现资源的循环利用。这一举措不仅提升了AEP公司的社会形象,也为公司的可持续发展注入了新的动力。

EVER-WAY公司的发展小趣事

随着公司规模的扩大和产品质量的提升,EVER-WAY公司开始积极拓展国内外市场。公司制定了详细的市场拓展计划,通过参加国际展会、开展国际贸易合作等方式,逐步打开了国际市场的大门。同时,公司还加强了与国内客户的合作,通过提供定制化服务、优化供应链管理等方式,赢得了客户的信任和支持。这些市场拓展的跨越不仅为公司带来了更多的商业机会,也进一步提升了公司的品牌价值和市场地位。

Alutronic Kuhlkorper Gmbh & Co Kg公司的发展小趣事

在电子行业,技术创新是企业发展的关键。EVER-WAY公司深知这一点,因此在技术研发方面投入了大量资源。公司成立了专门的研发团队,不断引进先进的生产设备和技术人才,致力于开发具有自主知识产权的电子产品。经过多年的努力,EVER-WAY公司成功推出了一系列高性能、高可靠性的电子元器件产品,获得了国内外客户的广泛认可。这些技术创新的突破不仅提升了公司的核心竞争力,也为公司带来了丰厚的经济回报。

General Industrial Controls ( GIC )公司的发展小趣事
确保所有元件均为合格产品,无损坏或老化现象。特别是电感器,其载流能力、Q值和工作频率等参数需满足要求。
Fractus公司的发展小趣事

随着技术的不断成熟和产品的市场推广,Fractus逐渐获得了业界的广泛认可。公司在多个国际展会上展示了其创新的天线技术,并赢得了多项重要奖项,包括欧洲联盟IST奖项的特等奖等。这些荣誉不仅提升了Fractus的品牌知名度,也进一步巩固了其在天线技术领域的领先地位。

问答坊 | AI 解惑

意外的惊喜!考研+就业!

考研就业专刊 考研流程+考研经验+人才招聘会+薪资洽谈+面试攻略+健康贴士+时间表…… 妹妹大餐都在这里面! 尤其适合自动化相关专业,特别版!一路陪伴从准备到结束!!! 为了节省大家的芯币 本人最新编辑了一下 把所有的东西打 ...…

查看全部问答>

request_dma()函数中第一个参数是怎么得到?

int request_dma(unsigned int dmanr, const char * device_id) 参数dmanr是从0~3、5~7里面的随便挑一个就行了么? 还是需要怎么做来得到啊…

查看全部问答>

大家给我出出主意

几个问题 1.嵌入式的前景不错嘛?酬薪怎样? 2.嵌入式工程师没有35岁瓶颈吗? 3.我是个学生,想问下培训费用大概多少钱? 4.对于现在的情况,大学生是不是很需要培训,培训的目的和作用是什么? 我是个新手,希望大家好好指导我下。谢谢。大二 ...…

查看全部问答>

ARM7中断疑惑?请哪个大虾帮忙看看。小弟不胜感激!

在ARM7下写了一个定时器中断程序。下面代码是进入IRQ中断后然后为了可重入中断,就切换到系统模式下。但是在切换的时候出现问题?如何直接MSR CPSR_C,#SYS32_MODE(1)就出现SIGBUS错误。切换代码改成MSR CPSR_C,#(SYS32_MODE|NO_INT)(2)就行了 ...…

查看全部问答>

Tornado2.2(arm)的USB2.0问题

我的Tornado2.2里为什么没有EHCI和EHCI Init组件 但是别人好像有这个组件啊,是不是序列号的问题? 而且,我在pudn上下了安装,貌似就是t22-cp1-arm.tar那个东西,但是里面还是没有啊?请问高手怎么回事情啊? http://www.pudn.com/downloads148 ...…

查看全部问答>

uCOS-II内部机制

附件中的文件非常简洁的讲述了uCOS-II的内部机制,是不错的学习OS的资料…

查看全部问答>

EZ430——Rf2500学习小感

最近刚刚入手430,原来只接触过51,不过由于430的程序大都用C写得,所以学习起来还是比较方便的。前几天一直在学习uart的输出,具体做了一个有关uart的小程序,刚开始有例程可以看,不过不知道问什么,所有的例程都无法用串口助手加以显示输出,当 ...…

查看全部问答>

中断嵌套学习一些心得

中断嵌套,优先级430总中断的控制位是状态寄存器内的GIE位(该位在SR寄存器内),该位在复位状态下,所有的可屏蔽中断都不会发生响应。可屏蔽中断又分为单中断源和多中断源的。单中断源的一般响应了中断服务程序中断标志位就自动清零,而多中断源的 ...…

查看全部问答>

求助:可以给单片机外接晶体振荡器求出该晶振频率吗?

已知一个石英晶体的谐振频率为5MHz左右(大概偏差几十Hz),想要较为准确测试出其谐振频率,可以把它作为一个晶振,接到单片机的两个晶振输入端,然后算出这个石英晶体的谐振频率么?如果可以的话,具体怎么接怎么求算?精度如何?对应的程序怎么写 ...…

查看全部问答>

CCS controlSUITE是干什么用的?

(DSP)管网上说这个是C2000系列的例程,帮助,等文件软件,反正就是学习C2000安装这个肯定有用,不知道学习C5000,安装这个有没有用???…

查看全部问答>