实验四功能模块.docx
《实验四功能模块.docx》由会员分享,可在线阅读,更多相关《实验四功能模块.docx(18页珍藏版)》请在冰豆网上搜索。
实验四功能模块
实验四功能模块(定时器、中断、串口)
实验目的
通过实验掌握单片机的功能模块(定时器、中断、串口)应用。
实验基本要求
按实验内容上机输入并调试实验程序。
画出实验程序的流程框图。
实验内容1
一、定时器实验:
AT89C51单片机的实验电路如图所示,P1.0口接一个发光二极管,编写程序,控制发光二极管闪烁,时间间隔1s,要求采用AT89C51单片机的内部定时器计时,用中断方式,采用工作方式2。
Porteus模型为ExternalInterrupt.DSN如下图所示。
程序设计要求:
设置内部计数器用作定时器,是对机器周期数计数。
每个机器周期的长度是12个振荡器振荡周期。
单片机晶振用12MHz,工作方式2,即8位自动重装方式定时器,定时100微秒中断一次,通过计算,得到定时常数=156,然后对100微秒中断次数计数10000次,就是1s。
汇编语言源程序:
ORG00H
TICKEQU10000;10000×100us=1s
T100usEQU256-100;100us时间常数(12M)
C100usEQU30H;100us计数单元
LEDBUFEQU40H
LEDBITP1.0
LJMP;跳至主程序
;中断服务子程序起始地址
T0INT:
PUSHPSW;状态保护
MOVA,C100us+1
JNZGOON
DECC100us;秒计数值减1
GOON:
DECC100us+1
MOVA,C100us
ORLA,C100us+1
JNZEXIT;100us计数器不为0,返回
MOVC100us,#HIGH(TICK);100us计数器为0,重置计数器
MOVC100us+1,#LOW(TICK)
CPLLEDBUF;取反LED
EXIT:
POPPSW
中断返回
START:
;方式2,定时器
;置定时器初值
;开中断
;开始定时
CLRLEDBUF
CLRLED
MOVC100us,#HIGH(TICK);设置10000次计数值
MOVC100us+1,#LOW(TICK)
LOOP:
MOVC,LEDBUF
MOVLED,C
LJMPLOOP
END
C语言:
#include
unsignedintc100us;
bitLEDBUF=0x28^0;
sbitLED=P1^0;
voidtimer0(void)interrupt1using1
{
c100us=c100us-1;
if(c100us==0)
{
c100us=10000;
LEDBUF=!
LEDBUF;
}
}
main()
{
TMOD=0x02;
TH0=156;
TL0=156;
EA=1;
ET0=1;
TR0=1;
LED=0;
c100us=10000;
for(;;)
{
LED=LEDBUF;
}
}
二、定时/计数器T0作定时应用
用AT89C51的定时器/计数器T0产生2s的定时,每当2s定时到来时,更换指示灯闪亮,每个指示灯闪亮的时间为0.2s,也就是说,开始D1指示灯闪亮0.2s,当2s定时到来之后,D2开始闪亮0.2s,如此循环下去。
0.2s的闪亮时间也由定时/计数器T0完成。
Proteus模型为TimerApplication.DSN,如下图所示。
程序设计要求:
定时2s,采用16位定时50ms,共定时40次才可达到2s,每50ms产生一次中断,定时的40次数在中断服务程序中完成,同样,对于0.2s的定时,需要4次中断才可以达到0.2s。
由于每次2s定时完成时,D1~D4要交替闪亮。
采用ID来识别,当ID=0时,D1在闪亮;当ID=1时,D2在闪亮;当ID=2时,D3在闪亮;当ID=3时,D4在闪亮。
仔细体会在程序中对ID状态的判断,并实现轮流闪亮的编程方法。
汇编语言源程序:
COUNTEQU30H
FLASHEQU31H
ORG00H
SJMPSTART
ORG0BH;定时器0中断入口
LJMPINT_T0
START:
MOVCOUNT,#00H
MOVFLASH,#00H
;定时器工作方式1
;定时器初值
;开中断
;启动定时器
;等待中断
INT_T0:
MOVA,COUNT
CJNEA,#00H,I1;D1闪烁
CPLP1.0
INCFLASH
MOVA,FLASH
CJNEA,#40,RETUNE;达到2秒?
MOVFLASH,#00H
INCCOUNT
LJMPRETUNE;D2闪烁
I1:
CJNEA,#01H,I2
CPLP1.1
INCFLASH
MOVA,FLASH
CJNEA,#40,RETUNE;达到2秒?
MOVFLASH,#00H
INCCOUNT
LJMPRETUNE
I2:
CJNEA,#02H,I3;D3闪烁
CPLP1.2
INCFLASH
MOVA,FLASH
CJNEA,#40,RETUNE;达到2秒?
MOVFLASH,#00H
INCCOUNT
LJMPRETUNE
I3:
CJNEA,#03H,RETUNE;D4闪烁
CPLP1.3
INCFLASH
MOVA,FLASH
CJNEA,#40,RETUNE;达到2秒?
MOVFLASH,#00H
MOVCOUNT,#00H
LJMPRETUNE
RETUNE:
;恢复初值
RETI
END
C语言:
#include
charCOUNT=0x30;
charFLASH=0x31;
sbitD1=P1^0;
sbitD2=P1^1;
sbitD3=P1^2;
sbitD4=P1^3;
main()
{
COUNT=0;
FLASH=0;
TMOD=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
IE=0x82;
TR0=1;
while
(1){}
}
voidtimer0()interrupt1using0
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(COUNT==0)
{
D1=!
D1;
FLASH++;
if(FLASH!
=40)
return;
FLASH=0;
COUNT++;
}
elseif(COUNT==1)
{
D2=!
D2;
FLASH++;
if(FLASH!
=40)
return;
FLASH=0;
COUNT++;
}
elseif(COUNT==2)
{
D3=!
D3;
FLASH++;
if(FLASH!
=40)
return;
FLASH=0;
COUNT++;
}
elseif(COUNT==3)
{
D4=!
D4;
FLASH++;
if(FLASH!
=40)
return;
FLASH=0;
COUNT=0;
}
}
三、方波发生器
方波发生器采用T0工作在定时器方式1,实现周期为100ms的方波输出。
接线如下图所示。
实验模型为SquareWaveGenerator.DSN。
由虚拟示波器观察和测量P3.0,P3.1的输出波形。
程序设计要求:
计算定时器初值,用中断方式工作,初始化定时器。
在中断服务程序中实现方波输出。
ORG0000H
SJMPMAIN
ORG000BH
SJMPD_T0
ORG0030H
MAIN:
MOVTMOD,#01H
MOVP3,#0FEH
MOVTH0,#3CH
MOVTL0,#0B0H
MOVIE,#0FFH
SETBTR0
SJMP$
D_T0:
CLRTR0
CLREA
CPLP3.0
CPLP3.1
MOVTH1,#3CH
MOVTL1,#0B0H
SETBTR0
SETBEA
RETI
END
四、计数器
从AT89C51单片机的P3.4口输入外部时钟,编写程序,对外部脉冲个数进行计数,并将计数值用8位发光二极管以二进制数显示出来。
程序设计要求:
AT89C51内部定时/计数器用作计数器,外部时间计数脉冲由P3.4引入定时器T0,单片机在每个机器周期采样一次T0引脚的输入波形,如果有跳变,则计数值自动加1。
Proteus模型为CounterDesign.DSN,如下图所示。
汇编语言源程序:
ORG0000H
MOVTMOD,#00000101B;置T0计数器方式1
MOVTH0,#0;置T0初值
MOVTL0,#0
SETBTR0;T0运行
LOOP:
MOVP1,TL0;记录P1口脉冲个数
LJMPLOOP;返回
END
C语言:
#include
voidmain()
{
TMOD=0x05;
TH0=0;
TL0=0;
TR0=1;
for(;;)
{
P1=TL0;
}
}
五、外部中断
AT89C51单片机的P3.2/INT0引脚接一个开关,模拟外部中断源,编写程序,当外部中断发生时,对其作出响应(以发光二极管的亮/灭来指示)。
程序设计:
外部中断的初始化设置共有三项内容:
中断总允许即EA=“1”,外部中断允许即EXi=“1”,中断方式设置。
中断方式设置一般有两种方式,即电平方式和脉冲方式,这里采用脉冲方式,当前一次为高电平后一次为低电平时为有效中断请求。
因此高电平状态和低电平状态至少维持一个周期,中断请求信号由引脚INT0(P3.2)和INT1(P3.3)引入。
Proteus模型为ExternalInterrupt.DSN。
汇编语言源程序:
LEDBITP1.0
LEDBUFEQU30H
ORG00H
LJMPSTART
;中断入口地址
;中断处理指令
START:
CLRLEDBUF
CLRLED
;外部中断0下降沿触发
;打开外部中断允许位(EX0)
;及总中断允许位(EA)
LJMP$;等待中断
INTERRUPT:
;保护现场
CPLLEDBUF;取反LED
MOVC,LEDBUF
MOVLED,C
POPPSW;恢复现场
RETI
END
C语言:
#include
bitLEDBUF=0x28^0;
sbitLED=P1^0;
voidint0()interrupt0using1
{
LEDBUF=!
LEDBUF;
LED=LEDBUF;
}
main()
{
LEDBUF=0;
TCON=0x01;
IE=0x81;
for(;;){}
}
六、单片机双机串口通信
在程序控制下,本方拨码开关的信息,可以在对方的LED上显示。
编制软件时,使用了汇编语言,针对按键和串行通信,都采用了中断方式,这样就可以取得最快的反应速度。
在实际的硬件实验中,双方都显得十分灵敏。
两个单片机,使用同一个程序,串行口参数:
方式1,数据位——8;奇偶校验——无;停止位——1;;波特率设置9600@11.0592MHz
Proteus模型为D-SerialCommunication.DSN。
汇编语言源程序:
ORG0000H
SJMPSTART
INT0中断
UART中断
START:
MOVSP,#60H
;方式1,8-n-1
;波特率发生器设置
;波特率设置
;
;启动定时器
;P3.2下降沿触发中断
;开放中断
SJMP$
INT0_INT:
MOVP2,#0FFH
MOVA,P2;读出的拨码开关信息
;MOVP0,A;调试的时候,可在本方显示,以证明中断正常
;JBTI,$
;向串口发送
RETI
UART_INT:
;测试是否发送中断,是转_FA_进行发送中断处理
;读出串口收到的信息
MOVP0,A;送到P0口进行显示
;请接收中断标志
RETI
_FA_:
;清发送中断标志
RETI
END
七、单片机与PC机通信
AT89C51单片机的串口经MAX232电平转换后,与PC机串行口相连。
使用虚拟终端,实现上位机与下位机的通信。
Proteus模型为SerialCommunication.DSN。
程序设计:
采用查询法接收和发送数据,上位机发出指定字符,下位机收到后返回原字符,
虚拟终端设置如下:
波特率——4800;数据位——8;奇偶校验——无;停止位——1;如图所示。
汇编语言源程序:
ORG30H
START:
MOVSP,#60H
;设定串行方式:
;8位异步,允许接收
;设定计数器1为模式2
;波特率加倍
;设定波特率为4800
;计数器1开始计时
AGAIN:
;等待接收完成
;清接收标志
;接收数据送缓冲区
;发送收到的数据
;等待发送完成
;清发送标志
SJMPAGAIN
END
在菜单栏中选择“”→“”选项,打开虚拟终端窗口,在键盘上按键,在虚拟终端窗口中会显示相应的字符。
如图所示。
C语言:
#include
sfrA=0xe0;
main()
{
SP=0x60;
SCON=0x50;
TMOD=0x20;
PCON=PCON|0x80;
TH1=0x0f3;
TL1=0x0f3;
TR1=1;
while
(1)
{
while(RI==0);RI=0;
A=SBUF;
SBUF=A;
while(TI==0);TI=0;
}
}