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
void main(void) {
P1 |= 0xf8; while(1); }
5-9 设8次采样值依次存放在20H~27H的连续单元中,采用算术平均值滤波法求采样平均值,结果保留在30H单元中。试编写程序。 答:#pragma small
#include
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 min = *dp; dp++; if(min>*dp) min = *dp; } dp = 0x21; *dp = min; while(1); } 6-10 某系统有三个外部中断源1、2、3,当某一中断源变低电平时便要求CPU处理,它们的优先处理次序由高到低为3、2、1,处理程序的入口地址分别为2000H、2100H、2200H。试编写主程序及中断服务程序(转至相应的 入口即可)。 答:对系统的三个外中断源,可利用MCS-51的2个外中断源INT0和INTI,再将定时/计 数器T1 作为扩展的外部中断使用,INT0接外中断源3,INTI接外中断源2,定时/计数器T1接外中断源1,3个中断源设置为同级中断,外中断源1、2、3依次接到P1.0、P1.1、P1.2上。 汇编语言程序代码如下: ORG 0000H ;复位入口地址 AJMP MAIN ;转主程序 ORG 0003H AJMP INT1 ORG 0100H MAIN: MOV TMOD, #60H ;T1方式2 MOV TH1, #0FFH MOV TL1, #0FFH ;置初值 SETB TR1 ;启动计数器T1 SETB EA ;CPU中断开放 SETB ET1 ;允许T1中断 SETB IT0 ;允许外中断0产生中断 SETB IT1 SETB PX0 ;外中断0为高级中断 SETB PX1 SETB PT1 SETB IT0 ;外中断0为跳沿触发方式 SETB IT1 LOOP1: SJMP LOOP1 ;等待中断 ;中断服务程序 ORG 1000H INT1: PUSH PSW ;保护现场 PUSH ACC JB P1.0,IR1 ;P1.0高,外中断1有请求 JB P1.1,IR2 ;P1.1高,外中断2有请求 JB P1.2,IR3 ;P1.2高,外中断3有请求 INTIR: POP ACC ;恢复现场 POP PSW RETI ;中断返回 ORG 2000H IR1: … … ;外中断1的中断处理程序 AJMP INTIR ORG 2100H IR2: … … ;外中断2的中断处理程序 AJMP INTIR ORG 2200H IR3: … … ;外中断3的中断处理程序 AJMP INTIR END 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-7 编写程序,要求使用T0,采用方式2定时,在P1.0输出周期为400μs,占空比为10:1的矩形脉冲。 答:本题采用晶体振荡器频率为12MHz,使用定时器配合计数器,设计成一个40μs定时将P1.0置0和一个400μs定时将P1.0置1。 ORG 0000H ;中断入口地址 AJMP START ORG 000BH ;定时器0的中断向量地址 AJMP TIME0 ORG 0030H START: MOV SP, #5FH MOV 30H, #00H ;软件计数器清零 MOV TMOD, #02H ;T0工作在方式1 MOV TH0, #216 MOV TL0, #216 SETB EA SETB ET0 SETB TR0 ;任意程序段 TIME0: PUSH ACC ;中断处理子程序 PUSH PSW CLR P1.0 INC 30H MOV A, 30H CJNE A, #10, T0_4 SETB P1.0 MOV 30H, #00H T0_4: POP PSW POP ACC RETI END 7-9 利用定时/计数器T0产生定时时钟,由P1口控制8个指示灯。编一个程序,使8个指示灯依次一个一 个闪动,闪动频率为20次/秒(8个灯依次亮一遍为一个周期)。 答:本题采用晶体振荡器频率为12MHz,每个灯的闪烁周期是:50ms,采用工作方式1。 ORG 0000H AJMP START ORG 000BH AJMP TIME0 ORG 0030H START: MOV SP, #5FH MOV R7, #0FEH MOV TMOD, #01H ;T0在工作方式1 MOV TH0, #3CH MOV TL0, #0B0H SETB EA SETB ET0 SETB TR0 S0: AJMP S0 ;此处放任意程序段 TIME0: PUSH ACC PUSH PSW MOV P1, R7 MOV A, R7 RL A MOV R7, A MOV TH0, #3CH MOV TL0, #0B0H POP PSW POP ACC RETI END 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-18 为什么定时/计数器T1用做串行口波特率发生器时,应采用方式2?若已知时钟频率、通信波特率,如何计算其初值? 答:因为方式2是有自动重装载计数值的功能,从而可以产生精确的波特率。串行工作方式0和方式2波特率是固定的,所以不用设初值;串行工作方式1和方式3时: 波特率:BR = (2 SMOD ×T)/32 dd osc 溢出一次的时间:1/T= (256-TH1)*12/f 溢出率:T= f/[12×(256-TH1)] d osc 初值:TH1 = 256- f/(12* T) osc d 7-19 若晶体振荡器为11.059MHz,串行口工作于方式1,波特率为4800b/s,写出用T1作为波特率发 生器的方式控制字和计数初值。 答: MOV TMOD, #20H MOV TH1, #0FAH MOV TL1, #0FAH SETB TR1 MOV SCON, #50H 7-20 利用单片机串行口扩展24个发光二极管和8个按键,要求画出电路图并编写程序使24个发光二极管按照不同的顺序发光(发光的时间间隔为1s)。 答: ORG 1000H START: MOV SCON, #00H ;串行口工作方式0 MOV R0, #00H MOV R7, #03H MOV R6, #24H CLR P1.0 ;关闭并行输出 LOOP: MOV A, @R0 MOV DPTR, #TAB ;查表取数,送出 MOVC A, @A+DPTR MOV SBUF, A OUT0: JNB TI, OUT0 INC R0 CLR TI DJNZ R7, LOOP SETB P1.0 ;开启并行输出 ACALL DELAY DJNZ R6, START AJMP LOOP DELAY: MOV R2, #250 D1: MOV R3, #100 D2: MOV R4, #20 D3: DJNZ R4, D3 DJNZ R3, D2 DJNZ R2, D1 RET TAB: DB 00000000B, 00000000B, 00000001B, 00000000B DB 00000000B, 00000010B, 00000000B, 00000000B DB 00000100B, 00000000B, 00000000B, 00001000B DB 00000000B, 00000000B, 00010000B, 00000000B DB 00000000B, 00100000B, 00000000B, 00000000B DB 01000000B, 00000000B, 00000000B, 10000000B DB 00000000B, 00000001B, 00000000B, 00000000B DB 00000010B, 00000000B, 00000000B, 00000100B DB 00000000B, 00000000B, 00001000B, 00000000B DB 00000000B, 00010000B, 00000000B, 00000000B DB 00100000B, 00000000B, 00000000B, 01000000B DB 00000000B, 00000000B, 10000000B, 00000000B DB 00000001B, 00000000B, 00000000B, 00000010B DB 00000000B, 00000000B, 00000100B, 00000000B DB 00000000B, 00001000B, 00000000B, 00000000B DB 00010000B, 00000000B, 00000000B, 00100000B DB 00000000B, 00000000B, 01000000B, 00000000B DB 00000000B, 10000000B, 00000000B, 00000000B END 11-4 试设计一个顺序开关灯控制器,要求当按钮K第一次按下时,灯A立刻亮,灯B在延时11秒钟后亮,在灯B亮后15秒,灯C亮;当按钮K第2次按下时,灯C立刻灭,延时17秒后灯B灭,灯B灭后12秒,灯A灭。 #include #define uint unsigned int unsigned char sum=0;