DJNZ R1, LOOP
END
4-5 编写程序,采用算术平均值滤波法求采样平均值,设8次采样值依次放在20H~27H的
连续单元中,结果保留在A中。 答:FILT: CLR A
MOV R2, A MOV R3, A MOV R0, #20H MOV R7, #08H
FILT1: MOV A, @R0 ADD A, R3 MOV R3, A CLR A ADDC A, R2 MOV R2, A INC R0 DJNZ R7, FILT1 FILT2: SWAP A RL A ;R2/8, XCH A, R3 SWAP A RL A ;R3/8, ADD A, #80H ANL A, #1FH ADDC A, R3 END
4-6 编写程序,将存放在内部RAM起始地址为20H和30H的两个3字节无符号相减,结 果存放在内部RAM单元70H、71H、72H中(低位对应低字节)。
答: ORG 0000H START: MOV R0, #20H MOV R1, #30H MOV R2, #03H CLR C S0: LCALL XU MOV 70H, A LCALL XU MOV 70H, A LCALL XU MOV 70H, A S1 MOV A, @R0 SUBB A, @R1 INC R0 INC R1 RET END
习题与思考题5
5-1 写出一个C51程序的结构。 答:全局变量说明 类型说明 main() {
声明部分 语句部分
}
类型说明 函数名1(形式参数) {
声明部分 语句部分
}
类型说明 函数名n(形式参数) {
声明部分 语句部分
}
5-2 哪些变量类型是MCS-51单片机直接支持的?
答:MCS-51单片机直接支持的变量类型是:char及其数组和指针、bit、sbit、sfr和sfr16 5-3 如何定义内部RAM的可位寻址区的字符变量? 答:char bdata 字符变量名,或bdata char字符变量名。
5-4 试编写一段程序,将内部数据存储器30H、3lH单元内容传送到外部数据存储器1000H、 1001H单元中去。
答: #include
{
unsigned int temp; temp = DWORD[0x0030]; XWORD[0x1000] = temp;
6
while(1);
}
5-5 试编写一段程序,将外部数据存储器40H单元中的内容传送到50H单元。 答:方法一: #include
XBYTE[0x0050] = XBYTE[0x0040]; while(1);
}
方法二: #include
unsigned char xdata *xp; unsigned char data temp; xp = 0x0040; temp = *xp; xp = 0x0050; *xp =temp; while(1); }
5-6 试编写—段程序,将R3中的数乘以4。 答: #include
{ unsigned int data *a; #pragma asm MOV 30H, R3 #pragma endasm a = 0x30; *a = *a*4; while(1);
}
5-7 试编写—段程序,将R2中的各位倒序排列后送入R3中。
答:考虑C中没有循环移位,对于这种很低级的运算,采用嵌入汇编的方式完成。 #include
void main(void)
{ #pragma asm MOV R7, #08H MOV R3, #00H DEL: CLR CY MOV A, R2 RLC A MOV R2, A MOV A, R3 RRC A MOV R3, A DJNZ R7, DEL #pragma endasm while(1); }
5-8 试编写—段程序,将P1口的高5位置位,低3位不变。 答: #include
{ P1 |= 0xf8; while(1); }
5-9 设8次采样值依次存放在20H~27H的连续单元中,采用算术平均值滤波法求采样平均
值,结果保留在30H单元中。试编写程序。 答: #pragma small #include
void main(void)
{ unsigned char *dp = 0x20,i; float temp = 0; for(i=0;i<8;i++)
{ temp += *dp; dp++; } temp /= 8; dp = 0x30; *dp = temp; while(1); }
5-10 从20H单元开始有一无符号数据块,其长度在20H单元中。编写程序找出数据块中最
小值,并存入21H单元。
答: #pragma small #include
{ unsigned char *dp, num, min, i; dp = 0x20; num = *dp; dp++; for(i=1;i
7
答:(1)被调函数要在主函数中说明,在汇编程序中,要使用伪指令使CODE选项有效并
声明为可再定位段类型,并且根据不同情况对函数名作转换;
(2)对为其他模块使用的符号进行PUBILC声明,对外来符号进行EXTRN声明; (3)参数的传递。在混合语言编程中,关键是入口参数和出口参数的传递,C51编译 器可使用寄存器传递参数,也可以使用固定存储器或使用堆栈,由于MCS-51的堆栈深 度有限,因此多用寄存器或存储器传递。用寄存器传递最多只能传递三个参数,需选择 固定的寄存器。
5-12 如何编写高效的单片机C51程序?
答:(1)选择小存储模式;(2)尽可能使用最小数据类型;(3)尽量使用“unsigned”数据类
型;(4)尽量使用局部变量;(5)选择高效率的编译器。
习题与思考题6
6-3 外部中断源有电平触发和边沿触发两种触发方式,这两种触发方式所产生的中断过程有
何不同?怎样设定?
答:采用中断电平触发方式时,中断请求标志IT0=0,CPU在每个机器周期的S5P2期间采
样,一旦在P3.2(INT0)引脚上检测到低电平,则有中断申请,使IE0置位(置1), 向CPU申请中断。在电平触发方式中,在中断响应后中断标志位IE0的清0由硬件自 动完成,但由于CPU对P3.2(INT0)引脚没有控制作用,使中断请求信号的低电平可 能继续存在,在以后的机器周期采样时又会把已清0的IE0标志位重新置1,所以,在 中断响应后必须采用其它方法撤消该引脚上的低电平,来撤除外部中断请求信号,否则 有可能再次中断造成出错。
采用边沿触发方式时,IT0=1,CPU在每个机器的S5P2期间采样,当检测到前一周期为 高电平,后一周期为低电平时,使标志IE0置1,向CPU申请中断,此标志位一直保持 到CPU响应中断后,才由硬件自动清除。在边沿触发方式中,为保证CPU在两个机器 周期内检测到由高到低的负跳变,高电平与低电平的持续时间不得少于一个机器周期的 时间。
6-4 试分析以下几种中断优先级的排列顺序(级别由高到低)是否可能?若可能,则应如何
设置中断源的中断级别?否则,请简述不可能的理由。
(1) 定时器T0中断,定时T1中断,外中断1NT0,外中断INT1,串行口中断; (2) 串行口中断,外中断1NT0,定时器T0中断,外中断INT1,定时器T1中断; (3) 外中断INT0、定时器T1中断,外中断INT1,定时器T0中断,串行口中断。 答:(1)可以,将定时器T0中断,定时T1设置为高优先级中断,将外中断1NT0,外中断
INT1,串行口中断
(2)可以,将串行口中断设置为高优先级中断,将外中断1NT0,定时器T0中断,外 中断INT1,定时器T1中断设置为低优先级中断;
(3)不行,因为MCS-51单片机有2级中断优先级别,同级中断还存在按次序决定的 第二优先级结构,由高到低依次为外中断1NT0、定时器T0中断、外中断INT1、定时
8
器T1中断、串行口中断。
6-5 MCS-51中断响应时间是否固定?为什么? 答:MCS-51中断响应时间不固定。
对一个单一中断系统,MCS-51单片机对外部中断请求的响应时间在3—8个机器周期。 外部中断的最短的响应时间为3个机器周期,其中中断请求标志位查询占1个机器周期 ,而这个机器周期恰好又是处于指令的最后一个机器周期,该指令结束后中断即被响应 ,CPU接着执行子程序调用指令LCALL转到相应的中断服务程序入口,需2个机器周 期,所以,外部中断响应最短时间为3个机器周期。
外部中断响应的最长时间为8个机器周期:发生在CPU进行中断标志查询时,刚好是 开始执行RETI或是访问IE或IP的指令,则需把当前指令执行完再继续执行一条指令 后,才能响应中断,最长需2个机器周期。接着再执行一条指令,按最长指令(乘法指 令MUL和除法指令DIV)来算,也只有4个机器周期。加上硬件子程序调用指令LCALL 的执行,需要2个机器周期。所以,外部中断响应最长时间为8个机器周期。 对于多级中断系统,响应时间无法计算。
6-6 MCS-51 中若要扩充6个中断源,可采用哪些方法?如何确定它们的优先级?
答:可采用硬件申请与软件查询的方法,把多个中断源通过硬件“线或”或者经或非门,引入
外部中断源的输入端INT0、INT1,同时又连到某I/O口,这样,每个中断源都可能引 起中断,但在中断服务程序中通过软件查询,就能确定哪一个是正在申请的中断源,其 查询的次序则由中断优先级决定,这样就可实现多个外部中断源的扩展。 6-7 试叙述中断的作用和中断的全过程。
答:中断可用于单片机测控系统、CPU与外部设备交换信息中。中断的全过程包括中断请
求、中断允许、中断响应过程和中断请求撤消。
6-8 当正在执行某一中断源的中断服务程序时,如果有新的中断请求出现,试问在什么情况
下可响应新的中断请求?在什么情况下不能响应新的中断请求?
答:一个正在执行的低优先级中断程序能被高优先级的中断源所中断,但不能被另一个低优
先级的中断源所中断。若CPU正在执行高优先级的中断,则不能被任何中断源所中断 。
6-9 在下列各种中断方式中,需要外加电路来实现中断撤除的是:
(1) 定时中断 (2) 脉冲方式的外部中断 (3) 外部串行中断 (4) 电平方式的外部中断 答:(4) 电平方式的外部中断
习题与思考题7
7-1 定时/计数器有哪些专用寄存器,它们有几种工作模式?如何设置?
答:有定时控制寄存器(TCON)和工作方式寄存器(TMOD),具有四种工作方式:方式0
、方式1、方式2和方式3,四种方式由工作方式寄存器(TMOD)的M1和M0两位决 定。
7-2 如果采用晶振的频率为3MHz,定时/计数器工作方式0、1、2下,其最大的定时时间 为多少?
答:内部定时脉冲周期=机器周期=12/3Mhz=4us
9
工作方式0:Tmax=8192*4us=32.768ms
工作方式1:Tmax=65536*4us=262.144ms 工作方式2:Tmax=256*4us=1.024ms
7-3 定时/计数器用作定时器时,其计数脉冲由谁提供?定时时间与哪些因素有关
答:其计数脉冲由单片机振荡脉冲12分频输出的机器周期脉冲提供,定时时间与工作方式
、晶振频率和预置数等因素有关。
7-4 定时/计数器用作计数器时,对外界计数频率有何限制? 答:外部输入的计数脉冲的最高频率为振荡器频率的1/24。
7-5 采用定时/计数器T0对外部脉冲进行计数,每计数100个脉冲后,T0转为定时工作方 式。定时1ms后,又转为计数方式,如此循环不止。假定MCS-51单片机的晶体振荡 器频率为6MHz,请使用方式1实现,要求编写出程序。
答: ORG 0000H START: CLR TR0 MOV TMOD, #05H MOV TH0, #0FFH MOV TL0, #9CH
计数器初始化 S0: JBC TF0, NEXT SJMP S0 NEXT: CLR TR0 MOV TMOD, #01H MOV TH0, #0F8H MOV TL0, #30H
;定时器初始化 SETB TR0 S1: JBC TF0, START SJMP S1 END
7-6 定时/计数器的工作方式2有什么特点?适用于哪些应用场合?
答:工作方式2具有初值自动重新加载和循环工作的特点,适用于产生固定脉宽的脉冲信号
,和作为串行口波特率发生器使用。
7-8 一个定时器的定时时间有限,如何实现两个定时器的串行定时,来实现较长时间的定 时?
答:方法一:让一个定时器先定时,溢出后,再启动另一个定时器定时;
方法二:在第一个中断处理子程序中加入计数器,计数器满后,就去启动另一个定时器 定时,把要处理的事件放第二个中断处理子程序中。
7-11 编写一段程序,功能要求为:当P1.0引脚的电平正跳变时,对P1.1的输入脉冲进行计
数;当P1.2引脚的电平负跳变时,停止计数,并将计数值写入R0、R1(高位存R1, 低位存R0)。
答:将P1.1的输入脉冲接入T0,即使用T0计数器完成对P1.1口的脉冲计数。R2中记T0
计满数的次数。 程序代码如下:
ORG 0000H LJMP MAIN ORG 000BH LJMP IT0 MAIN: JNB P1.0, MAIN
MOV TMOD, #05H ;定时/计数器T0为计数方式1 SETB TR0 ;启动T0,开始计数 SETB ET0 ;允许T0中断 SETB EA ;CPU开中断 WAIT: JB P1.2, WAIT CLR EA CLR TR0 MOV R1, TH0 MOV R0, TL0 AJMP $ IT0: INC R2 RETI 7-12 简述特殊功能寄存器SCON,TCON,TMOD功能。
答:SCON是串行口控制寄存器,主要用于控制、监视串行口的工作状态;TCON是定时控
制寄存器,主要用于控制定时/计数器的启动和停止、计数溢出标志和管理外部中断; TMOD是工作方式控制寄存器,主要用于设定定时/计数器的的工作方式和选定定时还 是计数以及门控INT0非信号。
10