单片机课后习题.docx
《单片机课后习题.docx》由会员分享,可在线阅读,更多相关《单片机课后习题.docx(42页珍藏版)》请在冰豆网上搜索。
单片机课后习题
P148作业
5-5请分别定义下列变量:
(1)片内RAM中无符号字符型变量x;
unsignedchardatax;
(2)片内RAM中位寻址区无符号字符型变量y,将y.0-y.2再分别定义为位变量key_in、key_up、key_down;
unsignedcharbdatay;
sbitkey_in=y^0;
sbitkey_up=y^1;
sbitkey_down=y^2;
(3)片外RAM中整型变量x,并指定变量x的绝对地址为4000H;
xdataintx_at_0x4000;
或#definexXWORD[[0x2000]
(4)特殊功能寄存器变量PCON;
sfrPCON=0x87;
5-7用C51语言编程实现,片内扩展RAM的000EH单元和000FH单元的内容交换。
#include
voidmain()
{
unsignedchar*pp1,*pp2,temp;
AUXR&=0xfd;
pp1=0x000e;
pp2=0x000f;
temp=*pp1;
*pp1=*pp2;
*pp2=temp;
}
5-9试用C51语言编写程序实现将片内RAM21H单元存放的两位BCD码数转换为十六进制数存入30H单元。
dataunsignedchary1_at_0x21;
dataunsignedchary2_at_0x30;
voidmain()
{unsignedchartemp;
temp=y1;
y1=(y1&0xf0)>>4;
y2=y1*10+(temp&0x0f);
}
P208作业
7-7在STC12C5A60S2单片机中,假设系统的时钟频率为12MHz,利用定时/计数器T0,分别用汇编语言和C51编程实现在P1.0引脚输出周期为2s的方波。
分析:
仿例题7-3,要产生周期2s的方波,需定时1s,一个定时器完成不了,可定时50ms,T0工作在方式1,然后利用R7对50ms定时中断计数20次来实现。
选择12T模式,T0x12=0,f=12MHz,则需计数50000,初值为65536-50000=15536=3CB0H
(1)汇编程序:
ORG0000H
LJMPMAIN
ORG000BH;T0的中断向量入口地址
LJMPT0_INT
ORG0100H
MAIN:
MOVSP,#0BFH;初始化堆栈指针
MOVTMOD,#01H;T0工作在方式1
MOVTL0,#0B0H;给T0写入初值
MOVTH0,#03CH
MOVR7,#20;利用寄存器R7计数20次
SETBEA;开放总中断
SETBET0;T1溢出中断允许
SETBTR0;启动T1开始工作
SJMP$
T0_INT:
MOVTL0,#0B0H;重新赋初值
MOVTH0,#03CH
DJNZR7,NEXT
CPLP1.0
MOVR7,#20;重新赋给R7值50
NEXT:
RETI
END
(1)C51程序:
#include/
sbitP1_0=P1^0;
unsignedchari=0;
voidmain()
{
TMOD=0x01;//T0工作在方式1
TL0=0xB0;//给T0装入初值
TH0=0x3C;
EA=1;//开放总中断
ET0=1;//T0溢出中断允许
TR0=1;//启动T0开始工作
while
(1);
}
voidT0_INT()interrupt1//T0中断服务程序
{
TH0=0x3C;
TL0=0xB0;//重新置入初值
i++;
if(i==20)
{
P1_0=!
P1_0;
i=0;
}
}
7-8由P1口驱动8个指示灯,利用定时/计数器T1的定时功能分别用汇编语言和C51编程实现8个指示灯依次循环点亮(输出高电平),点亮间隔为1s,反复循环。
分析:
仿照上题,T1需定时50ms,R7计数20次,达到定时1s的目的,每隔1s,循环一次,实现轮流点亮。
(1)汇编程序
ORG0000H
LJMPMAIN
ORG001BH;T1的中断向量入口地址
LJMPT1_INT
ORG0100H
MAIN:
MOVSP,#0BFH;初始化堆栈指针
MOVTMOD,#10H;T1工作在方式1
MOVTL1,#0B0H;给T1写入初值
MOVTH1,#03CH
MOVR7,#20;利用寄存器R7计数20次
MOVA,#01H
SETBEA;开放总中断
SETBET1;T1溢出中断允许
SETBTR1;启动T1开始工作
SJMP$
T1_INT:
MOVTL1,#0B0H;重新赋初值
MOVTH1,#03CH
DJNZR7,NEXT;R7减1不为0,说明中断次数未
;到20次,跳转到NEXT处返回
MOVP1,A;
RLA;为下一次做准备
MOVR7,#20;重新赋给R7值50
NEXT:
RETI
END
(2)C51程序:
#include
unsignedchari=0;
unsignedcharj;
voidmain()
{
TMOD=0x10;//T1工作在方式1
TL1=0xB0;//给T1装入初值
TH1=0x3C;
j=0x01;
EA=1;//开放总中断
ET1=1;//T1溢出中断允许
TR1=1;//启动T1开始工作
while
(1);
}
voidT1_INT()interrupt3//T1中断服务程序
{
TH1=0x3C;
TL1=0xB0;//重新置入初值
i++;
if(i==20)
{
P1=j;//已定时中断20次
i=0;
j=_crol_(j,1);
}
}
7-12假设系统时钟频率为12MHz,利用PCA模块的功能,分别用汇编语言和C51编程实现在P1.3引脚上间断重复输出频率为450Hz的方波,持续和停止时间均为4s。
分析:
将PCA模块的工作方式寄存器CCAPM0寄存器写为4DH,即PCA0设为时钟输出方式,从而可以在P1.3引脚自动翻转,输出方波,并允许PCA中断。
要求方波频率为450hz,即周期为1/450,定时时间应设定为1/900s,选择计数器时钟来源为系统时钟频率的12分频,即工作方式寄存器CMOD设为00H,需要计数(1/900)/(12/)=10000/9≈1111=0457H个时钟脉冲,可将CL、CH初始值设为零,CCAP0H设为04H,CCAP0L设为57H,在每次PCA中断里:
将计数值加到比较匹配寄存器里CCAP0H+=4,CCAP0L+=57H
4秒启动一次PCA计数(CR=1),4秒停止(CR=0);
4秒定时器由T1产生,工作在方式1定时50毫秒,计数时钟fosc/12
初值N,则(65536-N)*1=50000→N=15536=3cb0H
(1)汇编程序:
CCONEQU0D8H;PCA控制寄存器
CMODEQU0D9H;PCA模式寄存器
CLEQU0E9H;PCA定时器的低8位
CHEQU0F9H;PCA定时器的高8位
CCAPM0EQU0DAH;PCA模块0的模式寄存器
CCAP0LEQU0EAH;PCA模块0的捕获寄存器的低8位
CCAP0HEQU0FAH;PCA模块0的捕获寄存器的高8位
AUXREQU8EH
CRBITCCON.6;PCA定时控制位
CFBITCCON.7;PCA溢出标志位
ORG0000H
LJMPMAIN
ORG001BH
LJMPT1_INT
ORG003BH
LJMPPCA_INT
ORG0100H
MAIN:
CLRA
MOVCCON,A;//(P197)
MOVCL,A;
MOVCH,A;
MOVSP,#0BFH;初始化堆栈指针
MOVTMOD,#10H;T1工作在方式1
MOVTL1,#B0H;给T1写入初值
MOVTH1,#3CH;
ANLAUXR,#1H;//T1X12=0
MOVCCAPM0,#4DH;//允许中断,输出方波
MOVCCAP0L,#57H;
MOVCCAP0H,#04H;
MOVCMOD,#0H;//FOSC/12时钟计数
MOVR7,#80;利用寄存器R7计数80次
SETBEA;
SETBET1;
SETBTR1;
SETBCR
SJMP$
T1_INT:
MOVTL1,#B0H;给T1写入初值
MOVTH1,#3CH;
DJNZR7,NEXT;
MOVC,CR
CPLC
MOVCR,C
MOVR7,#80;
NEXT:
RETI
PCA_INT:
PUSHPSW
PUSHACC
CLRCCF0
MOVA,CCAP0L
ADDA,#57H
MOVCCAP0L,A
MOVA,CCAP0H
ADDCA,#04H
MOVCCAP0H,A
POPACC
POPPSW
RETI
END
C51程序:
#include
unsignedchari=0;
voidmain()
{
TMOD=0x10;
TL1=0xB0;
TH1=0x3C;
CMOD=0x00;
AUXR&=0xBF;
CCAPM0=0x4D;
CCAP0L=0x57;
CCAP0H=0x04;
EA=1;
ET1=1;
TR1=1;
CR=1;
while
(1);
}
voidT1_INT()interrupt3
{
TH1=0xB0;
TH1=0x3C;
i++;
if(i==80)
{
CR=!
CR;
i=0;
}
}
voidpca_INT()interrupt7
{
CCAP0L+=0x57;
CCAP0H+=0x04;
}
7-13假设系统的时钟频率为11.0592MHz,利用PCA模块的PWM功能分别用汇编语言和C51编程实现输出400Hz且占空比为60%的矩形波。
分析:
仿照例题7-8,系统的时钟频率为11.0592MHz,根据公式PWM的频率=
,计算出PCA的时钟源频率为102400Hz,用T0的溢出作为PCA时钟源,
102400=108,即对系统时钟源fosc进行108级分频,设T0工作在1T模式,T0的初值为256-108=148=80H,由占空比=
=0.6,可计算出CCAP0L=66H,CMOD寄存器应赋值为04H,CCAPM0寄存器初值为42H。
(1)汇编语言程序:
CCONEQU0D8H;PCA控制寄存器
CMODEQU0D9H;PCA模式寄存器
CLEQU0E9H;PCA定时器的低8位
CHEQU0F9H;PCA定时器的高8位
CCAPM0EQU0DAH;PCA模块0的模式寄存器
CCAP0LEQU0EAH;PCA模块0的捕获寄存器的低8位
CCAP0HEQU0FAH;PCA模块0的捕获寄存器的高8位
AUXREQU8EH
CRBITCCON.6;PCA定时控制位
CFBITCCON.7;PCA溢出标志位
ORG0000H
CLRA
MOVCCON,A
MOVCL,A;计数器初值复位
MOVCH,A
MOVTMOD,#02H
MOVTL0,#80H;给T0赋初值
MOVTH0,#80H
MOVCMOD,#04H;利用T0的溢出作PCA时钟源
MOVAUXR,#80H;T0工作在1T模式
MOVCCAPM0,#42H;允许P1.3引脚作脉宽调节输出
MOVCCAP0L,#66H;用于输出占空比为60%的波形
MOVCCAP0H,#66H
SETBTR0;T0计数器启动工作
SETBCR;PCA计数器启动工作
SJMP$
(2)C51程序:
#include//包含用于定义STC12C5Axx系列单片机片内资源的头文件
voidmain()
{
CCON=0x00;//PCA控制寄存器清0
CL=0x00;//16位PCA计数器清0
CH=0x00;
TMOD=0x02;//T0工作在方式2
TL0=0x80;//给T0赋初值
TH0=0x80;
CMOD=0x04;//利用T0的溢出作PCA时钟源
AUXR=0x80;//T0工作在1T模式
CCAPM0=0x42;//允许比较且作为PWM脉宽调节输出
CCAP0L=0x66;//控制模块0的输出占空比为40%
CCAP0H=0x66;
TR0=1;//T0开始工作
CR=1;//16位计数器开始工作
while
(1);
}
8-9甲乙两机利用串行口1的方式1实现双机通信,甲机将片内RAM中30H-3FH单元的内容传送到乙机片内RAM的50H-5FH单元,假设甲乙两机的波特率为2400bps,系统的时钟频率为11.0592MHz,试画出双机通信的电路图,并用汇编语言和C51分别编写相应的程序实现上述任务。
分析:
甲乙两机都选择串行口1工作在方式3,9位异步通信方式,TB8作为奇偶校验位,甲机控制字SCON=0C0H,乙机SCON=0D0H。
利用定时器T1工作在12T模式,方式2作为串行口的波特率发生器,TMOD=20H,设SMOD=0,PCON=7FH,波特率为2400bps,系统的时钟频率为11.0592MHz,可知T1的重装初值为F4H,
汇编子程序:
TRA_UART:
MOVTMOD,#20H
ANLAUXR,#0BFH
MOVTL1,#0F4H
MOVTH1,#0F4H
ANLPCON,#7FH
MOVSCON,#0C0H
MOVR0,#30H
MOVR7,#10H
SETBTR1
LOOP:
MOVA,@R0
MOVC,P
MOVTB8,C
MOVSBUF,A
WAIT:
JNBTI,WAIT
CLRTI
INCR0
DJNZR7,LOOP
RET
已机接收子程序:
RES_UART:
MOVTMOD,#20H
MOVTL1,#0F4H
MOVTH1,#0F4H
ANLAUXR,#0BFH
ANLPCON,#7FH
MOVSCON,#0D0H
MOVR0,#50H
MOVR7,#10H
SETBTR1
LOOP:
NOP
WAIT:
JNBRI,WAIT
CLRRI
MOVA,SBUF
MOVC,P
ANLC,/RB8
MOVF0,C
MOVC,RB8
ANLC,/P
ORLC,F0
JCERROR
MOV@R0,A
INCR0
DJNZR7,LOOP
RET
ERROR:
…
…
RET
C语言程序:
甲乙两机都选择方式1,8位异步通信方式,甲机的控制字SCON=40H,乙机的控制字SCON=50H,选择校验方式为和校验,其他不变
甲机的发送程序:
#include
unsignedcharidatabuf[16];
unsignedcharpf;
voidmain()
{
unsignedchari,j;
SCON=0x40;
TMOD=0x20;
PCON=PCON&0x7F;
AUXR=AUXR&0xBF;
TL1=0xF4;
TH1=0xF4;
TR1=1;
pf=0;
for(i=0;i<16;i++)
{
SBUF=buf[i];
pf+=buf[i];
while(TI==0);
TI=0;
}
SBUF=pf;
while(TI==0);
TI=0;
}
while
(1);
}
已机接收程序:
#include
unsignedcharidatabuf[16];
unsignedcharpf;
voiderror();
voidmain()
{
unsignedchari,j;
SCON=0x50;
TMOD=0x20;
PCON=PCON&0x7F;
AUXR=AUXR&0xBF;
TL1=0xF4;
TH1=0xF4;
TR1=1;
pf=0;
for(i=0;i<16;i++)
{while(RI==0);
RI=0;
buf[i]=SBUF;
pf+=buf[i];
}
while(RI==0);
RI=0;
if(SBUF^pf)
error();
while
(1);
}
voiderror()
{………..}
11-4设计电路并编写程序:
使用8255A驱动2个共阳极数码管,从0开始显示,每隔1秒钟加1,直到99,反复循环。
设计电路如图习题11—4。
(此处74HC373作驱动之用,不是锁存)
汇编语言程序段:
APORTEQU0F8FFH;A口
BPORTEQU0F9FFH;B口
CONPORTEQU0FBFFH;控制字端口
AUXREQU8EH
ORG0H
LJMPMAIN
MAIN:
MOVSP,#0AFH
ORLAUXR,#00000010B
MOVA,#80H
MOVDPTR,#CONPORT
MOVX@DPTR,A
NOP
NOP
NOP
NOP
NOP
BEGIN:
MOVR0,#00H
LOOP:
MOVB,#10
MOVA,R0
DIVAB
MOVDPTR,#TAB
MOVCA,@A+DPTR
XCHA,B
MOVCA,@A+DPTR
MOVDPTR,#APORT
MOVX@DPTR,A
MOVA,B
MOVDPTR,#BPORT
MOVX@DPTR,A
INCR0
LCALLDELAY_1S
CJNER0,#100,LOOP
LJMPBEGIN
DELAY_1S:
MOVR7,#42H
DL1:
MOVR6,#0DAH
DL0:
MOVR5,#0CFH
DJNZR5,$
DJNZR6,DL0
DJNZR7,DL1
RET
TAB:
DB0C0H,0F9H,0A4H,0B0H,99H,092H,082H,0F8H,080H,090H
;TAB是0-9对应的段码值表
END
C51程序:
#include
#include
#include
#defineAPORTXBYTE[0XF8FF]
#defineBPORTXBYTE[0XF9FF]
#defineCONPORTXBYTE[0xFBFF]
unsingnedcharcodeseg[10]={0xC0,0xF9,0xA4,
0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
voiddelay_1s();
voidmain()
{
unsingedchari;
CONPORT=0x80;
while
(1)
{
for(i=0;i<100;i++)
{
APORT=seg[i/10];
BPORT=seg[i%10];
delay_1s();
}
}
}
voiddelay_1s()
{
unsingedchara,b,c;
for(c=142;c>0;c--)
for(b=168;b>0;b--)
for(a=250;a>0;a--);
}
11-8如图11-46所示,在P1.0-P1.7引脚连接8个按键,分别定义为1号、2号….8号,在P3口连接一个共阳极数码管,编写程序,使8个按键中任意一个按下时,数码管上显示对应的键序号。
汇编语言程序:
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVSP,#0AFH
MOVP1,#0FFH
NOP
NOP
NOP
LOOP:
MOVA,P1
CJNEA,#0FFH,LOOP1
SJMPLOOP
LOOP1:
LCALLDELAY_15ms
MOVA,P1
CJNEA,#0FFH,LOOP2
SJMPLOOP
LOOP2:
JNBACC.0,KEY1
JNBACC.1,KEY2
JNBACC.2,KEY3
JNBACC.3,KEY4
JNBACC.4,KEY5
JNBACC.5,KEY6
JNBACC.6,KEY7
JNBACC.7,KEY8
LJMPLOOP
KEY1:
MOVP3,#0F9H
AJMPLOOP
KEY2:
MOVP3,#0A4H
AJMPLOOP
KEY3:
MOVP3,#0B0H
AJMPLOOP
KEY4:
MOVP3,#99H
AJMPLOOP
KEY5:
MOVP3,#92H
AJMPLOOP
KEY6:
MOVP3,#82H
AJMPLOOP
KEY7:
MOVP3,#0F8H
AJMPLOOP
KEY8:
MOVP3,#80H
AJMPLOOP
DELAY_15ms:
MOVR6,#177
DL0:
MOVR5,#0
DJNZR5,$
DJNZR6,DL0
RET
END
C51程序:
#include
unsignedchartemp,temp1;
voiddelay_15ms();
voidKEY1();
……
voidKEY8();
voidmain()
{
P1=0xFF;
while
(1)
{
temp=P1;
if(temp!
=0xFF)
{
delay_15ms();
temp=P1;
if(temp!
=0xFF)
{
switch(temp)
{
case0xFE:
KEY1();break;
case0xFD:
KEY2();break;