欢迎光临散文网 会员登陆 & 注册

MSC51编程题知识汇总

2023-06-06 22:32 作者:欢喜y1  | 我要投稿

仿真电路如题13图所示,编写程序,使图中的发光二极管D1闪烁10次后熄灭。

 

题13图 使发光二极管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单片机的P2口控制一个共阳极7段LED数码管,电路如题14图所示,请在下列程序中第①空处,依次写出使共阳极7段LED数码管显示0~9的十个段码,再在主程序第②、③空处编写相应的语句,实现LED数码管循环显示0~9的功能。

 

题14图  用AT89C51单片机P2口控制共阳极7段LED数码管的电路

#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口循环输出0~9共阳极段码表

delayms(900);

i++;

if(seg[i]==0x01) ③i=0;   // 如段码为0x01,表明一个循环显示已结束

}

}

void delayms(uint j)    // 延时函数

{uchar i;

for(;j>0;j--)

   {  i=250;

      while(--i);

      i=249;

      while(--i);

    }

}

14. 8位一体共阳极8段LED数码管和单片机的连接电路如题15图所示,请在下列程序中第①空处,依次写出使共阳极8段LED数码管显示1~9以及0的十个段码,再在主程序第②、③、④空处编写相应的语句,使8位数码管从左到右分别滚动显示单个数字1~8,即程序运行后,单片机控制左边第1个数码管显示1,其他不显示,延时之后,控制左边第2个数码管显示2,其他不显示,直至第8个数码管显示8,其他不显示,反复循环上述过程。

 

题15图 8位一体共阳极8段LED数码管和单片机的连接电路

#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数码管段码表

void  delay(uint t)        //延时函数

{   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循环左移1位

      ③P0=dis_code[i]; //P0口输出段码

      ④P2=j; //P2口输出位控码

       delay(180);  //延时,控制每位显示的时间

}

       }

}

16. 单片机控制8个发光二极管的电路如题16图,8个发光二极管D1~D8经限流电阻分别接至P1口的P1.0~P1.7引脚上,二极管阳极共同接高电平。在下列程序的第①~⑤空处编写相应的语句控制发光二极管由上至下反复循环流水点亮,每次点亮一个发光二极管。

 

题16 单片机控制8个发光二极管的电路

#①include <reg51.h>       //包含51单片机的头文件

#②include <intrins.h>  //包含移位函数_crol_(  )的头文件

#define uchar unsigned char      

#define uint unsigned int      

void  delay(uint i)    //延时函数

{

uchar t;

  while (i--)

{   for(t=0;t<120;t++);  }

}

void  main(  )    //主程序

{

③P1=0xfe;  //向P1口送出点亮数据

    while (1)

    {  

④ delay( 500 );  //调用延时函数

⑤P1=_crol_(P1,1);   //将P1中的数据循环左移1位

    }

}

 

17. 单片机键控电路如题17图所示,P1.0和P1.1引脚接有两只开关S0和S1,两引脚上的高低电平共4种组合,4种组合分别点亮P2.0~P2.3引脚控制的4只LED,即S0、S1均闭合,LED0亮,其余灭;S1闭合、S0打开,LED1亮,其余灭;S0闭合、S1打开,LED2亮,其余灭;S0、S1均打开,LED3亮,其余灭。在下列程序的第①~⑤空处编写相应的语句实现题目要求的控制功能。

 

题17 单片机键控电路

答:

#include <reg51.h>   // 包含头文件reg51.h

void  main(  )   //主函数main( )

{

char state;

  do

  {

P1=0xff;    // P1口为输入

   state=P1;       // 读入P1口的状态,送入state

   ① state=state&0x03;     // 屏蔽P1口的高6位

   switch (state)   // 判P1口低2位开关状态

   {

② case 0: P2=0x01; break;// P1.1、P1.0=00,点亮P2.0脚LED

    ③ case 1: P2=0x02; break; // P1.1、P1.0=01,点亮P2.1脚LED

    ④ case 2: P2=0x04; break; // P1.1、P1.0=10,点亮P2.2脚LED

    ⑤ case 3: P2=0x08; break; // P1.1、P1.0=11,点亮P2.3脚LED

   }

  }while ( 1 );

 

18.仿真电路如下图所示,编写程序,将开关K的闭合和打开情况用二极管表示,即当K1闭合时,D1亮,K1打开时,D1不亮,当K2闭合时,D2亮,K2打开时,D2不亮,依此类推,试编写程序。

 

键控发光二极管的电路

程序设计如下:(编程题答案不唯一,酌情扣分)

#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上接了四个按键,P3口上接了共阳极LED显示器,试编写程序,在LED显示器上将按下的键值显示出来。

 

题19图 独立式按键与单片机的接口(采用查询方式)

答:#include<reg51.h>

#define uchar unsigned char

#define uint unsigned int

int xx;                  

void delay(int k) //延时函数

{    int i;

    for(i=0;i<k;i++);  }

void main()

{   P2=0xFF;

    P3=0xFF;   //为输入键值做准备

    while(1)

     { while(P2==0xFF) //若无键按下,循环等待

        {;}

       if(P2!=0xFF) //有键按下,延时去抖动

       delay(10);

       if(P2!=0xFF)

{  xx=P2; //有键按下,根据键值进行显示

  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图所示,要求单片机的主程序实现P1口控制一个共阴极数码管的各段依次点亮,不断循环,当有外中断输入时,使数码管显示8,闪烁4次后,返回原断点处继续执行程序,外中断的触发方式采用边沿触发方式。试编写程序。

 

题18图 单片机外中断应用系统电路图

答:#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设为边沿触发方式  

aa=0x01;

P3=0xff;

while(1)

{ P1=aa;   //送入段选信号

delay(1000);

aa=_crol_(aa,1); //将aa循环左移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;  //送入段选信号7f,使数码管显示8

delay(500);

P1=0x00;  //送入段选信号00,使数码管熄灭

delay(500);  }

}

19. 电路如题19图所示,要求单片机主程序控制P2口所接的8段共阳极数码管各段依次循环点亮,当外部中断输入出现从高到低的负跳变时,数码管开始亮灭闪烁显示“0”,闪烁显示8次后,8段数码管的各段继续依次循环点亮。试编写程序,实现上述功能。

 

题19图 单片机外中断应用系统

答:#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设为边沿触发方式  

aa=0xfe;

        P3=0xff;

while(1)

{

P2=aa;   //送入段选信号

delay(1000);

aa=_crol_(aa,1); //将aa循环左移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;  //送入段选信号3f,使数码管显示0

delay(500);

P2=0x00;  //送入段选信号00,使数码管熄灭

delay(500);

}  

}

20. 电路连接如题20图所示,编程实现下列要求:在平时状态下,8个发光二极管以200ms的时间间隔,依次点亮。在中断时亮一半,暗一半;在中断时全灭,中断为高优先级,中断为低优先级。


题20图 采用中断控制二极管点亮的电路

答:程序如下:

#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边沿触发

IT1=1;   //INTl边沿触发

EA=1;   //开总中断

EX0=1;  //使能INT0

EX1=1;  //使能INTl

PX0=1;  //中断0优先

}

void main()      

{

init();

aa=0x01;

while(1)

{   

          P2=aa;

delay(200);

aa=_crol_(aa,1);//aa循环左移一位    

}

}

void int0() interrupt 0

{

for(i=8;i>0;i--)

{

P2=0x00;   //P2口送出00H使灯熄灭,循环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单片机控制P2口所接8只LED数码管的电路如题12图所示,要求用单片机定时器T0,采用方式1,定时中断方式,使P2口所接的8只LED每0.5s闪烁亮一次。计算与定时器工作方式控制寄存器TMOD、控制寄存器TCON、计数寄存器TH0、TL0及中断允许寄存器IE中各位的值,要求写出计算过程,同时完成实现上述要求功能的程序编写。

 

题12图AT89C51单片机控制P2口所接8只LED数码管的电路

附:TMOD及TCON控制字的格式如下:


答:(1)TMOD寄存器的设置

T0工作在方式1,应使TMOD寄存器的M1、M0=01;应设置C/T=0,为定时器模式;对T0的运行控制仅由TR0来控制,应使相应的GATE位为0。定时器T1不使用,各相关位均设为0。所以,TMOD寄存器应初始化为0x01。

(2)计算定时器T0的计数初值

设定时时间5ms(即5000µs),设T0计数初值为X,假设晶振的频率为11.0592MHz,则定时时间为:

定时时间=(216−X)×12/晶振频率

则  5000=(216 −X) ×12/11.059 2

    得  X = 60928

    转换成十六进制:0xee00,其中0xee装入TH0,0x00装入TL0。

(3)设置IE寄存器

由于采用定时器T0中断,因此需将IE寄存器中的EA、ET0位置1。

(4)启动和停止定时器T0

    将定时器控制寄存器TCON中的TR0=1,则启动定时器T0;TR0=0,则停止定时器T0定时。

参考程序:

#include<reg51.h>

char  i=100;         //

void main ()  

{ TMOD=0x01;   //定时器T0为方式1

TH0=0xee;   //设置定时器初值,定时器每5ms中断一次

TL0=0x00;

    P2=0x00;    //P2口8个LED点亮

EA=1;     //总中断开

ET0=1;     //开T0中断

TR0=1;     //启动T0

while(1);    //循环等待

{  ; }

}

void timer0() interrupt 1   //T0中断程序,每5ms中断一次

{ TH0=0xee;    //重新赋初值

TL0=0x00;

i--;     //循环次数减1

if(i<=0)

{

P2=~P2;       // 中断100次,达到0.5s,P2口按位取反

i=100;    //重置循环次数

}

}

13. 电路如题13图所示,在AT89C51单片机的P1口上接了8只LED,T1(P3.5)引脚接了一只按键开关,要求定时器T1采用计数模式,方式1中断,使输入引脚T1引脚上外接按钮开关作为计数信号输入。按4次按钮开关后,P1口的8只LED闪烁不停。计算与定时器有关的工作方式控制寄存器TMOD、控制寄存器TCON、计数寄存器TH1、TL1及中断允许寄存器IE的值,写出计算过程,编写实现上述功能的程序。

 

题13图 AT89C51单片机控制8只LED电路

答:

(1) 设置TMOD寄存器

T1工作在方式1,应使TMOD的M1、M0=01;设置C/T*=1,为计数器模式;对T0运行控制仅由TR0来控制,应使GATE0=0。定时器T0不使用,各相关位均设为0。所以,TMOD寄存器应初始化为0x50。

(2) 计算定时器T1的计数初值

由于每按1次按钮开关,计数1次,按4次后,P1口的8只LED闪烁不停。因此计数器初值为65 536−4=65 532,将其转换成十六进制后为0xfffc,所以,TH0=0xff,TL0=0xfc。

(3)设置IE寄存器

本例由于采用T1中断,因此需将IE寄存器的EA、ET1位置1。

(4)启动和停止定时器T1

将寄存器TCON中TR1=1,则启动T1计数;TR1=0,则停止T1计数。

程序如下:

  #include <reg51.h>

    void Delay(unsigned int i)  //定义延时函数Delay( )

{ unsigned int j;  

for(;i>0;i--)

for(j=0;j<125;j++)  

{;}    //空函数

 }

void  main( )   //主函数

 {

TMOD=0x50;   //设置定时器T1为方式1计数

TH1=0xff;   //向TH1写入初值的高8位

TL1=0xfc;   //向TL1写入初值的低8位

EA=1;       //总中断允许

ET1=1;      //定时器T1中断允许  

  TR1=1;      //启动定时器T1

  while(1) ;     //无穷循环,等待计数中断

 }

 

void T1_int(void)  interrupt 3   //T1中断函数

{

for(;;)    //无限循环

  {

P1=0xff;  //8位LED全灭

   Delay(500) ;  //延时500ms

   P1=0;   //8位LED全亮

   Delay(500);   //延时500ms

}      

}

14.原理电路如题14图所示,在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接一只按钮开关K1。要求将外部中断0设置为电平触发。程序启动时,P1口上的8只LED全亮。每按一次按钮开关K1,使引脚接地,产生一个低电平触发的外中断请求,在中断服务程序中,让低4位的LED与高4位的LED交替闪烁5次,中断结束后,控制8只LED再次全亮,请编写相应的控制程序。

 

题14图 单片机控制发光二极管电路

答:程序如下:

#include <reg51.h>                  

#define uchar  unsigned char

void Delay(unsigned int i) //延时函数,

{ unsigned int j;

for(;i > 0;i--)  

for(j=0;j<333;j++)         //晶振为12MHz,j选择与晶振频率有关

{;}      //空函数

}

void  main( )   //主函数

{ EA=1;   //总中断允许    

EX0=1;   //允许外部中断0中断

IT0=1;   //选择外部中断0为跳沿触发方式

while(1)  //循环  

{ P1=0;}   // P1口的8只LED全亮    

}

void int0( )  interrupt 0  using 0   //外中断0的中断服务函数

{

uchar  m;

EX0=0;   //禁止外部中断0中断

for(m=0;m<5;m++) //交替闪烁5次

{

P1=0x0f;  //低4位LED灭,高4位LED亮

Delay(400) ;  //延时

P1=0xf0;  //高4位LED灭,低4位LED亮

Delay(400);   //延时

EX0=1;   //中断返回前,打开外部中断0中断

}

 

15. 已知晶振频率fosc=12MHz,使用定时器T1使P2.0引脚产生100ms的方波程序,计算TH1、TL1、TMOD寄存器的值,并编写对定时器1进行初始化的程序。

附:TMOD及TCON控制字的格式如下:


 


答:分析:方波的周期为100ms,要求高、低电平的持续时间各为50ms,采用定时器定时,中断工作方式。每50ms时间到时,在中断服务程序中将P2.0引脚电平状态取反,即可获得所需要的波形。晶振频率fosc=12MHz,Tcy=12/fosc=1μs ,选择定时器T1的方式1。

(1) 确定计算初值

(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,定时器/计数器0没有使用,相应的各个位状态随意,均取为0,则(TMOD)=10H。

(3) 程序如下:

#include<reg51.h>

#define uint unsigned int

sbit fangbo=P2^0;

void main()

{

TMOD=0x10; //设置T1为定时器模式,工作在方式1

TH1=0x3C;

TL1= 0xB0;

EA=1; //开总中断

ET1=1; //允许T1中断

TR1=1; // 启动T1

while(1);

}

void timer1() interrupt 3  //定时器1中断服务程序

{ TH1=(65536-50000)/256;

TL1=(65536-50000)%256;

fangbo=~fangbo;  }

16. 已知晶振频率fosc=12MHz,要求定时器0产生10ms的定时时间,计算与定时器有关的工作方式控制寄存器TMOD、控制寄存器TCON及计数寄存器TH、TL中各位的值,并编写对定时器0进行初始化的程序。

答:由于晶振频率为12MHz,机器周期Tcy=1μs,选用方式0时最大定时时间8.192ms,选择方式1时,最大定时时间为65.536ms,要求的定时时间为10ms,所以不能选择方式0,只能选用方式1。

(1) 计算TH0、TL0的计数初值   

由于晶振频率为12MHz,所以机器周期Tcy=1μs,则定时时间为:

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寄存器初始化   

根据题目要求,GATE (TMOD.3)=0, (TMOD.2)=0,M1 (TMOD.1)=0,M0

 (TMOD.0)=1,定时器/计数器1没有使用,相应的各个位状态随意,均取为

0,则(TMOD)=01H。

(3) 初始化程序        

void init_time0(void)

{

TMOD=0x01;             //设置T0为定时器模式,工作在方式1

TH0=(65536-10000)/256;    //设置TH0和TL0的计数初值

TL0=(65536-10000)%256;

    TR0=1;                  // 启动T0

}

 

17. 设单片机系统时钟频率为12MHz,波形发生器电路如题17图所示,要使P2.0引脚上输出一个周期为2ms的方波,计算计数寄存器TH、TL的值,并编写程序实现上述功能。

 

题17图 波形发生器电路

答:(1) 计算TH0、TL0的计数初值  

要在P2.0上产生周期为2ms的方波,定时器应产生1ms的定时中断,定时时间到则在中断服务程序中对P2.0求反。使用定时器T0,方式1定时中断,GATE不起作用。

设T0的初值为X,有

      (216−X )×1×10−6=1×10−3

即    65536−X=1000

得X=64536,化为16进制数就是0xfc18。将高8位0xfc装入TH0,低8位0x18装入TL0。

(2) TMOD寄存器初始化   

GATE (TMOD.3)=0, (TMOD.2)=0,M1 (TMOD.1)=1,M0 (TMOD.0)=0,定时器/计数器1没有使用,相应的各个位状态随意,均取为0,则(TMOD)=01H。

(3) 程序编写         

#include <reg51.h>    //头文件reg51.h

sbit P2_0=P2^0;   //定义特殊功能寄存器P1的位变量P1_0

void main(void)   //主程序

{

TMOD=0x01;  //设置T0为方式1

TR0=1;   //接通T0

while(1)  //无限循环

{

TH0=0xfc;  //置T0高8位初值

TL0=0x18;  //置T0低8位初值

do{}while(!TF0);        //TF0为0原地循环,为1则T0溢出,往下执行

P2_0=!P2_0;  // P2.0状态求反

TF0=0;   //TF0标志清零

}

}

 

18. 已知晶振频率fosc=12MHz,要求用定时0每隔200μs产生一定时信号,计算与定时器有关的工作方式控制寄存器TMOD、控制寄存器TCON、计数寄存器TH、TL,并对定时器进行初始化编程。

解:选择定时器0,工作在方式2。

(1) 计算TH0、TL0的计数初值  

由于晶振频率为12MHz,所以机器周期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,定时器/计数器1没有使用,相应的各个位状态随

意,均取为0,则(TMOD)=02H。

(3) 初始化程序         

void init_time0(void)

{

TMOD=0x02; //设置T0为定时器模式,工作在方式1

TH0=0x38;  //设置TH0和TL0的计数初值

TL0=0x38;

    TR0=1;  // 启动T0

}

13. 对AT89C51单片机外扩一片RAM 62256芯片,请设计电路连接图,画出AT89C51、74LS373与62256之间的连接电路,计算62256存储器的地址范围。

答: 62256地址线有15条(A14~A0),片选信号CE接地,芯片地址范围为0000H~7FFFH。

单片机与存储器的连接电路如下图所示。

 

采用线选法扩展一片62256的电路连接

14. 对AT89C51单片机外扩展两片16kB的RAM 62128芯片,用线选法进行两片62128的片选,画出题14图所示电路中各芯片之间的连接,计算出两片62128的地址范围。

答:扩展的电路连接如图9所示。62128(1)芯片存储单元的地址变化范围为:1000 0000 0000 0000B~1011 1111 1111 1111B,即8000H~BFFFH,62128(2)芯片存储单元的地址变化范围为:0100 0000 0000 0000B~0111 1111 1111 1111B,即4000H~7FFFH。

 

题14图 AT89C51外扩两片62128的电路连接

15. 对AT89C51单片机外扩展两片16kB的RAM 62128芯片,用译码法进行两片62128的片选,画出AT89C51、74LS373、74LS139与62128之间的连接图,计算两片62128的地址范围。

答:扩展的电路连接如下图所示。

 

AT89C51外扩2片62128的电路连接

62128芯片中存储单元的地址变化范围为:xx00 0000 0000 0000B~xx11 1111 1111 1111B,即单片机地址线的P2.5~P2.0与P0.7~P0.0发出的信号可以从全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. 设计AT89C51单片机外扩2片6264存储器芯片的连接电路,要求6264芯片的片选信号采用译码法产生,画出图10所示电路中AT89C51、74LS373与6264之间的连接图,计算出两片6264的地址范围。

答:扩展的电路连接如下图所示。

 

题16AT89C51外扩两片6264的电路连接

6264(1)芯片存储单元的地址变化范围为:0000 0000 0000 0000B~0001 1111 1111 1111B,即0000H~1FFFH,6264(2)芯片存储单元的地址变化范围为:0010 0000 0000 0000B~0011 1111 1111 1111B,即2000H~3FFFH。

 

17. 对AT89C51单片机外扩一片8255A芯片,电路如题17图所示,8255A的地址线A1、A0由单片机P0.1、P0.0经74LS373锁存后获得,片选信号接单片机的P2.7,8255A的PA口接8个发光二极管。编写程序使发光二极管逐行先从左往右、再从右往左不停地循环点亮。

 

题17  AT89C51单片机外扩一片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单片机连接的仿真电路如题6(a)图所示,编写程序用DAC0832芯片生成题6(b)图所示的三角波。

 

题6(a)图 DAC0832与AT89C52单片机连接的仿真电路

 

题6(b)图 三角波

答:将输出的字节值先从0~255递增,再从255~0递减,如此循环,输出电压值先由0V~-5V递减,再从-5V~0V,依次循环,就可以形成三角波。

程序设计如下:

/*用DAC0832生成三角波*/

#include <reg52.h>                    

#include <absacc.h>

#define uint unsigned int

#define uchar unsigned char

#define DAC0832 XBYTE[0x7fff]

void DelayMS(uint ms)//延时程序          

{  uchar i;

while(ms--)

{   for(i=0;i<120;i++); }

}

void main()//主程序

{

        uchar i;                      

        uchar k;

        k=0;    //k为三角波上升和下降的标志位 //

        i=0;

while(1)     //循环输出三角波

{

   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单片机连接的仿真电路如题7(a)图所示,编写程序用DAC0832芯片生成题7(b)图所示的锯齿波。

 

7(a) DAC0832与AT89C52单片机连接的仿真电路

 

题7(b)  锯齿波

 

答:程序如下:

#include <reg52.h>

#include <absacc.h>

#define uint unsigned int

#define uchar unsigned char

#define DAC0832 XBYTE[0x7FFF]

void DelayMS(uint ms)//延时程序

{  uchar i;

while(ms--)

{for(i=0;i<120;i++); }

}

void main()//主程序

{   uchar i;

    i=255;

while(1)//循环输出三角波

{  i--;

   DAC0832 =i;

   DelayMS(1);

  }

}








MSC51编程题知识汇总的评论 (共 条)

分享到微博请遵守国家法律