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();
- }
- }
復制代碼
|