基于HD7279和51单片机的计算器
接到这个课程设计之前我自己懒懒散散地看了一段时间的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++);}}
- msp430单片机+HD7279A控制数码管(IAR环境)(11-29)
- 我的HD7279学习笔记——基于msp430g2553(11-28)
- HD7279A的原理与应用(04-10)
- 关于RTX51 TINY的分析与探讨(05-30)
- 浅析8051模块化编程技巧(05-28)
- 基于DSP和单片机通信的液晶显示设计方案(07-20)