MSC51編程題知識(shí)匯總
仿真電路如題13圖所示,編寫程序,使圖中的發(fā)光二極管D1閃爍10次后熄滅。
?
題13圖 使發(fā)光二極管D1閃爍的電路
答:#include <reg52.h>
#define uint unsigned int
sbit D1=P1^0;?
void main(void)
{uint i,j,k;
for(k=10;k>0;k--)
????{ ??D1=0;?
????????for(i=0;i<1000;i++)
????????for(j=0;j<110;j++);
????????D1=1;?
????????for(i=0;i<1000;i++)
????????for(j=0;j<110;j++); ??}
while(1);?
}
14. 用AT89C51單片機(jī)的P2口控制一個(gè)共陽極7段LED數(shù)碼管,電路如題14圖所示,請?jiān)谙铝谐绦蛑械冖倏仗帲来螌懗鍪构碴枠O7段LED數(shù)碼管顯示0~9的十個(gè)段碼,再在主程序第②、③空處編寫相應(yīng)的語句,實(shí)現(xiàn)LED數(shù)碼管循環(huán)顯示0~9的功能。
?
題14圖??用AT89C51單片機(jī)P2口控制共陽極7段LED數(shù)碼管的電路
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define out P2
uchar code seg[]={①0xc0,0xF9,0xa4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x01}; //0~9共陽極段碼表
void delayms(uint);
void main(void)
{uchar i;
while(1)
{
②out=seg[i]; //P2口循環(huán)輸出0~9共陽極段碼表
delayms(900);
i++;
if(seg[i]==0x01) ③i=0; ??// 如段碼為0x01,表明一個(gè)循環(huán)顯示已結(jié)束
}
}
void delayms(uint j) ? ?// 延時(shí)函數(shù)
{uchar i;
for(;j>0;j--)
?? { ?i=250;
??? ? while(--i);
??? ? i=249;
??? ? while(--i);
??? }
}
14. 8位一體共陽極8段LED數(shù)碼管和單片機(jī)的連接電路如題15圖所示,請?jiān)谙铝谐绦蛑械冖倏仗?,依次寫出使共陽極8段LED數(shù)碼管顯示1~9以及0的十個(gè)段碼,再在主程序第②、③、④空處編寫相應(yīng)的語句,使8位數(shù)碼管從左到右分別滾動(dòng)顯示單個(gè)數(shù)字1~8,即程序運(yùn)行后,單片機(jī)控制左邊第1個(gè)數(shù)碼管顯示1,其他不顯示,延時(shí)之后,控制左邊第2個(gè)數(shù)碼管顯示2,其他不顯示,直至第8個(gè)數(shù)碼管顯示8,其他不顯示,反復(fù)循環(huán)上述過程。
?
題15圖?8位一體共陽極8段LED數(shù)碼管和單片機(jī)的連接電路
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code dis_code[]={①0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc0,0x88 }; //共陽極8段LED數(shù)碼管段碼表
void ?delay(uint t) ???????//延時(shí)函數(shù)
{ ??uchar i;
while(t--) for(i=0;i<200;i++);
}
void ?main()
{ ?uchar i,j=0x80;
?????while(1)
???????{ for(i=0;i<8;i++)
{
??????②j=_crol_(j,1);// ?將對象j循環(huán)左移1位
??????③P0=dis_code[i]; //P0口輸出段碼
??????④P2=j; //P2口輸出位控碼
???????delay(180); ?//延時(shí),控制每位顯示的時(shí)間
}
???????}
}
16. 單片機(jī)控制8個(gè)發(fā)光二極管的電路如題16圖,8個(gè)發(fā)光二極管D1~D8經(jīng)限流電阻分別接至P1口的P1.0~P1.7引腳上,二極管陽極共同接高電平。在下列程序的第①~⑤空處編寫相應(yīng)的語句控制發(fā)光二極管由上至下反復(fù)循環(huán)流水點(diǎn)亮,每次點(diǎn)亮一個(gè)發(fā)光二極管。
?
題16圖?單片機(jī)控制8個(gè)發(fā)光二極管的電路
#①include <reg51.h> ??????//包含51單片機(jī)的頭文件
#②include <intrins.h> ?//包含移位函數(shù)_crol_( ?)的頭文件
#define uchar unsigned char ??? ?
#define uint unsigned int ??? ?
void ?delay(uint i) ?? //延時(shí)函數(shù)
{
uchar t;
? while (i--)
{ ? for(t=0;t<120;t++); ?}
}
void ?main( ?) ? ?//主程序
{
③P1=0xfe; ?//向P1口送出點(diǎn)亮數(shù)據(jù)
??? while (1)
??? { ?
④?delay( 500 ); ?//調(diào)用延時(shí)函數(shù)
⑤P1=_crol_(P1,1); ??//將P1中的數(shù)據(jù)循環(huán)左移1位
??? }
}
?
17. 單片機(jī)鍵控電路如題17圖所示,P1.0和P1.1引腳接有兩只開關(guān)S0和S1,兩引腳上的高低電平共4種組合,4種組合分別點(diǎn)亮P2.0~P2.3引腳控制的4只LED,即S0、S1均閉合,LED0亮,其余滅;S1閉合、S0打開,LED1亮,其余滅;S0閉合、S1打開,LED2亮,其余滅;S0、S1均打開,LED3亮,其余滅。在下列程序的第①~⑤空處編寫相應(yīng)的語句實(shí)現(xiàn)題目要求的控制功能。
?
題17圖?單片機(jī)鍵控電路
答:
#include <reg51.h> ? // 包含頭文件reg51.h
void ?main( ?) ? //主函數(shù)main( )
{
char state;
? do
? {
P1=0xff; ? ?// P1口為輸入
? ?state=P1; ? ????// 讀入P1口的狀態(tài),送入state
? ?①?state=state&0x03; ?? ?// 屏蔽P1口的高6位
? ?switch (state) ? // 判P1口低2位開關(guān)狀態(tài)
? ?{
②?case 0: P2=0x01; break;// P1.1、P1.0=00,點(diǎn)亮P2.0腳LED
? ? ③?case 1: P2=0x02; break; // P1.1、P1.0=01,點(diǎn)亮P2.1腳LED
? ? ④?case 2: P2=0x04; break; // P1.1、P1.0=10,點(diǎn)亮P2.2腳LED
? ? ⑤?case 3: P2=0x08; break; // P1.1、P1.0=11,點(diǎn)亮P2.3腳LED
? ?}
? }while ( 1 );
?
18.仿真電路如下圖所示,編寫程序,將開關(guān)K的閉合和打開情況用二極管表示,即當(dāng)K1閉合時(shí),D1亮,K1打開時(shí),D1不亮,當(dāng)K2閉合時(shí),D2亮,K2打開時(shí),D2不亮,依此類推,試編寫程序。
?
鍵控發(fā)光二極管的電路
程序設(shè)計(jì)如下:(編程題答案不唯一,酌情扣分)
#include <reg51.h>
sbit D1=P1^0;
sbit D2=P1^1;
sbit D3=P1^2;
sbit D4=P1^3;
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;
void main()
{
unsigned char k;
while(1)?
{
D1=K1;
D2=K2;
D3=K3;
D4=K4;
}
}
?
?
19. 仿真電路如題19圖所示,P2.0~2.3上接了四個(gè)按鍵,P3口上接了共陽極LED顯示器,試編寫程序,在LED顯示器上將按下的鍵值顯示出來。
?
題19圖?獨(dú)立式按鍵與單片機(jī)的接口(采用查詢方式)
答:#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
int xx; ?????????????? ??
void delay(int k) //延時(shí)函數(shù)
{ ???int i;
????for(i=0;i<k;i++); ?}
void main()
{ ??P2=0xFF;
????P3=0xFF; ??//為輸入鍵值做準(zhǔn)備
????while(1)
?????{ while(P2==0xFF) //若無鍵按下,循環(huán)等待
????????{;}
???????if(P2!=0xFF) //有鍵按下,延時(shí)去抖動(dòng)
???????delay(10);
???????if(P2!=0xFF)
{ ?xx=P2; //有鍵按下,根據(jù)鍵值進(jìn)行顯示
??switch(xx)
????{ case 0xFE: ??P3=0xC0;break;
?????case 0xFD: ??P3=0xF9;break;
?????case 0xFB: ??P3=0xA4;break;
?????case 0xF7: ??P3=0xB0;break;
?????default: ????P3=0xFF;break; ??} ??}
?????while(P2!=0xFF) //等待按鍵松開
???{;}
?}
}
18. 電路如題18圖所示,要求單片機(jī)的主程序?qū)崿F(xiàn)P1口控制一個(gè)共陰極數(shù)碼管的各段依次點(diǎn)亮,不斷循環(huán),當(dāng)有外中斷輸入時(shí),使數(shù)碼管顯示8,閃爍4次后,返回原斷點(diǎn)處繼續(xù)執(zhí)行程序,外中斷的觸發(fā)方式采用邊沿觸發(fā)方式。試編寫程序。
?
題18圖?單片機(jī)外中斷應(yīng)用系統(tǒng)電路圖
答:#include<reg51.h> ???
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar i,aa;
void delay(uint z);
void main() ?????????????
{
EA=1; ?//開總中斷
EX1=1; ?//開外部中斷1
IT1=1; ?//將外部中斷1設(shè)為邊沿觸發(fā)方式 ?
aa=0x01;
P3=0xff;
while(1)
{ P1=aa; ? //送入段選信號(hào)
delay(1000);
aa=_crol_(aa,1); //將aa循環(huán)左移1位后再賦給aa
} ??}
void delay(uint z) ????????????
{ uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--); ?}
void exter0( ) interrupt 2 ??????
{ ?for(i=4;i>0;i--)
{ P1=0x3f; ?//送入段選信號(hào)7f,使數(shù)碼管顯示8
delay(500);
P1=0x00; ?//送入段選信號(hào)00,使數(shù)碼管熄滅
delay(500); ?}
}
19.?電路如題19圖所示,要求單片機(jī)主程序控制P2口所接的8段共陽極數(shù)碼管各段依次循環(huán)點(diǎn)亮,當(dāng)外部中斷輸入出現(xiàn)從高到低的負(fù)跳變時(shí),數(shù)碼管開始亮滅閃爍顯示“0”,閃爍顯示8次后,8段數(shù)碼管的各段繼續(xù)依次循環(huán)點(diǎn)亮。試編寫程序,實(shí)現(xiàn)上述功能。
?
題19圖 單片機(jī)外中斷應(yīng)用系統(tǒng)
答:#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar i,aa;
void delay(uint z);
void main() ???????
{ EA=1; ?//開總中斷
EX0=1; ?//開外部中斷0
IT0=1; ?//將外部中斷0設(shè)為邊沿觸發(fā)方式 ?
aa=0xfe;
????????P3=0xff;
while(1)
{
P2=aa; ? //送入段選信號(hào)
delay(1000);
aa=_crol_(aa,1); //將aa循環(huán)左移1位后再賦給aa
}
}
void delay(uint z) ????
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void exter0( ) interrupt 0 ?
{
for(i=8;i>0;i--)
{ P2=0x3f; ?//送入段選信號(hào)3f,使數(shù)碼管顯示0
delay(500);
P2=0x00; ?//送入段選信號(hào)00,使數(shù)碼管熄滅
delay(500);
} ?
}
20. 電路連接如題20圖所示,編程實(shí)現(xiàn)下列要求:在平時(shí)狀態(tài)下,8個(gè)發(fā)光二極管以200ms的時(shí)間間隔,依次點(diǎn)亮。在中斷時(shí)亮一半,暗一半;在中斷時(shí)全滅,中斷為高優(yōu)先級,中斷為低優(yōu)先級。
題20圖 采用中斷控制二極管點(diǎn)亮的電路
答:程序如下:
#include <reg51.h> ??
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar i,j,aa;
void delay(uint z) ??
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void init() ???????
{
IT0=1; ??//INT0邊沿觸發(fā)
IT1=1; ??//INTl邊沿觸發(fā)
EA=1; ??//開總中斷
EX0=1; ?//使能INT0
EX1=1; ?//使能INTl
PX0=1; ?//中斷0優(yōu)先
}
void main() ?????
{
init();
aa=0x01;
while(1)
{ ??
???????? ?P2=aa;
delay(200);
aa=_crol_(aa,1);//aa循環(huán)左移一位 ? ?
}
}
void int0() interrupt 0
{
for(i=8;i>0;i--)
{
P2=0x00; ??//P2口送出00H使燈熄滅,循環(huán)8次
delay(500); ? ?
} ?
}
void int1() interrupt 2
{
for(j=8;j>0;j--)
{
P2=0x0f; ?//低4位亮,高四位暗
delay(500);
P2=0xf0; ?//低4位暗,高四位亮
delay(500);
} ?
}
12. AT89C51單片機(jī)控制P2口所接8只LED數(shù)碼管的電路如題12圖所示,要求用單片機(jī)定時(shí)器T0,采用方式1,定時(shí)中斷方式,使P2口所接的8只LED每0.5s閃爍亮一次。計(jì)算與定時(shí)器工作方式控制寄存器TMOD、控制寄存器TCON、計(jì)數(shù)寄存器TH0、TL0及中斷允許寄存器IE中各位的值,要求寫出計(jì)算過程,同時(shí)完成實(shí)現(xiàn)上述要求功能的程序編寫。
?
題12圖AT89C51單片機(jī)控制P2口所接8只LED數(shù)碼管的電路
附:TMOD及TCON控制字的格式如下:
答:(1)TMOD寄存器的設(shè)置
T0工作在方式1,應(yīng)使TMOD寄存器的M1、M0=01;應(yīng)設(shè)置C/T=0,為定時(shí)器模式;對T0的運(yùn)行控制僅由TR0來控制,應(yīng)使相應(yīng)的GATE位為0。定時(shí)器T1不使用,各相關(guān)位均設(shè)為0。所以,TMOD寄存器應(yīng)初始化為0x01。
(2)計(jì)算定時(shí)器T0的計(jì)數(shù)初值
設(shè)定時(shí)時(shí)間5ms(即5000μs),設(shè)T0計(jì)數(shù)初值為X,假設(shè)晶振的頻率為11.0592MHz,則定時(shí)時(shí)間為:
定時(shí)時(shí)間=(216?X)×12/晶振頻率
則 ?5000=(216??X) ×12/11.059?2
????得 ?X = 60928
????轉(zhuǎn)換成十六進(jìn)制:0xee00,其中0xee裝入TH0,0x00裝入TL0。
(3)設(shè)置IE寄存器
由于采用定時(shí)器T0中斷,因此需將IE寄存器中的EA、ET0位置1。
(4)啟動(dòng)和停止定時(shí)器T0
????將定時(shí)器控制寄存器TCON中的TR0=1,則啟動(dòng)定時(shí)器T0;TR0=0,則停止定時(shí)器T0定時(shí)。
參考程序:
#include<reg51.h>
char ?i=100; ????????//
void main () ?
{ TMOD=0x01; ? //定時(shí)器T0為方式1
TH0=0xee; ? //設(shè)置定時(shí)器初值,定時(shí)器每5ms中斷一次
TL0=0x00;
????P2=0x00; ? ?//P2口8個(gè)LED點(diǎn)亮
EA=1; ? ? //總中斷開
ET0=1; ? ? //開T0中斷
TR0=1; ? ? //啟動(dòng)T0
while(1); ? ?//循環(huán)等待
{ ?; }
}
void timer0() interrupt 1 ? //T0中斷程序,每5ms中斷一次
{ TH0=0xee; ? ?//重新賦初值
TL0=0x00;
i--; ? ? //循環(huán)次數(shù)減1
if(i<=0)
{
P2=~P2; ? ????// 中斷100次,達(dá)到0.5s,P2口按位取反
i=100; ? ?//重置循環(huán)次數(shù)
}
}
13. 電路如題13圖所示,在AT89C51單片機(jī)的P1口上接了8只LED,T1(P3.5)引腳接了一只按鍵開關(guān),要求定時(shí)器T1采用計(jì)數(shù)模式,方式1中斷,使輸入引腳T1引腳上外接按鈕開關(guān)作為計(jì)數(shù)信號(hào)輸入。按4次按鈕開關(guān)后,P1口的8只LED閃爍不停。計(jì)算與定時(shí)器有關(guān)的工作方式控制寄存器TMOD、控制寄存器TCON、計(jì)數(shù)寄存器TH1、TL1及中斷允許寄存器IE的值,寫出計(jì)算過程,編寫實(shí)現(xiàn)上述功能的程序。
?
題13圖?AT89C51單片機(jī)控制8只LED電路
答:
(1) 設(shè)置TMOD寄存器
T1工作在方式1,應(yīng)使TMOD的M1、M0=01;設(shè)置C/T*=1,為計(jì)數(shù)器模式;對T0運(yùn)行控制僅由TR0來控制,應(yīng)使GATE0=0。定時(shí)器T0不使用,各相關(guān)位均設(shè)為0。所以,TMOD寄存器應(yīng)初始化為0x50。
(2) 計(jì)算定時(shí)器T1的計(jì)數(shù)初值
由于每按1次按鈕開關(guān),計(jì)數(shù)1次,按4次后,P1口的8只LED閃爍不停。因此計(jì)數(shù)器初值為65?536?4=65?532,將其轉(zhuǎn)換成十六進(jìn)制后為0xfffc,所以,TH0=0xff,TL0=0xfc。
(3)設(shè)置IE寄存器
本例由于采用T1中斷,因此需將IE寄存器的EA、ET1位置1。
(4)啟動(dòng)和停止定時(shí)器T1
將寄存器TCON中TR1=1,則啟動(dòng)T1計(jì)數(shù);TR1=0,則停止T1計(jì)數(shù)。
程序如下:
??#include <reg51.h>
????void Delay(unsigned int i) ?//定義延時(shí)函數(shù)Delay( )
{ unsigned int j; ?
for(;i>0;i--)
for(j=0;j<125;j++) ?
{;} ? ?//空函數(shù)
?}
void ?main( ) ? //主函數(shù)
?{
TMOD=0x50; ? //設(shè)置定時(shí)器T1為方式1計(jì)數(shù)
TH1=0xff; ? //向TH1寫入初值的高8位
TL1=0xfc; ? //向TL1寫入初值的低8位
EA=1; ??? ? //總中斷允許
ET1=1; ?? ? //定時(shí)器T1中斷允許 ?
? TR1=1; ?? ? //啟動(dòng)定時(shí)器T1
? while(1) ; ??? //無窮循環(huán),等待計(jì)數(shù)中斷
?}
?
void T1_int(void) ?interrupt 3 ? //T1中斷函數(shù)
{
for(;;) ? ?//無限循環(huán)
? {
P1=0xff; ?//8位LED全滅
? ?Delay(500) ; ?//延時(shí)500ms
? ?P1=0; ? //8位LED全亮
? ?Delay(500); ??//延時(shí)500ms
} ? ? ?
}
14.原理電路如題14圖所示,在單片機(jī)P1口上接有8只LED。在外部中斷0輸入引腳(P3.2)接一只按鈕開關(guān)K1。要求將外部中斷0設(shè)置為電平觸發(fā)。程序啟動(dòng)時(shí),P1口上的8只LED全亮。每按一次按鈕開關(guān)K1,使引腳接地,產(chǎn)生一個(gè)低電平觸發(fā)的外中斷請求,在中斷服務(wù)程序中,讓低4位的LED與高4位的LED交替閃爍5次,中斷結(jié)束后,控制8只LED再次全亮,請編寫相應(yīng)的控制程序。
?
題14圖?單片機(jī)控制發(fā)光二極管電路
答:程序如下:
#include <reg51.h>??????????????????
#define uchar ?unsigned char
void Delay(unsigned int i) //延時(shí)函數(shù),
{ unsigned int j;
for(;i > 0;i--) ?
for(j=0;j<333;j++) ????????//晶振為12MHz,j選擇與晶振頻率有關(guān)
{;} ? ???//空函數(shù)
}
void ?main( ) ? //主函數(shù)
{ EA=1; ? //總中斷允許 ???
EX0=1; ? //允許外部中斷0中斷
IT0=1; ? //選擇外部中斷0為跳沿觸發(fā)方式
while(1) ?//循環(huán) ?
{ P1=0;} ? // P1口的8只LED全亮 ???
}
void int0( ) ?interrupt 0 ?using 0 ? //外中斷0的中斷服務(wù)函數(shù)
{
uchar ?m;
EX0=0; ? //禁止外部中斷0中斷
for(m=0;m<5;m++) //交替閃爍5次
{
P1=0x0f; ?//低4位LED滅,高4位LED亮
Delay(400) ; ?//延時(shí)
P1=0xf0; ?//高4位LED滅,低4位LED亮
Delay(400); ??//延時(shí)
EX0=1; ? //中斷返回前,打開外部中斷0中斷
}
?
15. 已知晶振頻率fosc=12MHz,使用定時(shí)器T1使P2.0引腳產(chǎn)生100ms的方波程序,計(jì)算TH1、TL1、TMOD寄存器的值,并編寫對定時(shí)器1進(jìn)行初始化的程序。
附:TMOD及TCON控制字的格式如下:
?
答:分析:方波的周期為100ms,要求高、低電平的持續(xù)時(shí)間各為50ms,采用定時(shí)器定時(shí),中斷工作方式。每50ms時(shí)間到時(shí),在中斷服務(wù)程序中將P2.0引腳電平狀態(tài)取反,即可獲得所需要的波形。晶振頻率fosc=12MHz,Tcy=12/fosc=1μs ,選擇定時(shí)器T1的方式1。
(1) 確定計(jì)算初值
(2n-x)×Tcy=(216-x)×1μs =50ms,
x=65536-50000=15536=3CB0H
即TH1=3CH,TL1=B0H ?
(2) TMOD寄存器初始化
GATE (TMOD.7)=0, (TMOD.6)=0,M1 (TMOD.5)=0,M0 (TMOD.4)=1,定時(shí)器/計(jì)數(shù)器0沒有使用,相應(yīng)的各個(gè)位狀態(tài)隨意,均取為0,則(TMOD)=10H。
(3) 程序如下:
#include<reg51.h>
#define uint unsigned int
sbit fangbo=P2^0;
void main()
{
TMOD=0x10; //設(shè)置T1為定時(shí)器模式,工作在方式1
TH1=0x3C;
TL1= 0xB0;
EA=1; //開總中斷
ET1=1; //允許T1中斷
TR1=1; // 啟動(dòng)T1
while(1);
}
void timer1() interrupt 3 ?//定時(shí)器1中斷服務(wù)程序
{ TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
fangbo=~fangbo; ?}
16. 已知晶振頻率fosc=12MHz,要求定時(shí)器0產(chǎn)生10ms的定時(shí)時(shí)間,計(jì)算與定時(shí)器有關(guān)的工作方式控制寄存器TMOD、控制寄存器TCON及計(jì)數(shù)寄存器TH、TL中各位的值,并編寫對定時(shí)器0進(jìn)行初始化的程序。
答:由于晶振頻率為12MHz,機(jī)器周期Tcy=1μs,選用方式0時(shí)最大定時(shí)時(shí)間8.192ms,選擇方式1時(shí),最大定時(shí)時(shí)間為65.536ms,要求的定時(shí)時(shí)間為10ms,所以不能選擇方式0,只能選用方式1。
(1) 計(jì)算TH0、TL0的計(jì)數(shù)初值 ??
由于晶振頻率為12MHz,所以機(jī)器周期Tcy=1μs,則定時(shí)時(shí)間為:
T=(2n-x)×Tcy=(216-x)×1μs =10ms,
所以x=65536-10000=55536=D8F0H
即TH0=D8H,TL0=F0H,或者TH0=55536/256,TL0=55536%256
(2) TMOD寄存器初始化 ??
根據(jù)題目要求,GATE (TMOD.3)=0, (TMOD.2)=0,M1 (TMOD.1)=0,M0
?(TMOD.0)=1,定時(shí)器/計(jì)數(shù)器1沒有使用,相應(yīng)的各個(gè)位狀態(tài)隨意,均取為
0,則(TMOD)=01H。
(3) 初始化程序 ???????
void init_time0(void)
{
TMOD=0x01; ????????????//設(shè)置T0為定時(shí)器模式,工作在方式1
TH0=(65536-10000)/256; ???//設(shè)置TH0和TL0的計(jì)數(shù)初值
TL0=(65536-10000)%256;
??? TR0=1; ?????????????????// 啟動(dòng)T0
}
?
17. 設(shè)單片機(jī)系統(tǒng)時(shí)鐘頻率為12MHz,波形發(fā)生器電路如題17圖所示,要使P2.0引腳上輸出一個(gè)周期為2ms的方波,計(jì)算計(jì)數(shù)寄存器TH、TL的值,并編寫程序?qū)崿F(xiàn)上述功能。
?
題17圖?波形發(fā)生器電路
答:(1) 計(jì)算TH0、TL0的計(jì)數(shù)初值 ?
要在P2.0上產(chǎn)生周期為2ms的方波,定時(shí)器應(yīng)產(chǎn)生1ms的定時(shí)中斷,定時(shí)時(shí)間到則在中斷服務(wù)程序中對P2.0求反。使用定時(shí)器T0,方式1定時(shí)中斷,GATE不起作用。
設(shè)T0的初值為X,有
??????(216?X )×1×10?6=1×10?3
即 ???65536?X=1000
得X=64536,化為16進(jìn)制數(shù)就是0xfc18。將高8位0xfc裝入TH0,低8位0x18裝入TL0。
(2) TMOD寄存器初始化 ??
GATE (TMOD.3)=0, (TMOD.2)=0,M1 (TMOD.1)=1,M0 (TMOD.0)=0,定時(shí)器/計(jì)數(shù)器1沒有使用,相應(yīng)的各個(gè)位狀態(tài)隨意,均取為0,則(TMOD)=01H。
(3) 程序編寫 ????????
#include <reg51.h> ?? //頭文件reg51.h
sbit P2_0=P2^0; ? //定義特殊功能寄存器P1的位變量P1_0
void main(void) ? //主程序
{
TMOD=0x01; ?//設(shè)置T0為方式1
TR0=1; ? //接通T0
while(1) ?//無限循環(huán)
{
TH0=0xfc; ?//置T0高8位初值
TL0=0x18; ?//置T0低8位初值
do{}while(!TF0); ???????//TF0為0原地循環(huán),為1則T0溢出,往下執(zhí)行
P2_0=!P2_0; ?// P2.0狀態(tài)求反
TF0=0; ? //TF0標(biāo)志清零
}
}
?
18. 已知晶振頻率fosc=12MHz,要求用定時(shí)0每隔200μs產(chǎn)生一定時(shí)信號(hào),計(jì)算與定時(shí)器有關(guān)的工作方式控制寄存器TMOD、控制寄存器TCON、計(jì)數(shù)寄存器TH、TL,并對定時(shí)器進(jìn)行初始化編程。
解:選擇定時(shí)器0,工作在方式2。
(1) 計(jì)算TH0、TL0的計(jì)數(shù)初值 ?
由于晶振頻率為12MHz,所以機(jī)器周期Tcy=1μs,則
(2n-x)×Tcy=(28-x)×1μs =200μs,所以x=256-200=56=38H
即TH0=38H,TL0=38H ?
或者TH0=(256-200) %256,TL0=(256-200)%256。
(2) TMOD寄存器初始化 ?
GATE (TMOD.3)=0, (TMOD.2)=0,M1 (TMOD.1)=1,M0
?(TMOD.0)=0,定時(shí)器/計(jì)數(shù)器1沒有使用,相應(yīng)的各個(gè)位狀態(tài)隨
意,均取為0,則(TMOD)=02H。
(3) 初始化程序 ????????
void init_time0(void)
{
TMOD=0x02; //設(shè)置T0為定時(shí)器模式,工作在方式1
TH0=0x38; ?//設(shè)置TH0和TL0的計(jì)數(shù)初值
TL0=0x38;
??? TR0=1; ?// 啟動(dòng)T0
}
13. 對AT89C51單片機(jī)外擴(kuò)一片RAM 62256芯片,請?jiān)O(shè)計(jì)電路連接圖,畫出AT89C51、74LS373與62256之間的連接電路,計(jì)算62256存儲(chǔ)器的地址范圍。
答:?62256地址線有15條(A14~A0),片選信號(hào)CE接地,芯片地址范圍為0000H~7FFFH。
單片機(jī)與存儲(chǔ)器的連接電路如下圖所示。
?
采用線選法擴(kuò)展一片62256的電路連接
14. 對AT89C51單片機(jī)外擴(kuò)展兩片16kB的RAM 62128芯片,用線選法進(jìn)行兩片62128的片選,畫出題14圖所示電路中各芯片之間的連接,計(jì)算出兩片62128的地址范圍。
答:擴(kuò)展的電路連接如圖9所示。62128(1)芯片存儲(chǔ)單元的地址變化范圍為:1000 0000 0000 0000B~1011 1111 1111 1111B,即8000H~BFFFH,62128(2)芯片存儲(chǔ)單元的地址變化范圍為:0100 0000 0000 0000B~0111 1111 1111 1111B,即4000H~7FFFH。
?
題14圖?AT89C51外擴(kuò)兩片62128的電路連接
15. 對AT89C51單片機(jī)外擴(kuò)展兩片16kB的RAM 62128芯片,用譯碼法進(jìn)行兩片62128的片選,畫出AT89C51、74LS373、74LS139與62128之間的連接圖,計(jì)算兩片62128的地址范圍。
答:擴(kuò)展的電路連接如下圖所示。
?
AT89C51外擴(kuò)2片62128的電路連接
62128芯片中存儲(chǔ)單元的地址變化范圍為:xx00 0000 0000 0000B~xx11 1111 1111 1111B,即單片機(jī)地址線的P2.5~P2.0與P0.7~P0.0發(fā)出的信號(hào)可以從全0變化到全1,則62128(1)的地址范圍為:0000 0000 0000 0000B~0011 1111 1111 1111B,即0000H~3FFFH,62128(2)的地址范圍為:0100 0000 0000 0000B~0111 1111 1111 1111B,即4000H~7FFFH。
?
?
16. 設(shè)計(jì)AT89C51單片機(jī)外擴(kuò)2片6264存儲(chǔ)器芯片的連接電路,要求6264芯片的片選信號(hào)采用譯碼法產(chǎn)生,畫出圖10所示電路中AT89C51、74LS373與6264之間的連接圖,計(jì)算出兩片6264的地址范圍。
答:擴(kuò)展的電路連接如下圖所示。
?
題16圖 AT89C51外擴(kuò)兩片6264的電路連接
6264(1)芯片存儲(chǔ)單元的地址變化范圍為:0000 0000 0000 0000B~0001 1111 1111 1111B,即0000H~1FFFH,6264(2)芯片存儲(chǔ)單元的地址變化范圍為:0010 0000 0000 0000B~0011 1111 1111 1111B,即2000H~3FFFH。
?
17. 對AT89C51單片機(jī)外擴(kuò)一片8255A芯片,電路如題17圖所示,8255A的地址線A1、A0由單片機(jī)P0.1、P0.0經(jīng)74LS373鎖存后獲得,片選信號(hào)接單片機(jī)的P2.7,8255A的PA口接8個(gè)發(fā)光二極管。編寫程序使發(fā)光二極管逐行先從左往右、再從右往左不停地循環(huán)點(diǎn)亮。
?
題17圖??AT89C51單片機(jī)外擴(kuò)一片8255A芯片的電路
附:8255A的方式控制字如下:
?
答:#include <reg51.h> ????
#include <absacc.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define PA XBYTE[0x0000] //PA及命令端口地址定義 ??
#define COM XBYTE[0x0003]
void Delay(uint x) ??????????????????????
{ ?uchar i;
while(x--)
{ ? for(i=0;i<120;i++); }
}
void main()
{
uchar k,m=0x7f;
COM=0x80;
while(1)
{ ? for(k=0;k<8;k++) ????//小燈從左到右亮 ??
{
m=_crol_(m,1);
PA = m;
Delay(1000); ?}
for(k=0;k<8;k++) ???????//小燈從右到左亮 ?
{
m=_cror_(m,1);
PA = m;
Delay(1000);
}
}
}
?
?
DAC0832與AT89C52單片機(jī)連接的仿真電路如題6(a)圖所示,編寫程序用DAC0832芯片生成題6(b)圖所示的三角波。
?
題6(a)圖?DAC0832與AT89C52單片機(jī)連接的仿真電路
?
題6(b)圖?三角波
答:將輸出的字節(jié)值先從0~255遞增,再從255~0遞減,如此循環(huán),輸出電壓值先由0V~-5V遞減,再從-5V~0V,依次循環(huán),就可以形成三角波。
程序設(shè)計(jì)如下:
/*用DAC0832生成三角波*/
#include <reg52.h> ???????????????????
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
#define DAC0832 XBYTE[0x7fff]
void DelayMS(uint ms)//延時(shí)程序 ?????????
{ ?uchar i;
while(ms--)
{ ? for(i=0;i<120;i++); }
}
void main()//主程序
{
????????uchar i; ?????????????????????
????????uchar k;
????????k=0; ???//k為三角波上升和下降的標(biāo)志位 //
????????i=0;
while(1) ????//循環(huán)輸出三角波
{
???if(k==0) ?//輸出三角波的下降沿 ??
???????????{
??????????????i++;
??????????????DAC0832 =i;
??????????????if(i==255) k=~k;
??????????DelayMS(1);
???????}
?????????Else ??//輸出三角波的上升沿
???????????{
??????????i--;
??????????????DAC0832 =i;
??????????????if(i==0) k=~k;
??????DelayMS(1);
???????}
??}
}
?
7. DAC0832與AT89C52單片機(jī)連接的仿真電路如題7(a)圖所示,編寫程序用DAC0832芯片生成題7(b)圖所示的鋸齒波。
?
題7(a)?DAC0832與AT89C52單片機(jī)連接的仿真電路
?
題7(b) ?鋸齒波
?
答:程序如下:
#include <reg52.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
#define DAC0832 XBYTE[0x7FFF]
void DelayMS(uint ms)//延時(shí)程序
{ ?uchar i;
while(ms--)
{for(i=0;i<120;i++); }
}
void main()//主程序
{ ??uchar i;
????i=255;
while(1)//循環(huán)輸出三角波
{ ?i--;
???DAC0832 =i;
???DelayMS(1);
??}
}