1、MCS51单片机作业解答第二章 MCS-51单片机的结构和原理(1) MCS-51单片机芯片包含哪些主要功能部件? 答:CPU、4KBROM、128B RAM、4个8位I/O口、2个定时计数器、串行I/O口、中断系统、时钟电路、位处理器、总线结构。(2)MCS-51单片机的 /EA端有何用途? 答:当/EA =0 只访问片外程序区;当/EA=1时,先访问片内程序区,当PC超过片内程序容量时,自动转向外部程序区。(3)MCS-51单片机有哪些信号需要芯片引脚以第二功能的方式提供? 答:RXD、TXD、/INT0、/INT1、T0、T1、/WR、/RD(4)MCS-51单片机的4个I/O口在使用上
2、各有什么功能和特点? 答:P1口通用输入输出;P0口数据总线、地址总线低8位、通用输入输出 P2口地址总线高8位、通用输入输出 P3第2功能信号、通用输入输出。 (5)单片机的存储器分哪几个空间? 试述各空间的作用。 答:程序存储器:内部ROM、外部ROM 数据存储器:内部基本RAM、专用寄存器区、外部RAM(6)简述片内RAM中包含哪些可位寻址单元? 答:20H2FH共16个可寻址单元(7)什么叫堆栈? 堆栈指针SP的作用是什么? 在程序设计中为何要对SP重新赋值? 答:只允许数据单端输入输出的一段存储空间。 SP的作用是用来存放堆栈栈顶的地址。 因为SP的初值是07H,后继的是寄存器区和位
3、寻址区,为了便于编程工作,要修改SP.(8)程序状态字寄存器PSW 的作用是什么?简述各位的作用。 答:PSW用来存放程序执行状态的信息, CY加减运算的进位、借位 AC辅助进位标志,加减运算的低4位进位、借位(9)位地址65H 与字节地址65H 如何区别? 位地址65H具体在片内RAM中什么位置? 答:位地址65H中是一位0/1的数据,字节地址65H是8位0/1的数据。 位地址65H在片内RAM中2CH单元第5位。(10)什么是振荡周期、时钟周期、机器周期和指令周期? 如何计算机器周期的确切时间? 答:振荡周期为单片机提供信号的振荡源的周期时钟周期振荡脉冲2分频的信号机器周期完成一个基本操作
4、需要的时间,是振荡周期/12=1T指令周期执行1条指令需要的时间 14T(11)单片机工作时在运行出错或进入死循环时,如何处理? 答:复位处理,在单片机的RESET加持续1段时间的高电平(12)使单片机复位的方法有几种?复位后单片机的初始状态如何? 分上电复位和手动复位。复位后PC=0000H ALE=0 /PSEN=1(13)开机复位后,单片机使用的是哪组工作寄存器? 它们的地址是什么? 如何改变当前工作寄存器组? 答: 单片机使用的是第0组工作寄存器R0-R7, 对应的地址为00H-07H,采用置位复位RS1、RS0,可以改变单片机使用的工作寄存器。第3章 MCS-51单片机的汇编语言指令
5、系统单片机的指令格式为: 操作码+操作数 标号: 操作码助记符 目的操作数 ,源操作数 ;注释答: MCS-51单片机有7种寻址方式: 立即寻址、直接寻址、寄存器寻址、寄存器间接寻址、变址寻址、相对寻址、位寻址。立即寻址操作数在指令中直接给出。直接寻址操作数存放的地址在指令中给出。可寻址RAM128B和特殊功能寄存器寄存器寻址操作数在寄存器中。可寻址4组寄存器共32个字节即00H1FH寄存器间接寻址操作数的地址放在寄存器R0、R1、dptr中 R0、R1可寻址256B DPTR可寻址64KB变址寻址操作数的地址由变址寄存器A和基址寄存器DPTR、PC相加得到。 可寻址64KB的程序区相对寻址实
6、现程序的相对转移,地址范围-128+127位寻址按位寻址,操作数的地址为位地址。 可寻址 RAM区128bit 特殊功能区的128bit答: 对片内RAM可以用直接寻址和寄存器寻址方式。对片外RAM可以用寄存器寻址方式-答: 在对片外RAM单元的寻址中用Ri间接寻址只能寻址当前页的256B,用dptr间接寻址可以直接寻址64KB的内存答:(1)立即寻址 (2)直接寻址 (3)寄存器间接寻址 (4)寄存器寻址 (5)MOVC A A+DPTR变址寻址 (6)相对寻址 (7)CLR A 立即寻址 ,CLR C 位寻址 答: 这2条指令的操作结果相当,但是前1条指令速度快,指令短答: 如A= 12H
7、 (PC) = 0FFEH + 20H +3= 1021H 如A= 10H (PC)= 0FFEH +3 = 1001H第4章 MCS-51 单片机汇编语言程序设计 解: x equ 5AH Y EQU 5BH ORG 0100H START: CJNE A,#10, START1START1: JC START_M ;X=15 MOV B,A ;10=X15 MUL AB ADD A,#8 SJMP START_ENDSTART_M: MOV B,A ; X=flag; i-)if(si=0) & (si=a) & (si=A) & (si=F)tmpi = si - A + 10;else
8、tmpi = 0;result = result + tmpi*count;count = count*16;return result;解:#include #include typedef unsigned char bool;bool strend(unsigned char s, unsigned char t);int main()unsigned char s1 = abcdefg;unsigned char s2 = ef;bool flag = strend(s1, s2);printf(the result is %dn, flag);return 0;bool strend
9、(unsigned char s, unsigned char t)int ls = strlen(s); int lt = strlen(t); if (lt = 0) return 1; if (ls lt) return 0; return !strcmp(&sls-lt,t);解:晶振频率 12MHZ, 25ms中断1次,5次中断为125ms移位1次。#define uint unsigned int #define uchar unsigned char uchar temp,num;void main() TMOD=0x10;TH1=(65536-25000)/256;TL1=(6
10、5536-25000)%256;EA=1;ET1=1;TR1=1;P1=0xff;temp=0xfe;while(1)P1=temp; void time1() interrupt 3TH1=(65536-25000)/256;TL1=(65536-25000)%256;num+;if(num=5)num=0;temp=(temp7);答:不是, 5/9=0; 则c=0. 改为 C= 5.0/9.0 *(F-32.0) ;第6章 单片机内部资源解: 因为10KHZ的周期为100us ,定时器中断时间可为50us,因此有4中方式。 方式0: x= 213 -50*(12/12) =8192-50
11、 =1FCEH = 1 1111 1100 1110B TH0 = FEH TL0 = 0EH 方式1: x= 216 -50*(12/12) =65536-50 =FFCEH = 1111 1111 1100 1110B TH0 = FEH TL0 = CEH方式2: x= 28 -50*(12/12) =256-50 =CEH = 1100 1110B TH0 = CEH TL0 = CEH方式3: x= 28 -50*(12/12) =256-50 =CEH = 1100 1110B TL0 = CEH解: 1.采用汇编语言 定时为50ms,采用方式1,X=216 -50000*(12/
12、12)=3CB0HORG 000BH LJMP T0_INT MAIN: MOV TMOD, #01H MOV TH0, #3CH MOV TL0, #0B0H SETB ET0 SETB IE SETB TR0 CLR P2.0 SJMP $ T0_INT: MOV TL0, #0B0H MOV TH0, #3CH CPL P2.0 RETI2.采用c51语言 定时为50ms,采用方式1,X=216 -50000*(12/12) #include sbit P2_0 = P20; void main(void) TMOD = 0x01;P2_0 = 0;TH0 = (65536 500000
13、)/256 ;TL0 = (65536 500000)%256 ;EA=1 ;ET0 =1;TR0 =1;Do while (1); Void timer0(void) interrupt 1 TL0 = (65536 500000)%256 ;TH0 = (65536 500000)/256 ;P2_0 = !P2_0;解: 1.采用汇编语言 定时为100ms,采用方式1,X=216 -100000*(6/12)=3CB0H,当 中断3次时清0,满10次重新置1。ORG 000BH LJMP T0_INT MAIN: MOV TMOD, #01H MOV TH0, #3CH MOV TL0,
14、 #0B0H MOV R2,#0 SETB ET0 SETB IE SETB TR0 SETB P1.0 SJMP $ T0_INT: MOV TL0, #0B0H MOV TH0, #3CH INC R2 CJNE R2,#3,T0_INT1 CLR P1.0 RETIT0_INT1:CJNE R2,#10, T0_INT2 SETB P1.0 MOV R2,#0T0_INT2: RETI2.采用c51语言 定时为100ms,采用方式1,X=216 -100000*(6/12) #include sbit P1_0 = P10; uchar NUM =0; void main(void) T
15、MOD = 0x01;P1_0 = 1;TH0 = (65536 500000)/256 ;TL0 = (65536 500000)%256 ;EA=1 ;ET0 =1;TR0 =1;Do while (1); Void timer0(void) interrupt 1 TL0 = (65536 500000)%256 ;TH0 = (65536 500000)/256 ;NUM+;If (NUM =3) P1_0 = 0;Else if (NUM =10) NUM =0; P1_0 =1;解: 1.采用汇编语言 定时为100ms,采用方式1,X=216 -100000*(6/12)=3CB0
16、H,当 中断10次时清0,满20次重新置1。ORG 000BH LJMP T0_INT MAIN: MOV TMOD, #01H MOV TH0, #3CH MOV TL0, #0B0H MOV R2,#0 SETB ET0 SETB IE SETB TR0 SETB P1.7 SJMP $ T0_INT: MOV TL0, #0B0H MOV TH0, #3CH INC R2 CJNE R2,#10,T0_INT1 CLR P1.7 RETIT0_INT1:CJNE R2,#20, T0_INT2 SETB P1.7 MOV R2,#0T0_INT2: RETI2.采用c51语言 定时为10
17、0ms,采用方式1,X=216 -100000*(6/12) #include sbit P1_7 = P17; uchar NUM =0; void main(void) TMOD = 0x01;P1_7 = 1;TH0 = (65536 500000)/256 ;TL0 = (65536 500000)%256 ;EA=1 ;ET0 =1;TR0 =1;Do while (1); Void timer0(void) interrupt 1 TL0 = (65536 500000)%256 ;TH0 = (65536 500000)/256 ;NUM+;If (NUM =10) P1_7 =
18、 0;Else if (NUM =20) NUM =0; P1_7 =1;解: 1.采用汇编语言 定时为100ms,采用方式1,X=216 -100000*(6/12)=3CB0H,当中断10次时p1.0=0,外部INT0中断时 p1.0=1,启动定时器。 ORG 0000H LJMP MAINORG 0003H LJMP INT0_INT ORG 000BH LJMP T0_INT MAIN: MOV TMOD, #01H MOV TH0, #3CH MOV TL0, #0B0H MOV R2,#0 SETB ET0 SETB IE SETB EX0 SETB IT0 SETB P1.0 C
19、LR P1.1 SJMP $ T0_INT: MOV TL0, #0B0H MOV TH0, #3CH INC R2CJNE R2,#10, T0_INT2 SETB P1.0 CLR P1.1 CLR TR0 T0_INT2: RETIINT0_INT: SETB TR0 MOV R2,#0 CLR P1.0 SETB P1.1 RETI2.采用c51语言 定时为100ms,采用方式1,X=216 -100000*(6/12) #include sbit P1_0 = P10; sbit P1_1 = P11; uchar NUM =0; void main(void) TMOD = 0x0
20、1;P1_0 = 1;P1_1 = 0;TH0 = (65536 500000)/256 ;TL0 = (65536 500000)%256 ;EA=1 ;ET0 =1;EX0 =1;IT0 =1;Do while (1); Void timer0(void) interrupt 1 TL0 = (65536 500000)%256 ;TH0 = (65536 500000)/256 ;NUM+;If (NUM =10)P1_0 =1;P1_1 =0;TR0 =0;Void INT_0(void) interrupt 0 P1_0 =0;P1_1 =1;TR0 =1;NUM =0; 解:外部脉
21、冲由管脚输入,可设T0工作于定时器方式1,计数初值为0,当 输入高电平时对T0计数,当高电平结束时,计数值乘上机器周期数就是脉冲宽度。工作方式控制字TMOD=00001001B=09H,计数初值TH1=00、TL0=00H。汇编语言程序: ORG 0000H LJMP MAIN ORG 0100HMAIN: MOV TMOD ,#09H ;T0定时,方式1,GATE=1 MOV TH0 ,#00H ;置TH0计数初值 MOV TL0 ,#00H ;置TL0计数初值WAIT: JB P3.2 WAIT ;等待/P3.2引脚变为低电平 SETB TR0 ;预启动T0WAIT1: JNB P3.2
22、,WAIT1 ;等待/P3.2引脚变为高电平、启动计数WAIT2: JB P3.2 ,WAIT2 ;等待/P3.2引脚再变为低电平 CLR TR0 ;停止计数 MOV 51H ,TH1 ;读取计数值,存入指定的单元 MOV 50H ,TL1 SJMP $ ENDC语言程序:#include unsigned char data *p;void main(void)TMOD=0x09; /* T0工作在定时器方式1,GATE=1 */TH0=0;TL0=0;do while (P3.2); /* 等待/P3.2引脚变为低电平 */TR0=1; /* 启动定时器/计数器0 */do while (
23、! P3.2); /* 等待引脚变为高电平、启动计数*/do while (P3.2); /* 等待引脚再变为低电平 */TR0=0; /* 停止计数 */p=0x50;*p=TL0;p=p+1;*p=TH0;解: 有4种工作方式方式0: 8位同步移位寄存器方式,波特率 fosc/12方式1: 10位异步收发方式,波特率 可变方式2: 11位异步收发方式,波特率 fosc/32、fosc/64 方式3: 11位异步收发方式,波特率 可变解: 串口SBUF 分接收SBUF和发送SBUF,占用同一地址。解:分析:甲、乙两机都选择方式1:8位异步通信方式,最高位用作奇偶校验,波特率为1200bps,
24、甲机发送,乙机接收,因此甲机的串口控制字SCON为40H,乙机的串口控制字SCON为50H。设甲、乙两机的振荡频率为12MHZ,由于波特率为1200。SMOD =0 ,定时/计数器T1选择为方式2,则初值为:初值=256 - fosc2SMOD /(12波特率32)=256-12000000/(12120032)230=E6H根据要求定时/计数器T1的方式控制字TMOD为20H。甲机的发送程序:TSTART:MOV TMOD,#20H MOV TL1,#0E6HMOV TH1,#0E6HMOV PCON,#00HMOV SCON,#40HMOV R0,#30HMOV R7,#10HSETB T
25、R1LOOP:MOV A,R0MOV SBUF,AWAIT:JNB TI,WAIT CLR TI INC R0 DJINZ R7,LOOP RET乙机接收程序:RSTART:MOV TMOD,#20H MOV TL1,#0E6H MOV TH1,#0E6HMOV PCON,#00HMOV DPTR,#0030H MOV R7,#10HSETB TR1;启动定时器1LOOP:MOV SCON,#50H WAIT:JNB RI,WAITMOV A,SBUFMOVX DPTR,AINC R0DJNZ R7,LOOPRET甲机对应的C语言发送程序如下:#include “reg51.h” /* 包含8
26、051单片机的寄存器定义头文件 */unsigned char data ADDRA 0X30; /* 在RAM区定义16个单元 */unsigned char num=0; /* 声明计数变量 */unsigned char *p; /* 定义 p为指针 */void main(void) /* 主程序 */SCON=0x40; /* 置串行口工作方式1 */TMOD=0x20; /* 定时器1为工作方式2 */PCON=0x00; /* SMOD=0 */TL1=0xe6; /* 置计数初值 */TH1=0xe6; /* 计数重装值 */ TR1=1; /* 启动定时器1 */ EA=1;
27、 /* 开中断 */ES=1; /* 串行口开中断 */p=ADDRA; /* 设置发送数据缓冲器区指针 */SBUF=*p; /* 发送第一个数据 */while (1); /* 等待中断 */void Ser_T1A (void) interrupt 4 /* 中断号4是串行中断 */TI=0; /* 清发送中断标志 */num+; /* 计数变量加1 */if (num=0x10) ES=0; /* 判断是否发送完,若已完,则关中断 */else /* 否则,修改指针,发送下一个数据 */ p+; SBUF=*p; 乙机对应的C语言程序如下:#include “reg51.h” unsigned char xdata ADDRB 0X0030; unsigned char num=0; /* 声明计数变量 */unsigned char *p; /* 定义 p为指针 */void main(void) /* 主程序 */SCON=0x50; /* 置串行口工作方式1,