第6章单片机串行通信系统习题解答一、填空题1.在串行通信中,把每秒中传送的二进制数的位数叫波特率。
2.当SCON中的M0M1=10时,表示串口工作于方式 2 ,波特率为 fosc/32或fosc/64 。
3.SCON中的REN=1表示允许接收。
4.PCON 中的SMOD=1表示波特率翻倍。
5.SCON中的TI=1表示串行口发送中断请求。
6.MCS-51单片机串行通信时,先发送低位,后发送高位。
7.MCS-51单片机方式2串行通信时,一帧信息位数为 11 位。
8.设T1工作于定时方式2,作波特率发生器,时钟频率为11.0592MHz,SMOD=0,波特率为2.4K时,T1的初值为 FAH 。
9.MCS-51单片机串行通信时,通常用指令 MOV SBUF,A 启动串行发送。
10.MCS-51单片机串行方式0通信时,数据从 P3.0 引脚发送/接收。
二、简答题1.串行口设有几个控制寄存器?它们的作用是什么?答:串行口设有2个控制寄存器,串行控制寄存器SCON和电源控制寄存器PCON。
其中PCON 中只有PCON.7的SMOD与串行口的波特率有关。
在SCON中各位的作用见下表:2.MCS-51单片机串行口有几种工作方式?各自的特点是什么?答:有4种工作方式。
各自的特点为:3.MCS-51单片机串行口各种工作方式的波特率如何设置,怎样计算定时器的初值? 答:串行口各种工作方式的波特率设置:工作方式O :波特率固定不变,它与系统的振荡频率fosc 的大小有关,其值为fosc/12。
工作方式1和方式3:波特率是可变的,波特率=(2SMOD/32)×定时器T1的溢出率 工作方式2:波特率有两种固定值。
当SM0D=1时,波特率=(2SM0D/64)×fosc=fosc/32当SM0D=0时,波特率=(2SM0D/64)×fosc=fosc/64计算定时器的初值计算:4.若fosc = 6MHz ,波特率为2400波特,设SMOD =1,则定时/计数器T1的计数初值为多少?并进行初始化编程。
答:根据公式N=256-2SMOD ×fosc /(2400×32×12)= 242.98≈243 =F3HTXDA: MOV TMOD,#20H;置T1定时器工作方式2 MOV TL1,#0F3H ;置T1计数初值.MOV TH1,#0F3HMOV PCON,#80H ;置SMOD =1Bf B f N OSC SMOD OSC SMOD ⨯⨯-=⨯⨯⨯-=3842256123222565.用8051串行口外接CD4094扩展8位并行输出口,驱动8个LED发光二极管。
画出硬件电路图,编写程序,使LED发光二极管从左到右依次闪亮。
答:电路图如下LED发光二极管从左到右循环点亮的C51参考程序:#include<reg51.h> //包含51单片机寄存器定义的头文件#include<intrins.h> //包含函数_nop_()定义的头文件unsigned char code Tab[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//流水灯控制码,该数组被定义为全局变量sbit P17=P1^7;void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/**************************************************************函数功能:发送一个字节的数据**************************************************************/void Send(unsigned char dat){P17=0; //P1.7引脚输出锁存信号,对cd4094锁存nop_(); //延时一个机器周期_nop_(); //延时一个机器周期,保证锁存完成P17=1; //结束对cd4094的锁存SBUF=dat; //将数据写入发送缓冲器,启动发送while(TI==0) //若没有发送完毕,等待;TI=0; //发送完毕,TI被置“1”,需将其清0}/*******************************************函数功能:主函数******************************************/void main(void){unsigned char i;SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0while(1){for(i=0;i<8;i++){Send(Tab[i]); //发送数据delay(); //延时}}}三、Proteus仿真1.在Proteus下,仿真实现6.6节内容。
答:全自动洗衣机串行方式时间显示Proteus仿真为节省单片机并口资源,全自动洗衣机时间显示可用串口实现。
一次洗衣时间一般不会超过99分钟,用2位LED数码管显示时间即可。
电路如图6-9所示。
移位寄存器,功能是接收AT89C51单片机串行通信口输出的串行数据并转换成并行数据输出,从而驱动LED数码管显示。
74LS164的1、2脚为数据输入端,接单片机串行口的RXD 端(P3.0脚),74LS164的第8脚为时钟脉冲输入端(CLK),接单片机串行口的TXD端(P3.1脚),第9脚R为清零端,低电平清零,正常工作时接高电平。
两只LED数码管采用共阴极静态显示方式。
下列程序实现串行两位LED数码管时间显示,显示范围为00—99分钟。
使用串行口进行信息传送,程序编写相当简单,用户只需将需要显示的数据直接送串口发送缓冲器,等待串行中断即可。
汇编语言参考程序:ORG 0000H ;在0000H单元存放转移指令LJMP NAIN ;转移到主程序ORG 000BH ;定时器T0的中断入口地址LJMP INTERRUPT ;转移到中断子程序ORG 0200H ;主程序从0200H开始MAIN: MOV TMOD,#01H ;使用定时器T0,工作方式1MOV TH0, #3CH ;置初T0值50msMOV TL0, #0B0HHMOV R0,#0 ;用于存1秒的计数次数SETB EA ;开中断总允许SETB ET0 ;允许T0中断SETB TR0 ;启动计时LOOP: LCALL Display ;循环调用显示子程序SJMP LOOPTAB: DB 3FH,06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH ;0~9的共阴极段码DISPLAY: ;显示子程序(显示分钟)MOV DPTR, #TAB ;将表首地址赋给DPTRMOV A, 30H ;将30H中存放的分计数赋给累加器AMOV B, #0AH ;将10赋给累加器BDIV AB ;分计数除以10得十位数放在A中,个位数放在B中MOVX A, @A+DPTR ;查表得十位数的`显示段码MOV SBUF, A ;发送十位数L1: JBC TI, L2 ;判是否发送完,未发完循环等待,若发完则转L2 SJMP L1L2: MOV A, B ;将个位数赋给累加器AMOVX A, @ A+DPTR ;查表得个`位数的显示段码MOV SBUF, A ;发送个位数L3: JBC TI, L4 ;判是否发送完,未发完循环等待,若发完则转L4 SJMP L3L4: RET ;子程序返回INTERRUPT: ;中断服务子程序INC R0 ;每中断一次(50ms)加1CJNE R0, #20, L5 ;判是否中断20次,若不是则转L5中断返回,若是则顺序执行CLR R0 ;到1秒钟,清R0INC R1 ;秒计数加1CJNE R1, #60, L5 ;判秒是否计满60次,若未满则转L5中断返回,若满则顺序执行CLR R1 ;如果秒计满60,将秒计数单元内容清0INC 30H ;分钟计数单元30H内容加1CJNE 30H, #99, L5 ;判分是否计满99次,若未满则转L5中断返回,若满则顺序执行CLR R1 ;如果分计满99,将秒计数单元内容清0CLR 30H ;同时将分计数单元内容清0L5: MOV TH0, #3CH ; 定时器重新赋初值MOV TL0, #0B0HHRETI ;中断返回C语言参考程序:#include<reg51.h> // 包含51单片机寄存器定义的头文件unsigned char Tab[ ]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数组Tab放0~9的共阴极字段码unsigned char int_time; //设中断次数计数变量unsigned char second; //秒计数变量unsigned char minute; //分钟计数变量void delay(void) //延时函数{unsigned char n,j; //设计数循环变量for(j=0;j<200;j++); //通过循环延时for(n=0;n<200;n++); //通过循环延时}void DisplayMinute(unsigned char m) //显示函数{ unsigned char ge, si; //定义变量ge、si,用于存放个位、十位si=Tab[m/10]; //计算出十位的值,查表转换成相应的段码送变量si SBUF=si; //发送显示十位while(TI==0); //等待发送完毕TI=0; //发送完后清中断标志ge=Tab[m%10]; //计算出十位的值,查表转换成相应的段码送变量geSBUF=ge; //发送显示个位while(TI==0); //等待发送完毕TI=0; //发送完后清中断标志delay(); //调延时函数,是数码管显示有一定的亮度delay();}void main(void) //主函数{TMOD=0x01; //使用定时器T0,工作方式1EA=1; //开中断总允许ET0=1; //允许T0中断TH0=(65536-46083)/256; //定时器高八位赋初值(50ms)TL0=(65536-46083)%256; //定时器低八位赋初值TR0=1; //启动计时PCON=0x00; //置SMOD=0SCON=0x00; //串行口工作在方式0while(1) //无限循环体{DisplayMinute(minute); //调用分钟显示子程序}}void interserve(void ) interrupt 1 //计数器T0中断函数{int_time++; //每中断一次(50ms)加1if(int_time==20) // 50ms记20次为1秒(仿真时可将次数改小,减少等待时间)。