1. 利用proteus把所需要的器件画出来,把它们的端口引脚定义好连起来。 2. 流水灯接AT89C51的P0口,在P0口接一个上拉电阻,在P3口接一个串口控制流水灯闪烁,流水灯上面接一个PNP,控制电流。计算器按键接在P1口,用液晶模块LCD1602显示按键值,LCD1602接P2口。利用74LS138译码器和74HC245连接数码管显示时钟,数码管的位选控制端接74LS138译码器的Y0-Y7,74LS138译码器的ABC引脚接P3口,负责接收输入的数据,传输给Y0-Y7,显示在数码管上。数码管的段选控制端接74HC245的B0-B7,74HC245的A0-A7接P0口,把接收到的信号传输到A0-A7,从而传输给数码管的段选控制端。 3.头文件
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code display1[]={0x1f,0x3f,0x5f,0x7f,0x9f,0xbf,0xdf,0xff}; //74LS138:Y0~Y7亮
- uchar code table1[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e};//共阴数码管编码表
- uchar code KEY_TABLE[]={ 0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb};//键盘表
- uchar code TABLE[]={'0','1','2','3','4','5','6','7','8','9'};
- sbit lcdrs=P3^3;
- sbit lcden=P3^2;
- sbit D1=P3^4;
- sbit A1=P3^5;
- sbit B1=P3^6;
- sbit C1=P3^7;
- long op1,op2,result;
- uchar i,tmp;
- uchar key;
- uchar opp_flag=0;
- char led_flag;
- 4.
- //------流水灯程序--------------------------------
- void delay0(uchar c)
- {
- uchar a,b;
- for(a=0;a<c;a++)
- for(b=0;b<255;b++);
- }
- void led_down_shift() //流水灯下移
- {
- D1=0;
- tmp=0xfe;
- for(i=0;i<8;i++)
- {
- P0=tmp;
- delay0(500);
- tmp<<=1;
- }
- D1=1;
- }
- void led_up_shift() //流水灯上移
- {
- D1=0; //低电平有电流通过,灯亮
- tmp=0x7f;
- for(i=0;i<8;i++)
- {
- P0=tmp;
- delay0(500);
- tmp>>=1;
- }
- D1=1;
- }
- void led_mie_shift() //8个向上灭后全亮{
- D1=0;
- tmp=0xfe;
- for(i=0;i<8;i++)
- {
- P0=~tmp;
- delay0(500);
- tmp>>=1;
- P0=0x00;
- }
- delay0(500);
- D1=1;
- }
- void comm(void) interrupt 4 //流水灯中断
- {
- if(RI==1)
- {
- RI=0;
- led_flag=SBUF;
- if(led_flag=='1')
- {
- led_down_shift();
- }
- if(led_flag=='2')
- {
- led_up_shift();
- }
- if(led_flag=='3')
- {
- led_mie_shift();
- }
- }
- else{
- TI=0;
- }
- }
- 5.
- //------------时钟程序-----------------------
- void delay1(uint t)
- {
- while(t--);
- }
- void display(uchar ,uchar ,uchar);
- uint count=0;
- uchar h=12;
- uchar m=30;
- uchar s=46;
- void display(uchar hh,uchar mm,uchar ss)
- {
- uchar h_s,h_g,m_s,m_g,s_s,s_g;
- h_s=hh/10;
- h_g=hh%10;
- m_s=mm/10;
- m_g=mm%10;
- s_s=ss/10;
- s_g=ss%10;
- A1=1; //给38译码器的引脚赋值,点亮数码管
- B1=1;
- C1=1;
- P0=table1[h_s];
- delay1(10);
- A1=0;
- B1=1;
- C1=1;
- P0=table1[h_g];
- delay1(10);
- A1=0;
- B1=0;
- C1=1;
- P0=table1[m_s];
- delay1(10);
- A1=1;
- B1=1;
- C1=0;
- P0=table1[m_g];
- delay1(10);
- A1=1;
- B1=0;
- C1=0;
- P0=table1[s_s];
- delay1(10);
- A1=0;
- B1=0;
- C1=0;
- P0=table1[s_g];
- delay1(10);
- }
- void time0()interrupt 1 //时钟中断
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
- if(count>=20)
- {
- count=0;
- s++;
- if(s>=60)
- {
- s=0;
- m++;
- if(m>=60)
- {
- m=0;
- h++;
- if(h>=24)
- {
- h=0;
- }
- }
- }
- }
- }
- 6.
- //----------计算器程序--------------------------
- void delay(uchar z)
- {
- uchar y;
- for(z;z>0;z--)
- for(y=0;y<110;y++);
- }
- void write_com (uchar com)
- {
- lcdrs=0;
- P2=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_data(uchar date)
- {
- lcdrs=1;
- P2=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void init()
- {
- delay(15);
- lcden=0;
- write_com(0x38); //显示模式设置
- write_com(0x0e); //显示模式设置:显示开,有光标,光标不闪烁
- write_com(0x06); //显示模式设置:光标右移,字符不移
- write_com(0x01); //清屏幕指令
- write_com(0x80+0x00);
- }
- uchar keyscan()
- {
- uchar temp1,temp2;
- P1=0xf0; //置行为0,列为1
- if(P1!=0xf0) //有无按键被按下
- {
- delay(10);
- if(P1!=0xf0) //语句为真 则有按键被按下
- {
- temp1=P1; //读入列值
- P1=0x0f; //列 0, 行 1
- delay(3);
- temp2=P1; //读入行值
- key=temp1|temp2;
- while(P1!=0x0f);
- return key;
- }
- }
- return 0xff;
- }
- uchar key_dis()
- {
- key=keyscan();
- switch(key)
- {
- case 0xbb: write_data('+');return '+';
- case 0x7b: write_data('-');return '-';
- case 0xe7: write_data('*');return '*';
- case 0xd7: write_data('/');return '/';
- case 0xb7: write_com(0x80+0x40); write_data('=');return '=';
- case 0x77: write_com(0x01);opp_flag = 0;op1 = 0;op2 = 0;result=0;;break;// 屏幕清零
- default: break;
- }
- for(i=0;i<10;i++)
- {
- if(key==KEY_TABLE[ i])
- {
- write_data(TABLE[ i]);
- return i;
- }
- }
- return 0xff;
- }
- void sum()
- {
- uchar k=0;
- uchar arr[9];
- uchar n;
- key=key_dis();
- if((key=='+')||(key=='-')||(key=='*')||(key=='/'))
- {
- op2=op1;
- op1=0;
- opp_flag=key;
- }
- if((key >=0) && (key <= 9))
- {
- op1=op1*10+key;
- }
- if(key== '=')
- {
- write_com(0x80+0x41);
- switch(opp_flag)
- {
- case '+':result=op2+op1; break;
- case '-':result=op2-op1; break;
- case '*':result=op2*op1;break;
- case '/':result=op2/op1;break;
- default:result=0;break;
- }
- for(k=0;k<9;k++)
- {
- arr[k]=result%10;
- result=result/10;
- if(result==0)
- break;
- }
- if(k==0)
- {
- write_data(TABLE[arr[k]]);
- }
- else
- { k=k+1;
- for(n=k;n>0;n--)
- write_data(TABLE[arr[n-1]]);
- }
- }
- }
- 7.
- //------------main方法-------------------------
- void main()
- {
- TMOD=0X21; //设置定时器0为工作方式1
- SM0=0;
- SM1=1;
- REN=1;
- PCON=0;
- TH1=0XFD;
- TL1=0XFD;
- TR1=1; //打开定时/计数器
- EA=1; //打开总中断
- ES=1; //串行口中断控制位,为1允许串行口中断
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ET0=1; //定时/计数器T0中断控制位,等于1允许中断
- TR0=1; //定时/计数器打开
- init();
- delay0(5);
- while(1)
- {
- display(h,m,s);
- sum();
- }
- }
复制代码
|