標(biāo)題:
51單片機(jī)仿真,流水燈、數(shù)碼管顯示時(shí)鐘、9鍵計(jì)算機(jī)的實(shí)現(xiàn)
[打印本頁(yè)]
作者:
187777797524
時(shí)間:
2018-12-11 12:30
標(biāo)題:
51單片機(jī)仿真,流水燈、數(shù)碼管顯示時(shí)鐘、9鍵計(jì)算機(jī)的實(shí)現(xiàn)
20181211122519.png
(22.5 KB, 下載次數(shù): 47)
下載附件
2018-12-11 12:26 上傳
1.
利用
proteus把所需要的器件畫出來,把它們的端口引腳定義好連起來。
2.
流水燈接
AT89C51的P0口,在P0口接一個(gè)上拉電阻,在P3口接一個(gè)串口控制流水燈閃爍,流水燈上面接一個(gè)PNP,控制電流。計(jì)算器
按鍵
接在
P1口,用
液晶模塊
LCD1602顯示按鍵
值,
LCD1602
接
P2口。利用74LS138譯碼器和74HC245連接數(shù)碼管顯示時(shí)鐘,數(shù)碼管的位選控制端接74LS138譯碼器的Y0-Y7,74LS138譯碼器的ABC引腳接P3口,負(fù)責(zé)接收輸入的數(shù)據(jù),傳輸給Y0-Y7,顯示在數(shù)碼管上。數(shù)碼管的段選控制端接74HC245的B0-B7,74HC245的A0-A7接P0口,把接收到的信號(hào)傳輸?shù)紸0-A7,從而傳輸給數(shù)碼管的段選控制端。
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};//共陰數(shù)碼管編碼表
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個(gè)向上滅后全亮{
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.
//------------時(shí)鐘程序-----------------------
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譯碼器的引腳賦值,點(diǎn)亮數(shù)碼管
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 //時(shí)鐘中斷
{
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.
//----------計(jì)算器程序--------------------------
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); //顯示模式設(shè)置
write_com(0x0e); //顯示模式設(shè)置:顯示開,有光標(biāo),光標(biāo)不閃爍
write_com(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移
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; //設(shè)置定時(shí)器0為工作方式1
SM0=0;
SM1=1;
REN=1;
PCON=0;
TH1=0XFD;
TL1=0XFD;
TR1=1; //打開定時(shí)/計(jì)數(shù)器
EA=1; //打開總中斷
ES=1; //串行口中斷控制位,為1允許串行口中斷
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1; //定時(shí)/計(jì)數(shù)器T0中斷控制位,等于1允許中斷
TR0=1; //定時(shí)/計(jì)數(shù)器打開
init();
delay0(5);
while(1)
{
display(h,m,s);
sum();
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1