1. 閃爍燈 1. 實(shí)驗(yàn)任務(wù) 如圖4.1.1所示:在P1.0端口上接一個(gè)發(fā)光二極管L1,使L1在不停地一亮一滅,一亮一滅的時(shí)間間隔為0.2秒。
2. 電路原理圖
圖4.1.1 3. 系統(tǒng)板上硬件連線 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0端口用導(dǎo)線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的L1端口上。
4. 程序設(shè)計(jì)內(nèi)容 (1).延時(shí)程序的設(shè)計(jì)方法 作為單片機(jī)的指令的執(zhí)行的時(shí)間是很短,數(shù)量大微秒級(jí),因此,我們要求的閃爍時(shí)間間隔為0.2秒,相對(duì)于微秒來(lái)說(shuō),相差太大,所以我們?cè)趫?zhí)行某一指令時(shí),插入延時(shí)程序,來(lái)達(dá)到我們的要求,但這樣的延時(shí)程序是如何設(shè)計(jì)呢?下面具體介紹其原理: 如圖4.1.1所示的石英晶體為12MHz,因此,1個(gè)機(jī)器周期為1微秒 機(jī)器周期 微秒 MOV R6,#20 2個(gè) 2 D1: MOV R7,#248 2個(gè) 2 2+2×248=498 20× DJNZ R7,$ 2個(gè) 2×248 (498 DJNZ R6,D1 2個(gè) 2×20=40 10002 因此,上面的延時(shí)程序時(shí)間為10.002ms。 由以上可知,當(dāng)R6=10、R7=248時(shí),延時(shí)5ms,R6=20、R7=248時(shí),延時(shí)10ms,以此為基本的計(jì)時(shí)單位。如本實(shí)驗(yàn)要求0.2秒=200ms,10ms×R5=200ms,則R5=20,延時(shí)子程序如下: DELAY: MOV R5,#20
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
(2). 輸出控制 如圖1所示,當(dāng)P1.0端口輸出高電平,即P1.0=1時(shí),根據(jù)發(fā)光二極管的單向?qū)щ娦钥芍@時(shí)發(fā)光二極管L1熄滅;當(dāng)P1.0端口輸出低電平,即P1.0=0時(shí),發(fā)光二極管L1亮;我們可以使用SETB P1.0指令使P1.0端口輸出高電平,使用CLR P1.0指令使P1.0端口輸出低電平。 5.程序框圖 如圖4.1.2所示 圖4.1.2 6. 匯編源程序
ORG 0
START: CLR P1.0
LCALL DELAY
SETB P1.0
LCALL DELAY
LJMP START
DELAY: MOV R5,#20 ;延時(shí)子程序,延時(shí)0.2秒
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
sbit L1=P1^0;
void delay02s(void) //延時(shí)0.2秒子程序
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
void main(void)
{
while(1)
{
L1=0;
delay02s();
L1=1;
delay02s();
} 2. 模擬開(kāi)關(guān)燈 1. 實(shí)驗(yàn)任務(wù) 如圖4.2.1所示,監(jiān)視開(kāi)關(guān)K1(接在P3.0端口上),用發(fā)光二極管L1(接在單片機(jī)P1.0端口上)顯示開(kāi)關(guān)狀態(tài),如果開(kāi)關(guān)合上,L1亮,開(kāi)關(guān)打開(kāi),L1熄滅。 2. 電路原理圖
圖4.2.1 3. 系統(tǒng)板上硬件連線 (1). 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0端口用導(dǎo)線連接到“八路發(fā)光二極管指示模塊” 區(qū)域中的L1端口上; (2). 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.0端口用導(dǎo)線連接到“四路撥動(dòng)開(kāi)關(guān)”區(qū)域中的K1端口上; 4. 程序設(shè)計(jì)內(nèi)容 (1). 開(kāi)關(guān)狀態(tài)的檢測(cè)過(guò)程 單片機(jī)對(duì)開(kāi)關(guān)狀態(tài)的檢測(cè)相對(duì)于單片機(jī)來(lái)說(shuō),是從單片機(jī)的P3.0端口輸入信號(hào),而輸入的信號(hào)只有高電平和低電平兩種,當(dāng)撥開(kāi)開(kāi)關(guān)K1撥上去,即輸入高電平,相當(dāng)開(kāi)關(guān)斷開(kāi),當(dāng)撥動(dòng)開(kāi)關(guān)K1撥下去,即輸入低電平,相當(dāng)開(kāi)關(guān)閉合。單片機(jī)可以采用JB BIT,REL或者是JNB BIT,REL指令來(lái)完成對(duì)開(kāi)關(guān)狀態(tài)的檢測(cè)即可。
(2). 輸出控制 如圖3所示,當(dāng)P1.0端口輸出高電平,即P1.0=1時(shí),根據(jù)發(fā)光二極管的單向?qū)щ娦钥芍@時(shí)發(fā)光二極管L1熄滅;當(dāng)P1.0端口輸出低電平,即P1.0=0時(shí),發(fā)光二極管L1亮;我們可以使用SETB P1.0指令使P1.0端口輸出高電平,使用CLR P1.0指令使P1.0端口輸出低電平。
5. 程序框圖
圖4.2.2 6. 匯編源程序 ORG 00H
START: JB P3.0,LIG
CLR P1.0
SJMP START
LIG: SETB P1.0
SJMP START
END 7. C語(yǔ)言源程序
#include <AT89X51.H>
sbit K1=P3^0;
sbit L1=P1^0;
void main(void)
{
while(1)
{
if(K1==0)
{
L1=0; //燈亮
}
else
{
L1=1; //燈滅
}
}
} 3. 多路開(kāi)關(guān)狀態(tài)指示 1. 實(shí)驗(yàn)任務(wù) 如圖4.3.1所示,AT89S51單片機(jī)的P1.0-P1.3接四個(gè)發(fā)光二極管L1-L4,P1.4-P1.7接了四個(gè)開(kāi)關(guān)K1-K4,編程將開(kāi)關(guān)的狀態(tài)反映到發(fā)光二極管上。(開(kāi)關(guān)閉合,對(duì)應(yīng)的燈亮,開(kāi)關(guān)斷開(kāi),對(duì)應(yīng)的燈滅)。 2. 電路原理圖 圖4.3.1 3. 系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.3用導(dǎo)線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的L1-L4端口上; (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.4-P1.7用導(dǎo)線連接到“四路撥動(dòng)開(kāi)關(guān)”區(qū)域中的K1-K4端口上; 4. 程序設(shè)計(jì)內(nèi)容 (1. 開(kāi)關(guān)狀態(tài)檢測(cè) 對(duì)于開(kāi)關(guān)狀態(tài)檢測(cè),相對(duì)單片機(jī)來(lái)說(shuō),是輸入關(guān)系,我們可輪流檢測(cè)每個(gè)開(kāi)關(guān)狀態(tài),根據(jù)每個(gè)開(kāi)關(guān)的狀態(tài)讓相應(yīng)的發(fā)光二極管指示,可以采用JB P1.X,REL或JNB P1.X,REL指令來(lái)完成;也可以一次性檢測(cè)四路開(kāi)關(guān)狀態(tài),然后讓其指示,可以采用MOV A,P1指令一次把P1端口的狀態(tài)全部讀入,然后取高4位的狀態(tài)來(lái)指示。 (2. 輸出控制 根據(jù)開(kāi)關(guān)的狀態(tài),由發(fā)光二極管L1-L4來(lái)指示,我們可以用SETB P1.X和CLR P1.X指令來(lái)完成,也可以采用MOV P1,#1111XXXXB方法一次指示。 5. 程序框圖 讀P1口數(shù)據(jù)到ACC中 <![endif]--> 圖4.3.2 6. 方法一(匯編源程序)
ORG 00H
START: MOV A,P1
ANL A,#0F0H
RR A
RR A
RR A
RR A
XOR A,#0F0H
MOV P1,A
SJMP START
END
7. 方法一(C語(yǔ)言源程序)
#include <AT89X51.H>
unsigned char temp;
void main(void)
{
while(1)
{
temp=P1>>4;
temp=temp | 0xf0;
P1=temp;
}
}
8. 方法二(匯編源程序)
ORG 00H
START: JB P1.4,NEXT1
CLR P1.0
SJMP NEX1
NEXT1: SETB P1.0
NEX1: JB P1.5,NEXT2
CLR P1.1
SJMP NEX2
NEXT2: SETB P1.1
NEX2: JB P1.6,NEXT3
CLR P1.2
SJMP NEX3
NEXT3: SETB P1.2
NEX3: JB P1.7,NEXT4
CLR P1.3
SJMP NEX4
NEXT4: SETB P1.3
NEX4: SJMP START
END
9. 方法二(C語(yǔ)言源程序)
#include <AT89X51.H>
void main(void)
{
while(1)
{
if(P1_4==0)
{
P1_0=0;
}
else
{
P1_0=1;
}
if(P1_5==0)
{
P1_1=0;
}
else
{
P1_1=1;
}
if(P1_6==0)
{
P1_2=0;
}
else
{
P1_2=1;
}
if(P1_7==0)
{
P1_3=0;
}
else
{
P1_3=1;
}
}
} 4. 廣告燈的左移右移 1. 實(shí)驗(yàn)任務(wù) 做單一燈的左移右移,硬件電路如圖4.4.1所示,八個(gè)發(fā)光二極管L1-L8分別接在單片機(jī)的P1.0-P1.7接口上,輸出“0”時(shí),發(fā)光二極管亮,開(kāi)始時(shí)P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0亮,重復(fù)循環(huán)。 2. 電路原理圖 圖4.4.1 3. 系統(tǒng)板上硬件連線 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.7用8芯排線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的L1-L8端口上,要求:P1.0對(duì)應(yīng)著L1,P1.1對(duì)應(yīng)著L2,……,P1.7對(duì)應(yīng)著L8。 4. 程序設(shè)計(jì)內(nèi)容 我們可以運(yùn)用輸出端口指令MOV P1,A或MOV P1,#DATA,只要給累加器值或常數(shù)值,然后執(zhí)行上述的指令,即可達(dá)到輸出控制的動(dòng)作。 每次送出的數(shù)據(jù)是不同,具體的數(shù)據(jù)如下表1所示 表1 5.程序框圖 圖4.4.2 6. 匯編源程序
ORG 0
START: MOV R2,#8
MOV A,#0FEH
SETB C
LOOP: MOV P1,A
LCALL DELAY
RLC A
DJNZ R2,LOOP
MOV R2,#8
LOOP1: MOV P1,A
LCALL DELAY
RRC A
DJNZ R2,LOOP1
LJMP START
DELAY: MOV R5,#20 ;
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char i;
unsigned char temp;
unsigned char a,b;
void delay(void)
{
unsigned char m,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
void main(void)
{
while(1)
{
temp=0xfe;
P1=temp;
delay();
for(i=1;i<8;i++)
{
a=temp<<i;
b=temp>>(8-i);
P1=a|b;
delay();
}
for(i=1;i<8;i++)
{
a=temp>>i;
b=temp<<(8-i);
P1=a|b;
delay();
}
}
} 5. 廣告燈(利用取表方式) 1. 實(shí)驗(yàn)任務(wù) 利用取表的方法,使端口P1做單一燈的變化:左移2次,右移2次,閃爍2次(延時(shí)的時(shí)間0.2秒)。
2. 電路原理圖
圖4.5.1 3. 系統(tǒng)板上硬件連線 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.7用8芯排線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的L1-L8端口上,要求:P1.0對(duì)應(yīng)著L1,P1.1對(duì)應(yīng)著L2,……,P1.7對(duì)應(yīng)著L8。 4. 程序設(shè)計(jì)內(nèi)容 在用表格進(jìn)行程序設(shè)計(jì)的時(shí)候,要用以下的指令來(lái)完成 (1). 利用MOV DPTR,#DATA16的指令來(lái)使數(shù)據(jù)指針寄存器指到表的開(kāi)頭。 (2). 利用MOVC A,@A+DPTR的指令,根據(jù)累加器的值再加上DPTR的值,就可以使程序計(jì)數(shù)器PC指到表格內(nèi)所要取出的數(shù)據(jù)。 因此,只要把控制碼建成一個(gè)表,而利用MOVC 工,@A+DPTR做取碼的操作,就可方便地處理一些復(fù)雜的控制動(dòng)作,取表過(guò)程如下圖所示: 5.程序框圖
圖4.5.2
6. 匯編源程序
ORG 0
START: MOV DPTR,#TABLE
LOOP: CLR A
MOVC A,@A+DPTR
CJNE A,#01H,LOOP1
JMP START
LOOP1: MOV P1,A
MOV R3,#20
LCALL DELAY
INC DPTR
JMP LOOP
DELAY: MOV R4,#20
D1: MOV R5,#248
DJNZ R5,$
DJNZ R4,D1
DJNZ R3,DELAY
RET
TABLE: DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
DB 07FH,0BFH,0DFH,0EFH
DB 0F7H,0FBH,0FDH,0FEH
DB 07FH,0BFH,0DFH,0EFH
DB 0F7H,0FBH,0FDH,0FEH
DB 00H, 0FFH,00H, 0FFH
DB 01H
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char code table[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f,
0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe,
0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe,
0x00,0xff,0x00,0xff,
0x01};
unsigned char i;
void delay(void)
{
unsigned char m,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
void main(void)
{
while(1)
{
if(table[ i]!=0x01)
{
P1=table[ i];
i++;
delay();
}
else
{
i=0;
}
}
6. 報(bào)警產(chǎn)生器 1. 實(shí)驗(yàn)任務(wù) 用P1.0輸出1KHz和500Hz的音頻信號(hào)驅(qū)動(dòng)揚(yáng)聲器,作報(bào)警信號(hào),要求1KHz信號(hào)響100ms,500Hz信號(hào)響200ms,交替進(jìn)行,P1.7接一開(kāi)關(guān)進(jìn)行控制,當(dāng)開(kāi)關(guān)合上響報(bào)警信號(hào),當(dāng)開(kāi)關(guān)斷開(kāi)告警信號(hào)停止,編出程序。 2. 電路原理圖
圖4.6.1 3. 系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0端口用導(dǎo)線連接到“音頻放大模塊”區(qū)域中的SPK IN端口上; (2. 在“音頻放大模塊”區(qū)域中的SPK OUT端口上接上一個(gè)8歐的或者是16歐的喇叭; (3. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.7/RD端口用導(dǎo)線連接到“四路撥動(dòng)開(kāi)關(guān)”區(qū)域中的K1端口上; 4. 程序設(shè)計(jì)內(nèi)容 (1. 信號(hào)產(chǎn)生的方法 500Hz信號(hào)周期為2ms,信號(hào)電平為每1ms變反1次,1KHz的信號(hào)周期為1ms,信號(hào)電平每500us變反1次;
5. 程序框圖
圖4.6.2 6. 匯編源程序
FLAG BIT 00H
ORG 00H
START: JB P1.7,START
JNB FLAG,NEXT
MOV R2,#200
DV: CPL P1.0
LCALL DELY500
LCALL DELY500
DJNZ R2,DV
CPL FLAG
NEXT: MOV R2,#200
DV1: CPL P1.0
LCALL DELY500
DJNZ R2,DV1
CPL FLAG
SJMP START
DELY500: MOV R7,#250
LOOP: NOP
DJNZ R7,LOOP
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
#include <INTRINS.H>
bit flag;
unsigned char count;
void dely500(void)
{
unsigned char i;
for(i=250;i>0;i--)
{
_nop_();
}
}
void main(void)
{
while(1)
{
if(P1_7==0)
{
for(count=200;count>0;count--)
{
P1_0=~P1_0;
dely500();
}
for(count=200;count>0;count--)
{
P1_0=~P1_0;
dely500();
dely500();
}
}
}
}
7. I/O并行口直接驅(qū)動(dòng)LED顯示 1. 實(shí)驗(yàn)任務(wù) 如圖13所示,利用AT89S51單片機(jī)的P0端口的P0.0-P0.7連接到一個(gè)共陰數(shù)碼管的a-h(huán)的筆段上,數(shù)碼管的公共端接地。在數(shù)碼管上循環(huán)顯示0-9數(shù)字,時(shí)間間隔0.2秒。 2. 電路原理圖 圖4.7.1 3. 系統(tǒng)板上硬件連線 把“單片機(jī)系統(tǒng)”區(qū)域中的P0.0/AD0-P0.7/AD7端口用8芯排線連接到“四路靜態(tài)數(shù)碼顯示模塊”區(qū)域中的任一個(gè)數(shù)碼管的a-h(huán)端口上;要求:P0.0/AD0與a相連,P0.1/AD1與b相連,P0.2/AD2與c相連,……,P0.7/AD7與h相連。 4. 程序設(shè)計(jì)內(nèi)容 (1. LED數(shù)碼顯示原理 七段LED顯示器內(nèi)部由七個(gè)條形發(fā)光二極管和一個(gè)小圓點(diǎn)發(fā)光二極管組成,根據(jù)各管的極管的接線形式,可分成共陰極型和共陽(yáng)極型。 LED數(shù)碼管的g~a七個(gè)發(fā)光二極管因加正電壓而發(fā)亮,因加零電壓而不以發(fā)亮,不同亮暗的組合就能形成不同的字形,這種組合稱之為字形碼,下面給出共陰極的字形碼見(jiàn)表2 “0”
| 3FH
|
| “8”
| 7FH
|
| “1”
| 06H
|
| “9”
| 6FH
|
| “2”
| 5BH
|
| “A”
| 77H
|
| “3”
| 4FH
|
| “b”
| 7CH
|
| “4”
| 66H
|
| “C”
| 39H
|
| “5”
| 6DH
|
| “d”
| 5EH
|
| “6”
| 7DH
|
| “E”
| 79H
|
| “7”
| 07H
|
| “F”
| 71H
|
|
(2. 由于顯示的數(shù)字0-9的字形碼沒(méi)有規(guī)律可循,只能采用查表的方式來(lái)完成我們所需的要求了。這樣我們按著數(shù)字0-9的順序,把每個(gè)數(shù)字的筆段代碼按順序排好!建立的表格如下所示:TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 5.程序框圖 圖4.7.2 6. 匯編源程序
ORG 0
START: MOV R1,#00H
NEXT: MOV A,R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
INC R1
CJNE R1,#10,NEXT
LJMP START
DELAY: MOV R5,#20
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char dispcount;
void delay02s(void)
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
void main(void)
{
while(1)
{
for(dispcount=0;dispcount<10;dispcount++)
{
P0=table[dispcount];
delay02s();
}
}
} 8. 按鍵識(shí)別方法之一 1. 實(shí)驗(yàn)任務(wù) 每按下一次開(kāi)關(guān)SP1,計(jì)數(shù)值加1,通過(guò)AT89S51單片機(jī)的P1端口的P1.0到P1.3顯示出其的二進(jìn)制計(jì)數(shù)值。
2. 電路原理圖
圖4.8.1 3. 系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.7/RD端口連接到“獨(dú)立式鍵盤(pán)”區(qū)域中的SP1端口上; (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.4端口用8芯排線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的“L1-L8”端口上;要求,P1.0連接到L1,P1.1連接到L2,P1.2連接到L3,P1.3連接到L4上。 4. 程序設(shè)計(jì)方法 (1. 其實(shí),作為一個(gè)按鍵從沒(méi)有按下到按下以及釋放是一個(gè)完整的過(guò)程,也就是說(shuō),當(dāng)我們按下一個(gè)按鍵時(shí),總希望某個(gè)命令只執(zhí)行一次,而在按鍵按下的過(guò)程中,不要有干擾進(jìn)來(lái),因?yàn)椋诎聪碌倪^(guò)程中,一旦有干擾過(guò)來(lái),可能造成誤觸發(fā)過(guò)程,這并不是我們所想要的。因此在按鍵按下的時(shí)候, 圖4.8.2 要把我們手上的干擾信號(hào)以及按鍵的機(jī)械接觸等干擾信號(hào)給濾除掉,一般情況下,我們可以采用電容來(lái)濾除掉這些干擾信號(hào),但實(shí)際上,會(huì)增加硬件成本及硬件電路的體積,這是我們不希望,總得有個(gè)辦法解決這個(gè)問(wèn)題,因此我們可以采用軟件濾波的方法去除這些干擾信號(hào),一般情況下,一個(gè)按鍵按下的時(shí)候,總是在按下的時(shí)刻存在著一定的干擾信號(hào),按下之后就基本上進(jìn)入了穩(wěn)定的狀態(tài)。具體的一個(gè)按鍵從按下到釋放的全過(guò)程的信號(hào)圖如上圖所示: 從圖中可以看出,我們?cè)诔绦蛟O(shè)計(jì)時(shí),從按鍵被識(shí)別按下之后,延時(shí)5ms以上,從而避開(kāi)了干擾信號(hào)區(qū)域,我們?cè)賮?lái)檢測(cè)一次,看按鍵是否真得已經(jīng)按下,若真得已經(jīng)按下,這時(shí)肯定輸出為低電平,若這時(shí)檢測(cè)到的是高電平,證明剛才是由于干擾信號(hào)引起的誤觸發(fā),CPU就認(rèn)為是誤觸發(fā)信號(hào)而舍棄這次的按鍵識(shí)別過(guò)程。從而提高了系統(tǒng)的可靠性。
由于要求每按下一次,命令被執(zhí)行一次,直到下一次再按下的時(shí)候,再執(zhí)行一次命令,因此從按鍵被識(shí)別出來(lái)之后,我們就可以執(zhí)行這次的命令,所以要有一個(gè)等待按鍵釋放的過(guò)程,顯然釋放的過(guò)程,就是使其恢復(fù)成高電平狀態(tài)。
(1. 對(duì)于按鍵識(shí)別的指令,我們依然選擇如下指令JB BIT,REL指令是用來(lái)檢測(cè)BIT是否為高電平,若BIT=1,則程序轉(zhuǎn)向REL處執(zhí)行程序,否則就繼續(xù)向下執(zhí)行程序。或者是 JNB BIT,REL指令是用來(lái)檢測(cè)BIT是否為低電平,若BIT=0,則程序轉(zhuǎn)向REL處執(zhí)行程序,否則就繼續(xù)向下執(zhí)行程序。 (2. 但對(duì)程序設(shè)計(jì)過(guò)程中按鍵識(shí)別過(guò)程的框圖如右圖所示: 圖4.8.3 5. 程序框圖 圖4.8.4 6. 匯編源程序
ORG 0
START: MOV R1,#00H ;初始化R7為0,表示從0開(kāi)始計(jì)數(shù)
MOV A,R1 ;
CPL A ;取反指令
MOV P1,A ;送出P1端口由發(fā)光二極管顯示
REL: JNB P3.7,REL ;判斷SP1是否按下
LCALL DELAY10MS ;若按下,則延時(shí)10ms左右
JNB P3.7,REL ;再判斷SP1是否真得按下
INC R7 ;若真得按下,則進(jìn)行按鍵處理,使
MOV A,R7 ;計(jì)數(shù)內(nèi)容加1,并送出P1端口由
CPL A ;發(fā)光二極管顯示
MOV P1,A ;
JNB P3.7,$ ;等待SP1釋放
SJMP REL ;繼續(xù)對(duì)K1按鍵掃描
DELAY10MS: MOV R6,#20 ;延時(shí)10ms子程序
L1: MOV R7,#248
DJNZ R7,$
DJNZ R6,L1
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char count;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
while(1)
{
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
count++;
if(count==16)
{
count=0;
}
P1=~count;
while(P3_7==0);
}
}
}
}
9. 一鍵多功能按鍵識(shí)別技術(shù) 1.實(shí)驗(yàn)任務(wù) 如圖4.9.1所示,開(kāi)關(guān)SP1接在P3.7/RD管腳上,在AT89S51單片機(jī)的P1端口接有四個(gè)發(fā)光二極管,上電的時(shí)候,L1接在P1.0管腳上的發(fā)光二極管在閃爍,當(dāng)每一次按下開(kāi)關(guān)SP1的時(shí)候,L2接在P1.1管腳上的發(fā)光二極管在閃爍,再按下開(kāi)關(guān)SP1的時(shí)候,L3接在P1.2管腳上的發(fā)光二極管在閃爍,再按下開(kāi)關(guān)SP1的時(shí)候,L4接在P1.3管腳上的發(fā)光二極管在閃爍,再按下開(kāi)關(guān)SP1的時(shí)候,又輪到L1在閃爍了,如此輪流下去。
2.電路原理圖
圖4.9.1 3.系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.7/RD端口連接到“獨(dú)立式鍵盤(pán)”區(qū)域中的SP1端口上; (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.4端口用8芯排線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的“L1-L8”端口上;要求,P1.0連接到L1,P1.1連接到L2,P1.2連接到L3,P1.3連接到L4上。 4.程序設(shè)計(jì)方法 (1. 設(shè)計(jì)思想由來(lái) 在我們生活中,我們很容易通過(guò)這個(gè)叫張三,那個(gè)叫李四,另外一個(gè)是王五;那是因?yàn)槊總(gè)人有不同的名子,我們就很快認(rèn)出,同樣,對(duì)于要通過(guò)一個(gè)按鍵來(lái)識(shí)別每種不同的功能,我們給每個(gè)不同的功能模塊用不同的ID號(hào)標(biāo)識(shí),這樣,每按下一次按鍵,ID的值是不相同的,所以單片機(jī)就很容易識(shí)別不同功能的身份了。
(2. 設(shè)計(jì)方法 從上面的要求我們可以看出,L1到L4發(fā)光二極管在每個(gè)時(shí)刻的閃爍的時(shí)間是受開(kāi)關(guān)SP1來(lái)控制,我們給L1到L4閃爍的時(shí)段定義出不同的ID號(hào),當(dāng)L1在閃爍時(shí),ID=0;當(dāng)L2在閃爍時(shí),ID=1;當(dāng)L3在閃爍時(shí),ID=2;當(dāng)L4在閃爍時(shí),ID=3;很顯然,只要每次按下開(kāi)關(guān)K1時(shí),分別給出不同的ID號(hào)我們就能夠完成上面的任務(wù)了。下面給出有關(guān)程序設(shè)計(jì)的框圖。
5.程序框圖
圖4.9.2
6. 匯編源程序
ID EQU 30H
SP1 BIT P3.7
L1 BIT P1.0
L2 BIT P1.1
L3 BIT P1.2
L4 BIT P1.3
ORG 0
MOV ID,#00H
START: JB K1,REL
LCALL DELAY10MS
JB K1,REL
INC ID
MOV A,ID
CJNE A,#04,REL
MOV ID,#00H
REL: JNB K1,$
MOV A,ID
CJNE A,#00H,IS0
CPL L1
LCALL DELAY
SJMP START
IS0: CJNE A,#01H,IS1
CPL L2
LCALL DELAY
SJMP START
IS1: CJNE A,#02H,IS2
CPL L3
LCALL DELAY
SJMP START
IS2: CJNE A,#03H,IS3
CPL L4
LCALL DELAY
SJMP START
IS3: LJMP START
DELAY10MS: MOV R6,#20
LOOP1: MOV R7,#248
DJNZ R7,$
DJNZ R6,LOOP1
RET
DELAY: MOV R5,#20
LOOP2: LCALL DELAY10MS
DJNZ R5,LOOP2
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char ID;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void delay02s(void)
{
unsigned char i;
for(i=20;i>0;i--)
{delay10ms();
}
}
void main(void)
{ while(1)
{ if(P3_7==0)
{delay10ms();
if(P3_7==0)
{
ID++;
if(ID==4)
{
ID=0;
}
while(P3_7==0);
}
}
switch(ID)
{ case 0:
P1_0=~P1_0;
delay02s();
break;
case 1:
P1_1=~P1_1;
delay02s();
break;
case 2:
P1_2=~P1_2;
delay02s();
break;
case 3:
P1_3=~P1_3;
delay02s();
break;
}
}
}
10. 00-99計(jì)數(shù)器 1. 實(shí)驗(yàn)任務(wù) 利用AT89S51單片機(jī)來(lái)制作一個(gè)手動(dòng)計(jì)數(shù)器,在AT89S51單片機(jī)的P3.7管腳接一個(gè)輕觸開(kāi)關(guān),作為手動(dòng)計(jì)數(shù)的按鈕,用單片機(jī)的P2.0-P2.7接一個(gè)共陰數(shù)碼管,作為00-99計(jì)數(shù)的個(gè)位數(shù)顯示,用單片機(jī)的P0.0-P0.7接一個(gè)共陰數(shù)碼管,作為00-99計(jì)數(shù)的十位數(shù)顯示;硬件電路圖如圖19所示。
2. 電路原理圖
圖4.10.1 3. 系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P0.0/AD0-P0.7/AD7端口用8芯排線連接到“四路靜態(tài)數(shù)碼顯示模塊”區(qū)域中的任一個(gè)a-h(huán)端口上;要求:P0.0/AD0對(duì)應(yīng)著a,P0.1/AD1對(duì)應(yīng)著b,……,P0.7/AD7對(duì)應(yīng)著h。 (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P2.0/A8-P2.7/A15端口用8芯排線連接到“四路靜態(tài)數(shù)碼顯示模塊”區(qū)域中的任一個(gè)數(shù)碼管的a-h(huán)端口上; (3. 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.7/RD端口用導(dǎo)線連接到“獨(dú)立式鍵盤(pán)”區(qū)域中的SP1端口上; 4. 程序設(shè)計(jì)內(nèi)容 (1. 單片機(jī)對(duì)按鍵的識(shí)別的過(guò)程處理 (2. 單片機(jī)對(duì)正確識(shí)別的按鍵進(jìn)行計(jì)數(shù),計(jì)數(shù)滿時(shí),又從零開(kāi)始計(jì)數(shù); (3. 單片機(jī)對(duì)計(jì)的數(shù)值要進(jìn)行數(shù)碼顯示,計(jì)得的數(shù)是十進(jìn)數(shù),含有十位和個(gè)位,我們要把十位和個(gè)位拆開(kāi)分別送出這樣的十位和個(gè)位數(shù)值到對(duì)應(yīng)的數(shù)碼管上顯示。如何拆開(kāi)十位和個(gè)位我們可以把所計(jì)得的數(shù)值對(duì)10求余,即可個(gè)位數(shù)字,對(duì)10整除,即可得到十位數(shù)字了。 (4. 通過(guò)查表方式,分別顯示出個(gè)位和十位數(shù)字。 5.程序框圖
圖4.10.2
6. 匯編源程序
Count EQU 30H
SP1 BIT P3.7
ORG 0
START: MOV Count,#00H
NEXT: MOV A,Count
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
WT: JNB SP1,WT
WAIT: JB SP1,WAIT
LCALL DELY10MS
JB SP1,WAIT
INC Count
MOV A,Count
CJNE A,#100,NEXT
LJMP START
DELY10MS: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Count;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
Count=0;
P0=table[Count/10];
P2=table[Count%10];
while(1)
{
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
Count++;
if(Count==100)
{
Count=0;
}
P0=table[Count/10];
P2=table[Count%10];
while(P3_7==0);
}
}
}
}
11. 00-59秒計(jì)時(shí)器(利用軟件延時(shí)) 1. 實(shí)驗(yàn)任務(wù) 如下圖所示,在AT89S51單片機(jī)的P0和P2端口分別接有兩個(gè)共陰數(shù)碼管,P0口驅(qū)動(dòng)顯示秒時(shí)間的十位,而P2口驅(qū)動(dòng)顯示秒時(shí)間的個(gè)位。 2. 電路原理圖
圖4.11.1 3. 系統(tǒng)板上硬件連線 (1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P0.0/AD0-P0.7/AD7端口用8芯排線連接到“四路靜態(tài)數(shù)碼顯示模塊”區(qū)域中的任一個(gè)a-h(huán)端口上;要求:P0.0/AD0對(duì)應(yīng)著a,P0.1/AD1對(duì)應(yīng)著b,……,P0.7/AD7對(duì)應(yīng)著h。 (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P2.0/A8-P2.7/A15端口用8芯排線連接到“四路靜態(tài)數(shù)碼顯示模塊”區(qū)域中的任一個(gè)a-h(huán)端口上;要求:P2.0/A8對(duì)應(yīng)著a,P2.1/A9對(duì)應(yīng)著b,……,P2.7/A15對(duì)應(yīng)著h。 4. 程序設(shè)計(jì)內(nèi)容 (1. 在設(shè)計(jì)過(guò)程中我們用一個(gè)存儲(chǔ)單元作為秒計(jì)數(shù)單元,當(dāng)一秒鐘到來(lái)時(shí),就讓秒計(jì)數(shù)單元加1,當(dāng)秒計(jì)數(shù)達(dá)到60時(shí),就自動(dòng)返回到0,從新秒計(jì)數(shù)。 (2. 對(duì)于秒計(jì)數(shù)單元中的數(shù)據(jù)要把它十位數(shù)和個(gè)數(shù)分開(kāi),方法仍采用對(duì)10整除和對(duì)10求余。 (3. 在數(shù)碼上顯示,仍通過(guò)查表的方式完成。 (4. 一秒時(shí)間的產(chǎn)生在這里我們采用軟件精確延時(shí)的方法來(lái)完成,經(jīng)過(guò)精確計(jì)算得到1秒時(shí)間為1.002秒。 DELY1S: MOV R5,#100
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
5. 程序框圖
圖4.11.2
6. 匯編源程序
Second EQU 30H
ORG 0
START: MOV Second,#00H
NEXT: MOV A,Second
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
LCALL DELY1S
INC Second
MOV A,Second
CJNE A,#60,NEXT
LJMP START
DELY1S: MOV R5,#100
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Second;
void delay1s(void)
{
unsigned char i,j,k;
for(k=100;k>0;k--)
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
Second=0;
P0=table[Second/10];
P2=table[Second%10];
while(1)
{
delay1s();
Second++;
if(Second==60)
{
Second=0;
}
P0=table[Second/10];
P2=table[Second%10];
}
}
12. 可預(yù)置可逆4位計(jì)數(shù)器 1. 實(shí)驗(yàn)任務(wù) 利用AT89S51單片機(jī)的P1.0-P1.3接四個(gè)發(fā)光二極管L1-L4,用來(lái)指示當(dāng)前計(jì)數(shù)的數(shù)據(jù);用P1.4-P1.7作為預(yù)置數(shù)據(jù)的輸入端,接四個(gè)撥動(dòng)開(kāi)關(guān)K1-K4,用P3.6/WR和P3.7/RD端口接兩個(gè)輕觸開(kāi)關(guān),用來(lái)作加計(jì)數(shù)和減計(jì)數(shù)開(kāi)關(guān)。具體的電路原理圖如下圖所示
2. 電路原理圖
圖4.12.1 3. 系統(tǒng)板上硬件連線
(1. 把“單片機(jī)系統(tǒng)”區(qū)域中的P1.0-P1.3端口用8芯排線連接到“八路發(fā)光二極管指示模塊”區(qū)域中的L1-L4上;要求:P1.0對(duì)應(yīng)著L1,P1.1對(duì)應(yīng)著L2,P1.2對(duì)應(yīng)著L3,P1.3對(duì)應(yīng)著L4; (2. 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.0/RXD,P3.1/TXD,P3.2/INT0,P3.3/INT1用導(dǎo)線連接到“四路撥動(dòng)開(kāi)關(guān)”區(qū)域中的K1-K4上; (3. 把“單片機(jī)系統(tǒng)”區(qū)域中的P3.6/WR,P3.7/RD用導(dǎo)線連接到“獨(dú)立式鍵盤(pán)”區(qū)域中的SP1和SP2上; 4. 程序設(shè)計(jì)內(nèi)容 (1. 兩個(gè)獨(dú)立式按鍵識(shí)別的處理過(guò)程; (2. 預(yù)置初值讀取的問(wèn)題 (3. LED輸出指示 5. 程序框圖
圖4.12.2
6. 匯編源程序
COUNT EQU 30H
ORG 00H
START: MOV A,P3
ANL A,#0FH
MOV COUNT,A
MOV P1,A
SK2: JB P3.6,SK1
LCALL DELY10MS
JB P3.6,SK1
INC COUNT
MOV A,COUNT
CJNE A,#16,NEXT
MOV A,P3
ANL A,#0FH
MOV COUNT,A
NEXT: MOV P1,A
WAIT: JNB P3.6,WAIT
LJMP SK2
SK1: JB P3.7,SK2
LCALL DELY10MS
JB P3.7,SK2
DEC COUNT
MOV A,COUNT
CJNE A,#0FFH,NEX
MOV A,P3
ANL A,#0FH
MOV COUNT,A
NEX: MOV P1,A
WAIT2: JNB P3.7,WAIT2
LJMP SK2
DELY10MS: MOV R6,#20
MOV R7,#248
D1: DJNZ R7,$
DJNZ R6,D1
RET
END
7. C語(yǔ)言源程序
#include <AT89X51.H>
unsigned char curcount;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
curcount=P3 & 0x0f;
P1=~curcount;
while(1)
{
if(P3_6==0)
{
delay10ms();
if(P3_6==0)
{
if(curcount>=15)
{
curcount=15;
}
else
{
curcount++;
}
P1=~curcount;
while(P3_6==0);
}
}
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
if(curcount<=0)
{
curcount=0;
}
else
{
curcount--;
}
P1=~curcount;
while(P3_7==0);
}
}
}
}
Word下載(帶圖片):http://m.zg4o1577.cn/bbs/dpj-91484-1.html
|