单片机原理及应用7.docx
《单片机原理及应用7.docx》由会员分享,可在线阅读,更多相关《单片机原理及应用7.docx(12页珍藏版)》请在冰豆网上搜索。
单片机原理及应用7
第7章
1.简述键盘扫描的主要思路。
答案:
键盘扫描的主要思路:
首先确定是否有键按下,消除抖动,若有键按下,输出逐行或列的扫描字,读取列或行的状态,确定按键键值,然后再判断按键是否释放,若释放,即可返回。
2.简述软件消除键盘抖动的原理。
答案:
软件消除键盘抖动的原理:
当CPU发现有键按下的情况下,为了防止是机械抖动的误动作,可以采用软件延时10ms,然后再次检测按键是否仍然为闭合状态,若仍然闭合,则确定有键按下,否则就是键盘抖动,不予理睬。
3.什么叫LED的动态显示和静态显示。
答案:
静态显示形式,即七段LED数码管在显示某一个字符时,相应的段(发光二极管)恒定的导通或截至,直至换显其他字符为止。
动态显示是将所有数码管的段码线对应并联在一起,由一个8位的输出口控制,每位数码管的公共端(称位选线)分别由一位I/O口线控制,以实现各位的分时选通。
4.要求利用8051的P1口扩展一个2
2行列式键盘电路,画出电路图,并根据所绘电路编写键扫描子程序。
答案:
设行线H1~H2连接到51单片机P1口的P1.0~P1.1,列线L1~L2连接到P1口的P1.4~P1.5。
电路图如下:
键扫描子程序:
KEY:
MOVP1,#0FH;列输出低电平,行输出高电平
MOVA,P1;读P1口状态
ANLA,#0FH;保留行状态
CJNEA,#0FH,KEY0;有键按下转KEY0
SJMPKEY;无键按下等待,转键检测
KEY0:
LCALLDELAY10;调10mS延时取抖
MOVA,P1
ANLA,#0FH
CJNEA,#0FH,KEY1;不是抖动转键值判断
SJMPKEY;是抖动到键检测
KEY1:
MOVP1,#11101111B;第一列键被按下判断
MOVA,P1
ANLA,#0FH
CJNEA,#0FH,KEYC1;第一列键被按下转KEYC1处理
MOVP1,#11011111B;第二列键被按下判断
MOVA,P1
ANLA,#0FH
CJNEA,#0FH,KEYC2;第二列键被按下转KEYC2处理
LJMPKEY;均不是转到键检测
KEYC1:
MOVA,P1;读键值键值处理
JBE0H,KEYC11
LCALLK1;K1键处理
SJMPFANH
KEYC11:
LCALLK3;K3键处理
SJMPFANH
KEYC2:
MOVA,P1;读键值键值处理
JBE0H,KEYC21
LCALLK2;K2键处理
SJMPFANH
KEYC21:
LCALLK4;K4键处理
FANH:
RET
C程序如下:
/***********************************************************************/
//按键函数扫描有键按下否(返回值不等于0,说明有键按下)
/***********************************************************************/
ucharkeysearch()
{
uchark;
P1=0x0f;
k=P1;
k=~k;
k=k&0x0f;
returnk;
}
/***********************************************************************/
//按键函数(返回值:
等于0xff,说明没有键按下)
/***********************************************************************/
ucharkey()
{
uchara,c,kr,keynumb;
a=keysearch();
if(a==0)
return0xff;
else
delay(10);//延时去抖动
a=keysearch();
if(a==0)
return0xff;
else
{
a=0xef;
for(kr=0;kr<2;kr++)
{
P1=a;
c=P1;
if((c&0x01)==0)keynumb=kr+0x00;
if((c&0x02)==0)keynumb=kr+0x02;
a=_crol_(a,1);//循环左移函数,需要intrins.h头文件支持
}
}
do{//按键释放检测
a=keysearch();
}while(a!
=0);
returnkeynumb;//返回按键的编码键值
}
/***********************************************************************/
//按键的键值处理函数
/***********************************************************************/
voidkeybranch(uchark)
{
switch(k)
{
case0x00:
//添加需要执行的功能;break;
case0x01:
//添加需要执行的功能;break;
case0x02:
//添加需要执行的功能;break;
case0x03:
//添加需要执行的功能;break;
default:
break;
}
}
5.请在图7-1的基础上,设计一个以中断方式工作的开关式键盘,并编写其中断键处理程序。
答案:
电路图如下:
中断键处理程序:
KINT:
LCALLDELAY10;调10mS延时取抖
MOVA,P1
ANLA,#0FH
CJNEA,#0FH,KEY1;不是抖动转键值判断
SJMPFANH;是抖动返回
KEY1:
MOVA,P1;读键值键值处理
JB0E0H,KEY2
LCALLK1;K1键处理
SJMPFANH
KEY2:
JB0E1H,KEY3
LCALLK2;K2键处理
SJMPFANH
KEY3:
JNB0E2H,KEY4
LCALLK3;K3键处理
SJMPFANH
KEY4:
LCALLK4;K4键处理
FANH:
RETI
C程序如下:
voidint_key()interrupt0
{
delay(10);//delay10ms
temp=P1;
if((temp&0x0f)==0x0f)
break;
temp=P1;
if((temp&0x0f)==0x0e)
//key1处理函数
if((temp&0x0f)==0x0d)
//key2处理函数
if((temp&0x0f)==0x0b)
//key3处理函数
if((temp&0x0f)==0x07)
//key4处理函数
}
6.状态或数码显示时,对LED的驱动可采用低电平驱动,也可以采用高电平驱动,二者各有什么特点?
答案:
高电平驱动要采用共阴极数码管,必须外接上拉电阻;低电平驱动要采用共阳极数码管,电源效率相对较高。
7.用DAC0832进行D/A转换时,当输出电压的范围在0~5V时,每变化一个二进制数其输出电压跳变约20mV,即输出是锯齿状的,采取何种措施可使输出信号比较平滑?
答案:
两种方法:
(1)可以计算移动平均值;
(2)可以设计滤波器的办法。
8.当系统的主频为6MHz时,请计算图7-17中DAC0832产生锯齿波信号的周期。
答案:
T=2μs×8×256=4096μs
9.编写图7-17中用DAC0832产生三角波的应用程序。
答案:
START:
MOVDPTR,#7FFFH
MOVA,#00H
LOOP:
MOVX@DPTR,A
INCA
CJNEA,#0FFH,L1
L2:
DECA
MOVX@DPTR,A
CJNEA,#00H,L2
L1:
AJMPLOOP
C程序如下:
/***************************************************************************
程序功能:
连续访问外部DAC寄存器,产生锯齿波
***************************************************************************/
#include//头文件包含
#include
#defineucharunsignedchar//宏定义
#defineuintunsignedint
/***************************************************************************
延时函数
***************************************************************************/
voiddelay()
{
uinti,j;
for(i=0;i<1;i++)
for(j=0;j<120;j++);
}
/**************************************************************************
主函数
***************************************************************************/
voidmain()
{
unsignedchara=0;//控制波形累加深度
while
(1)
{
XBYTE[0x7FFF]=a;
a++;
delay();//加入延时函数,控制其周期
}
}
10.对图7-24的A/D转换电路,若采用中断方式,编写相应程序。
答案:
在硬件电路上,应当将EOC引脚接到单片机的外部中断引脚上面,如
;
初始化程序:
MAIN:
SETBIT1
SETBEA
SETBEX1
MOVR1,#data;R1指向数据存储区首地址
MOVDPTR,#7FF8H;DPTR指向通道0
MOVR7,#08H;通道数8
LOOP:
MOVX@DPTR,A;启动A/D转换
SJMP$
;中断服务程序:
PINT1:
MOVXA,@DPTR;转换结果读入累加器A
MOV@R1,A;存储数据
INCDPTR;修改指针
INCR1
RETI
C程序如下:
/**************************************************************************/
//程序功能:
对8路模拟信号轮流采样,并把结果依次存到数组中;
/**************************************************************************/
#include//头文件定义
#include
unsignedchara[8];
unsignedchari;
/**************************************************************************
主程序
**************************************************************************/
voidmain()
{
EA=1;
IT1=1;
EX1=1;
XBYTE[0x7FF8]=a[0];
while
(1)
{
}
}
voidint_adc()interrupt0
{
a[i]=XBYTE[0x7FF8+i];
i++;
if(i>7)
i=0;
}
11.当图7-24的ADC0809对8路模拟信号进行A/D转换时,编写用查询方式工作的采样程序,8路采样值存放在30H~37H单元。
答案:
MAIN:
MOVR1,#30H
MOVDPTR,#7FF8H
MOVR7,#08H
LOOP:
MOVX@DPTR,A
MOVR6,#0AH
DELAY:
NOP
NOP
NOP
NOP
DJNZR6,DELAY
MOVXA,@DPTR
MOV@R1,A
INCDPTR
INCR1
DJNZR7,LOOP
END
C程序如下:
/**************************************************************************/
//程序功能:
对8路模拟信号轮流采样一次,并把结果依次存放在30H~37H单元;
/**************************************************************************/
#include//头文件定义
#include
unsignedchara[8];
unsignedcharp;
/**************************************************************************
延时函数
**************************************************************************/
voiddelay(unsignedcharm)
{
unsignedchari,j;
for(i=0;ifor(j=0;j<123;j++);
}
/**************************************************************************
主程序
**************************************************************************/
voidmain()
{
unsignedchari;
p=0x30;
XBYTE[0x7FF8]=a[0];
for(i=0;i<8;i++)
{
delay(10);
a[i]=XBYTE[0x7FF8+i];
*[p++]=a[i];
}
while
(1);
}