单片机课后答案解析9.docx
《单片机课后答案解析9.docx》由会员分享,可在线阅读,更多相关《单片机课后答案解析9.docx(11页珍藏版)》请在冰豆网上搜索。
单片机课后答案解析9
习题9
1.某系统片外RAM的片选电路如图9-38所示:
RAM共7路,有2K×8位和1K×8位两种芯片,其片选信号都是低电平有效。
请为各路RAM芯片注明它的容量和地址范围。
图9-38第1题图
解:
第一路芯片的地址为8000H-87FFH;
第二路芯片的地址为8800H-8FFFH;
第三路芯片的地址为9000H-97FFH;
第四路芯片的地址为A000H-A3FFH;
第五路芯片的地址为A400H-A7FFH;
第六路芯片的地址为A800H-ABFFH;
第七路芯片的地址为AC00H-AFFFH。
2.对AT89C51单片机外扩4片静态RAM62128芯片,请画出硬件电路图,写出每片芯片的地址。
解:
62128
(1):
0000H-3FFFH,62128
(2):
4000H-7FFFH,62128(3):
8000H-BFFFH,
62128(4):
C000H-FFFFH
3.8255A有几种工作方式?
如何进行选择?
解:
8255A共有三种工作方式,用方式控制字来选择。
4.现有一片AT89C51单片机,扩展了一片8255A,若把8255A的B口用作输入,每一位接一个开关,A口用作输出,每一位接一个发光二极管,请用proteus软件画出电路原理图,并编写出B口某一位开关接低电平时,A口相应位发光二极管被点亮的程序。
解:
电路如下图:
程序如下:
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
//PA,PB,PC及命令端口地址定义
#definePAXBYTE[0x0000]
#definePBXBYTE[0x0001]
#definePCXBYTE[0x0002]
#defineCOMXBYTE[0x0003]
voidmain()
{
uchark;
COM=0x82;//控制字
while
(1)
{
k=PB;
PA=k;
}
}
5.按照图9-18所示8255与AT89C52的连接图,用8255C口的PC3引脚向外输出连续的正方波信号,频率为500Hz。
试编程,并用proteus仿真验证。
解:
利用定时器0,每1ms中断一次,在中断服务程序中改变PC3的状态。
程序如下:
#include
#include
#definePA8255XBYTE[0xe000]/*定义8255A口地址*/
#definePB8255XBYTE[0xe001]/*定义8255B口地址*/
#definePC8255XBYTE[0xe002]/*定义8255C口地址*/
#defineCOM8255XBYTE[0xe003]/*定义8255控制寄存器地址*/
voidtimer0init();
bitk;
unsignedcharaa;
voidinit8255(void);
voidmain(void)
{
timer0init();
init8255();
COM8255=0x07;/*PC3置1*/
k=0;
while
(1);
}
voidinit8255(void){
COM8255=0x80;/*工作方式选择字送入8255控制寄存器,设置A、B、C口为基本I/O输出方式*/
}
voidtimer0init()
{
TMOD=0x01;//设置T0为定时器模式,工作在方式1
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
EA=1;//开总中断
ET0=1;//允许T0中断
TR0=1;//启动T0
}
voidtimer0()interrupt1//定时器0每1ms中断一次
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
if(k==0)
{
COM8255=0x06;/*PC3清0*/
k=~k;
}
else
{
COM8255=0x07;/*PC3置1*/
k=~k;
}
}
6.为什么要进行按键消抖?
按键消抖的方法有几种?
解:
按键是利用机械触点的合、断来实现键的闭合与释放,由于弹性作用,机械触点在闭合及断开瞬间会有抖动的过程,从而使键输入电压的信号也存在抖动现象。
去除抖动的方法一般有硬件和软件两种。
硬件方法就是在按键输出通道上添加去抖动电路,从根本上避免电压抖动的产生,去抖动电路可以是单稳态电路或者滤波电路。
软件方法通常是在检测到有键按下时延迟10~20ms的时间,待抖动期过去后,再次检测按键的状态,如果仍然为闭合状态,才认为是有键按下,否则认为是一个扰动信号。
按键释放的过程与此相同,都要利用延时进行消抖处理。
由于人的按键速度与单片机的运行速度相比要慢很多,所以,软件延时的方法简单可行,而且不需要增加硬件电路,成本低,因而被广泛采用。
7.按键输入程序应具备哪些功能?
解:
具有下列功能:
(1)确定键是否闭合;
(2)按键消抖处理;(3)确定闭合键的位置;(4)确定按键是否上访;(5)对按键进行处理。
8.利用LED显示器设计一个统计按键次数的系统,能够实时将当前按键次数以十进制形式显示在2位LED显示器上。
(1)所设计的Proteus仿真电路如图5-13所示。
图5-13计数器的仿真电路与效果图
两位数码管与单片机相连时,可以采用静态显示方式,也可以采用动态显示方式。
这里采用动态显示方式,将两个数码管的段码连接到单片机的P0口,P0口通过470Ω的上拉电阻接+5V,两个数码管的位选由P2.6和P2.7选中。
图5-13中数码管是共阴极的。
(2)程序设计如下:
#include
#defineucharunsignedchar
sbitkey=P3^0;
sbitge=P2^7;
sbitshi=P2^6;
uchardd;//dd为显示的数字
ucharf0;//f0为键按下过的标志
uchartime=0,count=0;
ucharcodedis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码
/*************延时程序*************/
voiddelay(ucharN)
{
uchari,j;
for(i=0;ifor(j=0;j<125;j++);
}
/***************显示程序*************/
voiddisplay(void)
{
P0=dis[dd%10];//显示个位
ge=0;
delay(3);
ge=1;
P0=dis[dd/10];//显示十位
shi=0;
delay(3);
shi=1;
}
/****************主程序***************/
voidmain()
{
dd=0;//开始显示的数字为0
f0=1;//f0为按下过键的标志位,如果按下过键,f0=0,否则f0=1
while
(1)
{
while(key==1)//键未按下,显示
{
display();
if(f0==0)
{
dd=dd+1;
f0=1;
}
}
while(key==0)//键按下,显示,标志f0=0
{
display();
f0=0;
}
}
}
(3)仿真效果
0~99计数器的仿真效果图如图5-13所示,图中显示的是23。
9.LCD1602与AT89C52单片机连接的仿真电路如图9-36所示。
用C语言编程,实现第一行从右侧移入“Helloeveryone”,同时第二行从右侧移入“Welcometohere!
”,移入速度自定,然后停留在屏幕上。
解:
程序设计如下:
程序如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable[]="Helloeveryone";
ucharcodetable1[]="Welcometohere!
";
sbitlcden=P3^4;//液晶使能端
sbitlcdrs=P3^5;//液晶数据命令选择端
ucharnum;
voiddelay(uintz)//延时子程序
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//写命令函数
{
lcdrs=0;//选择写命令模式
P0=com;//将要写的命令字送到数据总线上
delay(5);//稍微做延时以待数据稳定
lcden=1;//使能端给一个高脉冲,因为初始化函数中已将lcden置为0
delay(5);//稍做延时
lcden=0;//将使能端置0以完成高脉冲
}
voidwrite_data(uchardate)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit()
{
lcden=0;
write_com(0x38);//设置16×2显示,5×7点阵,8位数据接口
write_com(0x0f);//设置开显示,不显示光标
write_com(0x06);//写一个字符后地址指针加1
write_com(0x01);//显示清0,数据指针清0
}
voidmain()
{
init();
write_com(0x80+0x10);//先将数据指针定位到第一行第一个字处
for(num=0;num<15;num++)//做简短延时
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x50);//写第二行时重新定位数据指针
for(num=0;num<16;num++)
{
write_data(table1[num]);
delay(20);
}
for(num=0;num<16;num++)
{
write_com(0x1c);
delay(100);
}
while
(1);
}