微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于HD7279和51单片机的计算器

基于HD7279和51单片机的计算器

时间:09-15 来源:互联网 点击:
HD7279是一款用于扩展单片机I/O口的芯片,至少我是这么认为的,虽然它占用了单片机4个I/O但是真正作为传输的仅仅是一根总线,它可以同时驱动8位共阴数码管(或者8×8点阵),及8×8的矩阵键盘,而同时接在单片机上的话,至少需要3~4组I/O,当然单总线控制的芯片基本需要自己的指令和时序。

接到这个课程设计之前我自己懒懒散散地看了一段时间的C51(用C语言编写单片机代码),之前老师教的是A51(用汇编编写单片机代码),我玩了很久,但是发现A51真的很局限,汇编这种语言是写给机器看的,真正地写0和写1,真正是一个寄存器一个寄存器的调用,对于8位的51单片机来说,要实现1000×1000或者小数是比较困难的。老师推荐用C,之前只是看书实现过一些小东西这回要做比较大的项目了,虽然还有其他课题比如温度计和数字钟,不过都做过,只是环境不一样,修改一下代码太没有挑战性了。

确实开始轻敌了,真正做的时候发现不是那么简单,

高中的时候学过一点VB做过计算器,如果让我现在做,也许给我几天我可以做出来,用C我也没什么问题,但是C51就有难度了,要考虑太多硬件的东西,特别是显示这个模块好不容易瘦下去的头又两个大了。等我真正意识到的时候,已经过去几个礼拜了,呵呵,要和朋友说抱歉了,虽然我答应“等我做完计算器之后再帮你改下程序”但是没一个实现。

当然,此程序因为基本全是自己写的,被方晋甬老师称之为“程序设计不成熟、比较乱”的,额,本来准备用switch语句,但是吕昂老师说switch语句会产生过多闲置寄存器(可是他没有考虑到我仅仅是实现很少的功能),这段程序只实现+-×÷,符号闪烁,过八位报错等功能但是没有小数,只能计算一步(加少数程序即可计算多部)。其实程序挺早就写出来了,只是一直出不来效果,后来在仿真和VC++编译环境下修改了很多,理论上是可以实现了,可是还是没有显示,于是抓狂了“看来我已处在瓶颈...”,晃了最后一个礼拜,周日周一看了两天晚上,依然没有看出什么来,礼拜二去方晋甬老师办公室请教,查了近3个钟头,在仿真多遍之后发现就少了一句“while(!key)”囧啊~~~~以至于周四答辩的时候我演示之后,刚点看ppt他就说直接给A,不用答了。。。。
程序的完整版下载地址:http://www.51hei.com/ziliao/file/jsjq.rar

/////////////////////////////****************程序*****************///////////////////////

#includereg51.h>#includemath.h>sbit  cs=P2^6;sbit clk=P1^0;sbit dat=P1^1; sbit key=P3^3; bit  add,sub,mul,div,equ,clr;unsigned char times,st,l,data_jp,flag,d;unsigned int  tmr;unsigned long    num[8],sn[8],disp[8],sh,result,hp=100000000;void send(unsigned char);unsigned char receive(void);unsigned long real(unsigned long ,unsigned char);unsigned long calcu(unsigned   long, unsigned long);void display(unsigned long);unsigned long write_key(unsigned   char);void char_flk(void);void test(void);void error(void);void long_delay(void);void short_delay(void);void delay10ms(unsigned char);  /////////**************主函数****************//////////void main (){times=0;l=times;st=0;flag=0;test();while(1){unsigned char i;if(!key){   send(0x15);data_jp=receive();cs=1;d=write_key(data_jp);if (data_jp=9){flag=0;num[times]=d;}else{flag=1;//times-=1;}if(flag!=1){ if(num[0]==0){times=0;continue;}if(7>times>=1){send(0xa1);}send(0x80);send(num[times]);while(!key); delay10ms(1);times=times+1;cs=1;if(times>7){send(0xa4);error() ;times=0;send(0xa4); }}else{send(0xa4);char_flk();times-=1;l=times;for(i=0;i=times;i++)    {num[i]=real(num[i],l);sh=sh+num[i];l--;           }sn[st]=sh;if(st>=1){result=calcu(sn[st],sn[st-1]);sn[st-1]=result;st--;           }st++;times=0;flag=0;sh=0;if(equ==1){  st=0;           send(0xa4);display(result);equ=0;}if(clr==1){st=0;times=0;flag=0;sh=0;add=0;sub=0;mul=0;div=0;equ=0;clr=0;send(0xa4);}while(!key);}}}}/////////*********************测试子函数****************////////void test(void){   char i;delay10ms(2);send(0xbf);cs=1; for (i=0;i=3;i++)    {delay10ms(100);}send(0xa4);cs=1;delay10ms(20);}
///////***********************读键盘程序**************///////unsigned long write_key(unsigned char data_jp){unsigned char shuzi;if(data_jp10){shuzi=data_jp;}else{if(data_jp==10){add=1;}else  if(data_jp==11){sub=1;}else if(data_jp==12){mul=1;}else if(data_jp==13){div=1;}else if(data_jp==14){equ=1;}else if(data_jp==15){clr=1;}shuzi=0xff;}return(shuzi) ;}///////***********************发送子函数*************//////void send(unsigned char data_out) {unsigned char i;cs=0;long_delay();for(i=0;i=7;i++){if(data_out0x80){dat=1;}else{dat=0;}clk=1;short_delay();clk=0;short_delay();data_out=data_out1;}dat=0;}/////************************接收键盘子函数************//////unsigned char receive(void){unsigned char i,data_in;dat=1;long_delay();for(i=0;i=7;i++){clk=1;short_delay();data_in=data_in1;if(dat){data_in=data_in|0x01;}else{data_in=data_in|0x00;}clk=0;short_delay();}dat=0;return(data_in);}/////////***************************显示数字处理子函数***********/////////unsigned long real(unsigned long so, unsigned char s){unsigned char z;if(s!=0){for(z=0;z=(s-1);z++){if(s!=0){so=so*10;}else{so=so;}}}else{so=so;}return(so);}//////////*************************计算子函数*******************///////////unsigned long calcu(unsigned   long    sn0,unsigned   long   sn1  ) {if(add==1){sn0=sn0+sn1;add=0;}if(sub==1){sn0=sn1-sn0;sub=0;}if(mul==1){sn0=sn0*sn1;mul=0;}if(div==1){if(sn0>0)sn0=sn1/sn0;else error();div=0;}return(sn0);}////////****************************报错错误子函数***************/////////void error(void){while(key){send(0x96);send(0x4f);delay10ms(2);send(0x95);send(0x05);delay10ms(2);send(0x94);send(0x05);delay10ms(2);send(0x93);send(0x1d);delay10ms(2);send(0x92);send(0x05);delay10ms(2);    }}///////////********************显示子函数*********////////////void display(unsigned long display){unsigned char i,asus=8;if(display>99999999)error();  else{  for(i=0;i=7;i++){if((display/hp)>=1)break;else{hp=hp/10;asus-=1;}}for(i=0;i=asus;i++){disp[i]=display/hp;if(hp>1){display=display%hp;hp=hp/10;}}for(i=0;i=asus;i++){if(i>0){ send(0xa1); }send(0x80);send(disp[i]);}}}///////////********************符号判断闪烁显示*********////////////void char_flk(void){if(add==1){send(0x97);send(0x77);}else if(sub==1){send(0x97);send(0x01);}else if(mul==1){send(0x97);send(0x37);}else if(div==1){send(0x97);send(0x49);}else if(clr){;}send(0x88);send(0x7f);}//////************************延时子函数*************///////void long_delay(void){char i;for(i=0;i=25;i++) ;}void short_delay(void){char j;for(j=0;j=4;j++);}void delay10ms(unsigned char time){unsigned char i;unsigned int j;for (i=0;i=time;i++){for(j=0;j=0x390;j++);}}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top