《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx

上传人:b****4 文档编号:12244897 上传时间:2023-04-17 格式:DOCX 页数:42 大小:141.24KB
下载 相关 举报
《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx_第1页
第1页 / 共42页
《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx_第2页
第2页 / 共42页
《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx_第3页
第3页 / 共42页
《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx_第4页
第4页 / 共42页
《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx

《《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx》由会员分享,可在线阅读,更多相关《《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx(42页珍藏版)》请在冰豆网上搜索。

《单片机的C语言程序设计与运用第2版》期末复习题及答案2.docx

《单片机的C语言程序设计与运用第2版》期末复习题及答案2

第四章

中断类

例4-1P104

假设外部中断0和外部中断1均为下降沿触发,当外部中断0发生时,P0端口的电平反向,当外部中断1发生时,P1端口的电平反向。

#include

voidIS0(void)interrupt0

{P0=~P0;}//P0端口反向

voidIS1(void)interrupt2

{P1=~P1;}//P1端口反向

voidmain()

{P0=0x00;P1=0xFF;

IT0=1;IT1=1;

EX0=1;EX1=1;EA=1;

while

(1);

}

【例4-9】外部中断示例

在本实例中,首先通过P1.7口点亮发光二极管D1,然后外部输入一脉冲串,则发光二极管D1亮、暗交替。

#include

sbitP1_7=P1^7;

voidinterrupt0()interrupt0using2//外部中断0

{P1_7=!

P1_7;}

voidmain()

{EA=1;//开中断

IT0=1;//外部中断0脉冲触发

EX0=1;//外部中断0

P1_7=0;

do{}while

(1);

}

如果有3个脉冲,则灯亮、暗交替一次,可如下面编程:

#include

SbitP17=P1^7;

unsignedchari=3;

voidmain()

{EA=1;IT0=1;EX0=1;

P17=0;

do{}while

(1);}

voidinterrupt0()interrupt0

{i=i-1;

if(i==0)

{P17=!

P17;i=3;

}

}

【例4-10】如图4-18所示,8只LED阴极接至单片机P0口,两开关S0、S1分别接至单片机引脚P3.2()和P3.3()。

编写程序控制LED状态。

按下S0后,点亮8只LED;按下S1后,变为闪烁状态。

#include

sbitP32=P3^2;

voiddelay(unsignedintd)//定义延时子函数

{while(--d>0);

}

voidmain()

{P0=0xFF;//熄灭LED

IT0=1;IT1=1;//外中断0、1脉冲触发方式

EA=1;EX0=1;EX1=1;//开中断

for(;;)//延时等待中断发生

{;}

}

voidINT0_ISR()interrupt0//外中断0中断服务函数

{P0=0x00;

}

voidINT1_ISR()interrupt2//外中断1中断服务函数

{while(P32!

=0)//如果有外部中断0,则退出

{delay(5000);

P0=0x00;

delay(5000);

P0=0xFF;

}

}

定时类

【例4-16】设单片机的fosc=12MHz,要求在P1.0上产生周期为2ms的方波。

要在P1.0上产生周期为2ms的方波,定时器应产生1ms的周期性定时,定时到对P1.0取反。

要产生1ms的定时,应选择方式1,定时器方式。

TMOD的确定:

选择定时器/计数器T0,定时器方式。

方式1,GATE不起作用,高4位为0000,TMOD=01H。

TH、TL的确定:

单片机的fosc=12MHz,则单片机的机器周期为1ms,1ms=1000ms,计数器的计数初值为65536-1000,TH0=(65536-1000)/256,TL0=(65536-1000)%256。

①采用查询方式

程序如下:

#include

sbitP1_0=P1^0;

voidmain(void)

{TMOD=0x01;

TR0=1;

for(;;)

{TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

do{}while(!

TF0);

P1_0=!

P1_0;

TF0=0;

}

}

②采用中断方式

程序如下:

#include

sbitP1_0=P1^0;

voidtimer0(void)interrupt1using1

{P1_0=!

P1_0;

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

}

voidmain(void)

{TMOD=0x01;

P1_0=0;

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

EA=1;ET0=1;

TR0=1;

do{}while

(1);

}

【例4-17】设系统时钟频率为12MHz,编程实现从P1.1输出周期为1s的方波。

要输出周期为1s的方波,应产生500ms的周期性定时,定时到则对P1.1取反即可实现。

由于定时时间较长,一个定时器/计数器不能直接实现,一个定时器/计数器最长定时时间为65ms多一点,可以用以下两种方法实现。

(1)方法一

用定时/计数器T0产生周期性为10ms的定时,然后用一个变量对10ms计数50次。

系统时钟为12MHz,定时/计数器T0定时10ms,计数值N为10000,选方式1,方式控制字为00000001B(01H),则初值X为X=65536-10000。

#include

sbitP1_1=P1^1;

unsignedchari;//定义计数变量

voidmain()

{i=0;//初始化

TMOD=0x01;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

EA=1;

ET0=1;

TR0=1;

while

(1);

}

voidtime0_int(void)interrupt1//中断服务程序

{TH0=(65536-10000)/256;//重载初始值

TL0=(65536-10000)%256;//重载初始值

i++;//每发生一次中断,计数变量加1

if(i==50)//发生50次中断,定时0.5ms

{P1_1=!

P1_1;

i=0;//计数变量清零

}

}

(2)方法二

用定时/计数器T1计数实现,对10ms计数50次。

定时/计数器T1工作于计数方式时,计数脉冲通过T1(P3.5)输入。

设定时/计数器T0定时时间到对P1.0取反一次,则T1(P3.5)每10ms产生一个计数脉冲,那么定时500ms只需计数25次,设定时/计数器T1工作于方式2,初值X=256-25=231,TH1=TL1=231。

因为定时/计数器T0工作于方式1,定时方式,则这时方式控制字为01100001B(61H)。

定时/计数器T0和T1都采用中断方式工作。

#include

sbitP1_1=P1^1;

sbitP1_0=P1^0;

voidmain()

{TMOD=0x61;//初始化

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

TH1=231;TL1=231;

EA=1;

ET0=1;ET1=1;

TR0=1;TR1=1;

while

(1);

}

voidtime0_int(void)interrupt1//T0中断服务程序

{TH0=(65536-10000)/256;//重载初始值

TL0=(65536-10000)%256;//重载初始值

P1_0=!

P1_0;

}

voidtime1_int(void)interrupt3//T1中断服务程序

{P1_1=!

P1_1;}

【例4-18】设系统时钟频率为12MHz,编程实现:

P1.1引脚上输出周期为1s,占空比为20%的脉冲信号

根据输出要求,脉冲信号在一个周期内高电平占0.2s,低电平占0.8s,超出了定时器的最大定时间隔,因此利用定时器0产生一个基准定时配合软件计数来实现。

取50ms作为基准定时,采用工作方式1,这样这个周期需要20个基准定时,其中高电平占4个基准定时。

#include

sbitP1_1=P1^1;

unsignedchari;//定义计数变量

voidmain()

{i=0;//初始化

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

EA=1;ET0=1;

TR0=1;

while

(1);

}

voidtime0_int(void)interrupt1//中断服务程序

{TH0=(65536-50000)/256;//重载初始值

TL0=(65536-50000)%256;

i=i+1;

if(i==4)P1_1=0;//高电平时间到变低

elseif(i==20)//周期时间到变高

{P1_1=1;

i=0;//计数变量清零

}

}

第五章

【例5-9】串行口自发自收

#include

#defineucharunsignedchar

#defineuintunsignedint

voidmain()

{uchari=0x55;

uintj=0;

TMOD=0X20;//设定定时器1模式2

TL1=TH1=0XF4;

PCON=0X00;

SCON=0X50;

TR1=1;

while

(1)

{SBUF=i;//发送数据

do()while(!

RI)

RI=0;

TI=0;

i=SBUF;//读取接收数据

P1=i;

i=~i;//将发送数据取反

for(j=0;j<12500;j++);

}

}

【例5-10】两个单片机串行通信1

单片机1的C51源程序代码:

#include

#defineuintunsignedint

#defineucharunsignedchar

voidmain()

{uchari;

TMOD=0x20;TH1=TL1=0xff;

SCON=0x50;PCON=0x80;

TR1=1;

P1=0xff;

while

(1)

{P1=0xff;

i=P1;SBUF=i;

while(TI==0)

{;}

TI=0;

}

}

单片机2的C51源程序:

#include

#defineuintunsignedint

#defineucharunsignedchar

voidmain()

{uchari=0;

TMOD=0x20;TH1=TL1=0xff;

SCON=0x50;PCON=0x80;

TR1=1;

while

(1)

{while(RI==0){;}

RI=0;

i=SBUF;

P1=i;

}

}

两个单片机串行通信2

C51源程序代码如下:

#include

#defineucharunsignedchar

#defineTR1//TR=1,发送

ucharidatabuf[10];

ucharpf;

voidmain()

{int();//串行口初始化子函数

if(TR==0)

{send(buf);}//发送

else

{receive(buf);}//接收

}

/*串口初始化子函数*/

voidinit(void)

{TMOD=0x20;//T1工作于方式2

TH0=0xE8;

TL0=0xE8;

TR1=1;

SCON=0X50;//串行口工作于方式1,REN=1

}

/*发送子函数*/

voidsend(ucharidata*d)

{uchari;

do

{SBUF=0xAA;//发送联络信号

while(TI==0);//等待一帧发送完毕

TI=0;//发送完毕,标志位清0

while(RI==0);//等待乙机应答信号

RI=0;

}while(SBUF^0xBB!

=0);//乙机未准备好,继续联络

do

{pf=0;//校验和变量清0

for(i=0;i<10;i++){

SBUF=d[i];//发送一个数据

pf+=d[i];//计算校验和

while(TI==0);

TI=0;}

SBUF=pf;//发送校验和

while(TI==0);TI=0;

while(RI==0);RI=0;//等待乙机应答

}while(SBUF!

=0);//回答出错,则重新发送

}

/*接收函数*/

voidreceive(ucharidata*d)

{uchari;

do

{while(RI==0);RI=0;

}while(SBUF^0xAA)!

=0);//判断甲机是否请求

SBUF=0xBB;//发应答信号

while(TI==0);TI=0;

while

(1){

pf=0;//清校验和

for(i=0;i<10;i++){

d[i]=SBUF;//接收数据

pf+=d[i];}//计算校验和

while(RI==0);RI=0;//接收甲校验和

If((SBUF^pf)==0){//比较校验和

SBUF=0x00;break;}//校验和相等,发0x00

else{

SBUF=0xFF;//校验和不相等,发0Xff

while(TI==0);TI=0;

}

}

}

第六章

静态:

【例6-1】利用单片机的并行口作为静态显示的输出口的示例

静态轮流显示“12”、“--”和“AB”的C51源程序如下:

#include

#defineucharunsignedchar

uchardatadis_buf[2];//显示缓冲区

ucharcodeable[18]=

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};//显示的代码表

voiddl()

{unsignedinti;

for(i=0;i<40000;i++);

}

voiddisplay(void)//显示函数

{ucharsegcode;

segcode=dis_buf[0];//P0口显示

segcode=table[segcode];

P0=segcode;

segcode=dis_buf[1];//P3口显示

segcode=table[segcode];

P3=segcode;

}

voidmain(void)//主函数

{while

(1)

{dis_buf[0]=1;dis_buf[1]=2;//显示12

display();dl();

dis_buf[0]=16;dis_buf[1]=16;//显示--

display();dl();

dis_buf[0]=10;dis_buf[1]=11;//显示AB

display();dl();

}

}

示例中的显示函数display()可以再简单一些,如下面程序段:

voiddisplay(void)

{P0=table[dis_buf[0]];//P0口显示

P3=table[dis_buf[1]];//P3口显示

}

动态:

【例6-3】利用MCS-51单片机的并行口作为动态显示的段口与位口的示例

6位数码管动态显示“123456”的C51源程序如下

1)随机调用

#include

#defineucharunsignedchar

uchardatadis_buf[6];//显示缓冲区

ucharcodetable[18]=

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};//代码表

voiddl_ms()//延时1ms函数

{unsignedintj;

for(j=0;j<200;j++);

}

voiddisplay(void)//显示函数

{ucharsegcode,bitcode,i;

bitcode=0xfe;//位码赋初值

for(i=0;i<6;i++)

{segcode=dis_buf[i];//显示缓冲器内容查表

P0=table[segcode];P3=bitcode;dl_ms();

P3=0xff;//关闭显示

bitcode=bitcode<<1;//调整位码

bitcode=bitcode|0x01;

}

}

voidmain(void)

{dis_buf[0]=1;dis_buf[1]=2;

dis_buf[2]=3;dis_buf[3]=4;

dis_buf[4]=5;dis_buf[5]=6;

while

(1)

{display();

}

}

(2)定时调用

定时调用是通过定时器/计数器的定时功能来定时一定的时间(如20ms),定时时间到来调用显示函数。

voidmain(void)//定时调用

{TMOD=0x01;

TH0=-20000/256;TL0=-2000%256;

EA=1;ET0=1;

TR0=1;

dis_buf[0]=1;dis_buf[1]=2;dis_buf[2]=3;

voidtime0_int()interrupt1

{TH0=-20000/256;

TL0=-2000%256;

display();

}

dis_buf[3]=4;dis_buf[4]=5;dis_buf[5]=6;

while

(1);

}

【例6-6】独立式按键示例

C51源程序如下:

#include

#defineucharunsignedchar

#defineuintunsignedint

uchardatakey2;

codeuchardirtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};

voiddl_6()

{uinti;

for(i=0;i<600;i++);

}

voidkey()

{ucharkey1;

P1=0xff;

key1=P1;

if(key1!

=0xff)

{dl_6();P1=0xff;key1=P1;

if(key1!

=0xff)

{key1=P1;

switch(key1)

{case0xff:

key2=8;break;

case0xfe:

key2=0;break;

case0xfd:

key2=1;break;

case0xfb:

key2=2;break;

case0xf7:

key2=3;break;

case0xef:

key2=4;break;

case0xdf:

key2=5;break;

case0xbf:

key2=6;break;

case0x7f:

key2=7;break;

default:

break;

}

}

}

}

voidmain()

{

key2=8;

while

(1)

{

key();

P3=dirtab[key2];

}

}

【例6-7】4×4矩阵键盘示例

#include

#defineucharunsignedchar

#defineuintunsignedint

uchardatadir_buf;

codeuchardirtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};

codeucharkeytab[]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,

0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77};

voiddelay(void);

voidkeyscan();

voiddir();

ucharkey;

voidmain(void)

{dir_buf=16;

while

(1)

{keyscan();

dir();

}

}

voiddir()

{P2=dirtab[dir_buf];}

voiddelay(void)

{uchari;

for(i=0;i<200;i++);

}

voidkeyscan()

{ucharcode_h,code_l,i1,i2;

P1=0xf0;//所有的行输出0

code_l=P1;//读列值

code_l=code_l&0xf0;//屏蔽掉高4位

if(code_l!

=0xf0)

{delay();

//P1=0xf0;

code_l=P1;

code_l=code_l&0xf0;

if(code_l!

=0xf0)

{code_h=0xfe;

for(i1=0;i1<4;i1++)

{kk:

P1=code_h;

code_l=P1;

code_l=code_l&0xf0;

if(code_l==0xf0)

{code_h=(code_h<<1)|0x01;gotokk;

}

gotoll;

}//for

}

ll:

code_h=code_h&0x0f;

key=code_h+code_l;

for(i2=0;i2<16

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 研究生入学考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1