第6章单片机的定时计数器_第1页
第6章单片机的定时计数器_第2页
第6章单片机的定时计数器_第3页
第6章单片机的定时计数器_第4页
第6章单片机的定时计数器_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第6 6章章 单片机的定时单片机的定时/ /计数器计数器 MCS-51单片机内部有两个16位的可编程的定时器/计数器,即定时器T0和定时器T1(8052提供3个,第3个称为定时器T2)。它们既可用做定时器方式,又可用做计数器方式。6.1 6.1 定时定时/ /计数器的基本知识计数器的基本知识6.1.1 6.1.1 定时定时/ /计数器的结构计数器的结构 定时器/计数器的基本结构如图6-1所示,基本的部件是两个8位的计数器(其中TH1和TL1是T1的计数器,TH0和TL0是T0的计数器)。1讲 在作为定时器使用时,是对单片机内部机器周期的计数,因其内部频率为晶振频率的 1/12,如果晶振频率1

2、2MHz,则定时器每接收一个输入脉冲的时间为1s。 当它用做对外部事件计数时,接相应的外部输入引脚T0(P3.4)或T1(P3.5)。在这种情况下,当检测到输入引脚上的电平由高跳变到低时,计数器就加1。图图6-1 定时定时/计数器的基本结构计数器的基本结构6.1.2 6.1.2 有关的控制寄存器有关的控制寄存器 与定时/计数器应用有关的控制寄存器有3个。 1.定时器控制寄存器(TCON) TCON寄存器既参与中断控制又参与定时控制。有关中断的控制内容已在第5章介绍了,现在只介绍和定时/计数器有关的控制位。与定时/计数器有关的控制位共有4位。1) TF0和TF1:定时/计数器溢出标志位 当计数器

3、计数溢出(计满)时,该位置1。使用査询方式时,此位作为状态位供查询,但应注意查询有效后,需用软件方法及时将该位清零;使用中断方式时,此位作为中断标志位,在转向中断服务程序时由硬件自动清零。2) TR0和TR1:定时器运行控制位 TR0(TR1)=0:停止定时/计数器工作。 TR0(TR1)=1:启动定时/计数器工作。 该位根据需要以软件方法使其置1或清零。2. 工作方式控制寄存器(TMOD) TMOD寄存器是一个专用寄存器,用于设定两个定时/计数器的工作方式,但TMOD寄存器不能位寻址,只能用字节传送指令设置其内容。格式如图6-2所示。1) GATE:门控位 GATE=0:由运行控制位TR启动

4、定时器。 GATE=1:由外中断请求信号( 和 )和TR的组合状态启动定时器。2) :定时方式或计数方式选择位 =0:定时器工作方式。 =1:计数器工作方式。3) M1M0:工作方式选择位 M1M0=00:方式0,13位定时/计数器工作方式, M1M0=01:方式1,16位定时/计数器工作方式。 M1M0=10:方式2,常数自动装入的8位定时/计数器工作方式。 M1M0=11:方式3,仅适用于T0,为两个8位定时/计数器工作方式,在方式3时T1 停止计数。 3. 中断允许控制寄存器(IE) IE寄存器的详细内容在第5章已介绍,这里只就与定时/计数器有关的位介绍如下。 EA:中断允许总控制位。

5、ET0和ET1:定时/计数器中断允许控制位。 ET0 (ET1)=0,禁止定时器/计数器中断; ET0 (ET1)=1,允许定时器/计数器中断。TCTCTC0INT1INT6.1.3 6.1.3 工作方式工作方式 MCS-51单片机的定时/计数器共有4种工作方式,在C51语言程序设计中,方式1和方式2用得比较多。 1. 方式0 方式0是13位计数结构的工作方式,其计数器由TH0的全部8位和TL0的低5位构成,TL0的高3位不用。不管是哪种工作方式,当TL0的低5位计数溢出时,向TH0进位,而全部13位计数溢出时,则向计数溢出标志位TF0进位。计数范围和定时范围如下: 1) 当定时器/计数器在方

6、式1下作计数器计数器用时,其计数范围是18192 (2 ) 2) 当定时器/计数器在方式1下作定时器定时器用时,其定时时间计算公式为: T =(2 -X)T 12式中,T 为定时时间,X为计数初值,T 为晶振周期。13ddosc13osc 2. 方式1(重点分析) 方式1是16位计数结构的工作方式,计数器由TH0的全部8位和TL0的全部8位构成, 其逻辑电路和工作情况与方式0完全相同,所不同的只是组成计数器的位数。方式1的逻辑电路如图6-3所示。中断0TCTR0TF0TH0(8位)TL0(8位)振荡器12GATEM1M0TMODT0 TCON11&控制INT01TCTC10 图图6-3

7、 方式方式1的逻辑电路图的逻辑电路图MSC-51单片机之所以重复设置完全一样的方式0和方式1,是出于与MCS-48单片机兼容考虑,所以对于方式1无须多加讨论,下面仅将其计数范围和定时范围列出, 1) 当定时器/计数器在方式1下做计数器用时,其计数范围是165536 (2 )。 2) 当定时器/计数器在方式1下做定时器用时,其定时时间计算公式为: T =(2 -X)T 12 式中,T 为定时时间,X为计数初值,T 为晶振周期。 1616ddoscosc 3. 方式2工作方式0和工作方式1的特点是计数溢出后,计数回0,而不能自动重装初值。因此,循环定时或循环计数应用时就存在反复设置计数初值的问题,

8、这不但影响定时精度,而且也给程序设计带来麻烦。方式2就是针对此问题而设置的,它具有自动重装计数初值的功能。在这种工作方式下,把16位计数分为两部分即以TL作为计数器,以TH作为预置计数器, 初始化时把计数初值分别装入TL和TH中。当计数溢出时,由预置计数器自动给计数器Tl重新装初值。这不但省去了用户程序中重装指令,而且也有利于提高定时精度。但这种方式是8位计数结构,计数值有限,最大只能到256。 计数范围是1256 (2 ), 定时时间计算公式为T =(2 -X)T 12式中,T 定时时间,X为计数初值, T 为晶振周期。方式2的逻辑电路如图6-4所示。88ddoscosc 这种自动重装工作方

9、式非常适应于循环定时或循环计数应用,例如: 1)用于产生固定脉宽的脉冲 2)用做串行数据通信的波特率发生器.图图6-4 方式方式2的逻辑电路图的逻辑电路图4. 方式3 前3种工作方式,对两个定时/计数器的设置和使用是完全相同的,但是在工作方式3 下,两个定时/计数器的设置和使用却是不同的,因此要分开介绍。 1) 工作方式3下的T0(定时/计数器0) 在工作方式3下,定时/计数器T0被拆成两个独立的8位TL0和TH0。其中,TL0既可以用做计数,又可以用做定时,定时/计数器T0的各控制位和引脚信号全归它使用,其功能和操作与方式0和方式1完全相同,而且逻辑电路结构也极其类似。 定时/计数器T0的高

10、8位TH0,只能作为简单的定时器使用。由于定时/计数器T0的控制位已被TL0占用,因此只好借用定时/计数器T1的控制位TR1和TF1,即以计数溢出置位TF1,而定时的启动和停止则由TR1的状态控制, 由于TL0既能作为定时器使用又能作为计数器使用,而TH0只能作为定时器使用。因此在工作方式3下,定时/计数器T0构成两个定时器或一个定时器一个计数器。 2)在定时/计数器T0设置为工作方式3时的定时/计数器T1 这里只讨论定时/计数器0工作方式3时定时/计数器1的使用情况。因为定时/计数器0工作在方式3时已借用了定时/计数器1的运行控制位TR1和计数溢出标志位TF1,所以定时/计数器1不能工作于方

11、式3,只能工作于方式0、方式1或方式2。 且在定时/计数器0已工作于方式3时,定时/计数器1通常用做串行口的波特率发生器,以确定串行通信的速率。因为已没有计数溢出标志位TF1可供使用,因此只能把计数溢出直接送给串行口。 当作为波特率发生器使用时,只需设置好工作方式,便可自动运行。如要停止工作,只需送入一个把它设置为方式3的方式控制字就可以了。6.1.4 6.1.4 初始化初始化1. 初始化步骤 在使用8051单片机的定时/计数器前,应对它进行初始化编程,主要是对TCON和TMOD寄存器编程,还需要计算和装载T/C的计数初值,一般应完成以下几个步骤:1) 确定T/C的工作方式编程TMOD寄存器;

12、2) 计算T/C中的计数初值,并装载到TH和TL;3) T/C在中断方式工作时,需开CPU中断和源中断编程IE寄存器;4) 启动T/C编程TCON中的TR1或TR0位。 2. 计数初值的计算 在计数模式,工作方式下对应的最大计数值如下。方式1:16位计数器的最大计数值为2 =65536。方式2:8位计数器的最大计数值为2 =256。在用C语言编写程序时,计数器工作于方式1情况下,可按下式装载计数寄存器初始值: TH=X/256 TL=X%256 (说明:X代表计数初值)计数器工作于方式2情况下,可按下式装载计数寄存器初始值: TH=TL=X说明:N=MAX-X (计数值=最大计数值-计数初值)

13、N代表计数值,MAX代表最大计数值,X代表计数初值816【例【例6-16-1】定时器/计数器0工作于计数方式,且允许中断,计数值N=100,分别令其工作在方式1和方式2,用C语言进行初始化编程。 (详细介绍) 方式1编程: 首先,定时器/计数器0工作于计数方式,则 =1,GATE=0。计数器0工作于方式1, 所以M1M0=01。计数器1不用,TMOD的高4位取0000,则TMOD=05H。 计数寄存器为16位,因此计数寄存器初值分别为: TH0=(65536-100)/256, TL0=(65536-100)%256 初始化程序如下: TMOD=0 x05; /设置计数器工作方式 TH0=(6

14、5536-100)/256; /计数器高8位TH0赋初值 TL0=(65536-100)%256 /计数器低8位TL0赋初值 TR0=1; /启动计数器 ET0=1; /开计数器中断 EA=1; /CPU开中断TC方式2编程: 计数器0工作于方式2,所以M1M0=10。计数器1不用,TMOD的高4位取0,则TMOD=06H。、 方式2为8位初值自动重载方式,计数寄存器初值分别为:TH0=TL0=256-100。 初始化程序如下: TMOD=0 x06; TH0=156; TL0=156;其余语句与前面相同。 在定时器工作方式下,T/C是对机器周期脉冲计数的,如果单片机外接晶振频率为f =12M

15、Hz,那么一个机器周期为T =12/f =1s,则: 方式1:16位定时器的最大定时间隔为2 =65536s。 方式2:8位定时器的最大定时间隔为2 =256s。 如果定时器计数初值为X,机器周期为T ,定时器定时时间为T ,则T =(2 -X)T , 那么定时器的初值为:X=2 - T / T ,计算得到定时器计数寄存器的初始值X,就可根据定时器的工作方式装载TH和Tl,编程方法类似于计数器方式。168cycydnoscosccycyddn【例例6-26-2】单片机外接晶振频率f =12MHz,定时器/计数器0工作于定时方式,且允许中断,定时时间为20ms,令其工作在方式1。用C语言进行初始

16、化编程。定时器/计数器0工作于定时方式:从而 =0,GATE=0。定时器0工作于方式1,所以 M1M0=01。定时器1不用,TMOD=00000001=01H。计数寄存器为16位,因此定时器的计数初值为:X=(65536-20000)/1。 计数寄存器初值分别为:TH0=(65536-20000)/256,TL0=(65536-20000)%256因此初始化程序如下:TMOD=0 x01; /设置定时器工作方式TH0=(65536-20000)/256; /定时/计数器T0的高8位TH0赋初值 TL0=(65536-20000)%256; /定时/计数器T0的低8位TL0赋初值 TR0=1;

17、/启动计数器 ET0=1; /开计数器中 EA=1;oscTC6.2 6.2 定时定时/ /计数器的编程及应用实例计数器的编程及应用实例【例【例6-36-3】设系统时钟频率为12MHz,用定时/计数器T0编程实现从P1.0输出周期为500s的方波。 分析:从P1.0输出周期为500s的方波,只需P1.0每250s取反一次则可。当系统时钟为12MHz,定时/计数器T0工作于方式2时,最大的定时时间为256s,(也可以取方式2), 满足250s的定时要求,方式控制字应设定为00000010B (02H)。系统时钟为12MHz,定时250s,计数值N为 250,初值X=256-250=6, 则TH0

18、=TL0=06H。 认真分析对比:中断和查询的特点 #includesbit P1_0=P10;void main( ) TMOD=0 x02;/初始化 THO=0 x06; TL0=0 x06; EA=1; ET0=1; TR0=1; while(1);/等待中断发生void time0_int(void) interrupt 1/中断服务程序 P1_0=!P1_0; #inclidesbit P1_0=P10;void main() unsigned char i;TMOD=0 x02;/初始化THO=0 x06;TL0=0 x06;TR0=1;for(;) if(TF0) TF0=0;P

19、1_0=!P1_0; 【例【例6-4】设单片机的f =12MHz,要求在P1.0上产生周期为2ms的方波。 要在P1.0上产生周期为2ms的方波,定时器应产生1ms的周期性定时,定时到对P1.0取反。 要产生1ms的定时,应选择方式1,定时器方式。 TMOD的确定:选择定时器/计数器T0,定时器方式。方式1,GATE不起作用,高4 位为0000,TMOD=01H。TH、TL的确定:单片机的f =12MHz,则单片机的机器周期为1s,1ms=1000s,计数器的计数初值为 65536-1000,TH0=(65536-1000)/ 256,TL0=(65536-1000)% 256。oscosc

20、程序如下: #include sbit P1_0=P10; void main(void) TMOD=0 x01; TR0=1; for(;) TH0=(65536-1000)/ 256; TL0=(65536-1000)% 256; do while(!TF0); P1_0=!P1_0; TF0=0; 程序如下:#includesbit P1_0=P10;void timer0(void) interrupt 1 using 1P1_0=!P1_0;TH0=(65536-1000)/ 256; TL0=(65536-1000)% 256; void main(void) TMOD=0 x01

21、; P1_0=0; TH0=(65536-1000)/ 256; TL0=(65536-1000)% 256; EA=1; ET0=1; TR0=1; do while(1); 由于计数器向上计数,为得到1000个计数之后的定时器溢出,必须给定时器赋初值 65536-1000,C语言中相当于-1000。 1) 用定时器0的方式1编程,釆用查询方式 程序如下:#includesbit P1_0=P10;void timerlover(void);void main(void) TMOD=0 x01; TH0=(65536-1000)/256; TL0=(65536-1000)%256; TR0=

22、1; for(;) if(TF0) timerlover( ); void timerlover(void) TH0=(65536-1000)/256;TL0=(65536-1000)%256;TF0=0;P1_0=!P1_0; 2) 采用中断方式程序如下:#includesbit P1_0=P10;void timer0(void) interrupt 1 using 1 P1_0=!P1_0; TH0=(65536-1000)/256; TL0=(65536-1000)%256; TF0=0; void main(void) TMOD=0 x01; P1_0=0; TH0=(65536-1

23、000)/256; TL0=(65536-1000)%256; EA=1; ET0=1; TR0=1; for(;) ; 例例6-56-5 设系统时钟频率为12MHz,编程实现从P1.1输出周期为1s的方波。 要输出周期为1s的方波,应产生500ms的周期性定时,定时到则对P1.1取反即可实现。由于定时时间较长,一个定时/计数器不能直接实现,一个定时/计数器最长定时时间为65ms多一点,可以用以下两种方法实现。 用定时/计数器T0产生周期性为10ms的定时,然后用一个变量对10ms计数50次。系统时钟为12MHz,则定时/计数器T0定时10ms,计数值N为10000,选工作方式1,方式控制字为

24、0000001B (01H),则初值X为X=65536-10000。程序代码如下:2讲#includesbit P1_1=P11;unsigned char i;/定义计数变量void main( )i=0;TMOD=0 x01;/初始化TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=1;while(1);void time0_int(void) interrupt 1/中断服务程序TH0=(65536-10000)/256;/重载初始值TL0=(65536-10000)%256;/重载初始值i+;/每发生一次中断,计数变量

25、加1if(i=50)/发生50次中断,定时500msP1_1=!P1_1;i=0;/计数变量清零 用定时/计数器T1实现,对10ms计数50次。定时/计数器T1工作于计数方式时,计数脉冲通过T1 (P3.5)输入。设定时/计数器T0定时时间到对P1.0取反一次,则T1 (P3.5) 每10ms产生一个计数脉冲,那么定时500ms只需计数50次,设定时/计数器T1工作于方式 2,初值X=256-50=206, TH1=TL1=206。因为定时/计数器T0工作于方式1,T0工作于定时方式,则这时方式控制字为01100001B(61H)。定时/计数器T0和T1都釆用中断方式工作。程序代码如下:#in

26、cludesbit P1_1=P11;sbit P1_0=P10;void main( )TMOD=0 x61; /初始化TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=206;TL1=206;EA=1;ET0=1; ET1=1;TR0=1; TR1=1;while(1);void time0_int(void) interrupt 1 /T0中断服务程序TH0=(65536-10000)/256;/重载初始值TL0=(65536-10000)%256;/重载初始值P1_0=!P1_0;void time1_int(void) interrupt

27、 3 /T1中断服务程序P1_1=!P1_1;【例【例6-6】设系统时钟频率为12MHz,编程实现:P1.1引脚上输出周期为1s,占空比为20%的脉冲信号。 根据输出要求,脉冲信号在一个周期内高电平占0.2s,低电平占0.8s,超出了定时器的最大定时间隔,因此利用定时器T0产生一个基准定时配合软件计数来实现。取50ms作为基准定时,采用工作方式1,这样这个周期需要20个基准定时:其中高电平占4个基准定时。 #include sbit P1_1=P11; unsigned char i;/定义计数变量 void main( ) i=0;/初始化TMOD=0 x01;TH0=(65536-5000

28、0)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;while(1); void time0_int(void) interrupt 1 /中断服务程序TH0=(65536-50000)/256;/重载初始值TL0=(65536-50000)%256;/重载初始值i=i+1;if(i=4) /高电平时间到变低 P1_1=0;else if(i=20)/周期时间到变高 P1_1=1; i=0; /计数变量清零【例【例6-7】采用10MHz晶振,在P1.0脚上输出周期为 2.5s,占空比为20%的脉冲信号。对于10MHz晶振,使用定时器最大定时为几十毫秒 (

29、ms)。取10ms定时,则周期2.5s需250次,占空比为20%, 高电平应为50次中断。10ms定时,晶振定时,晶振f=10MHz。Tcy=12/f=12/10MHZ=1.2s 需定时计数次数需定时计数次数X=10ms/Tcy=10000/1.2=8333 中断服务程序流程如图6-5所示。#include#define uchar unsigned charuchar time;sbit P1_0=P10; uchar period=250; uchar high=50;time0( ) interrupt 1 using 1 /中断服务程序TH0=(65536-8333)/256;/重载计

30、数值TL0=(65536-8333)%256;if(+time=high)/高电平时间到变低 P1_0=0;else if(time=period) /周期时间到变高 time=0; P1_0=1;3void main( )TMOD=0 x01;/定时器0方式1TH0=(65536-8333)/256;/预置计数值TL0=(65536-8333)%256;EA=1;/开CPU中断ET0=1;/开T0中断TR0=1;/启动T0dowhile(1);图图6-5 中断程序流程图中断程序流程图例例6-86-8 编程实现:利用定时/计数器T0对输入到P3.4引脚上的脉冲进行釆样计数。由于计数寄存器字节长

31、度所限,且用硬件寄存器最多只能计数65536个脉冲,为解决这一问题可加软件计数来实现。程序代码如下:#includeunsigned long i;/定义软件计数变量unsigned char count_low;/定义计数变量,用来读取TL0的值unsigned char count_high;/定义计数变量,用来读取TH0的值void read_counter( );/声明读计数寄存器子函数void main( ) i=0;/初始化TMOD=0 x05;/T0设置为计数器模式,方式1TH0=0;TL0=0;EA=1;ET0=1;TR0=1;while(1) read_counter( );

32、/循环读取、处理计数寄存器内容void read_counter( )/读取计数寄存器内容do count_high=TH0;/读高字节 count_low=TL0;/读低字节 . . ./计数值处理语句while(count_high!=TH0); /*在读取计数寄存器内容时要特别注意,因为单片机不能在同一时刻读取TH1和TL1的内容,因而如果只读取一次可能会出错。比如:先读TL,再读TH,可能会由于此时恰好产生TL溢出向TH进位的情況而出错;同样,先读TH后读TL也可能出现类似的错误。因此,需要采用上面程序中给出的读取顺序:先读TH,再读TL,然后再读TH。若两次读取的TH内容一致,则读取

33、正确,否则就是不正确,需要再次重复上次读取过程直到正确读取为止*/void time0_int(void) interrupt 1i=i+1;TH0=0;TL0=0;TR0=1; /*中断服务程序:当计数寄存器溢出进入;当计数寄存器溢出;软件计数变量加1;此变量中的1相当于收到65536个脉冲信号*/ 【例【例6-96-9】利用定时器的门控位GATE测量正脉冲宽度,脉冲从/INT1(P3.3)引脚输入。门控位GATE=1,定时/计数器T1的启动受到外中断1引脚/INT1的控制,当GATE=1,TR1=1时,只有/INT1引脚为高电平时,T1才被允许计数(定时/计数器T0具有同样特性),利用GA

34、TE的这个功能,可以测量/INT1引脚(P3.3)上正脉冲的宽度(机器周期数),其方法图6-6所示。 程序代码如下:#includesbit P3_3=P33;/定义位变量unsigned count_low;/定义计数变量,用来读取TL1值unsigned count_high;/定义计数变量,用来读取TH1值void read_counter();/声明读计数寄存器子函数void main()TMOD=0 x90;/T1设置为定时器模式,工作方式1TH1=0;TL1=0;TR1=1;while(P3_3=1); /等待INT1变低TR1=1;/如果INT1为低,启动T1(未真正开始计数)w

35、hile(P3_3=0); /等待INT1变高,变高后T1真正开始计数while(P3_3=1); /等待INT1变低,变低后T1实际上停止计数TR1=0;/停止T1read_counter( );/读取、处理计数寄存器void read_counter( ) /读取计数寄存器内容docount_high=TH1; /读高字节count_low=TL1; /读低字节. . . /计数值处理语句while(count_high!=TH1);【例【例6-106-10】设P1口的P1.0、P1.1上有2个开关S1和S2 ,周期开始时,它们全关。2s以后S1开,0.1s后S2开;S1保持开2.4s,周

36、而复始。釆用10MHz晶振。解:根据要求P1.0,P1.1上开关顺序如图6-7所示。采用10MHz晶振,每10ms中断一次,0.1s对应10次,幵关变化对应的中断次数位置为:0、200、 210、 400、 450。相应的P1.1 P1.0输出分别为:00、01、11、10、00。 #include#define uchar unsigned char #define uint unsigned intsbit P1_0=P10;sbit P1_1=P11;uchar i;uint time;void timer0( ) interrupt 1 using 1 /*item1*/TH0=(65

37、536-8333)/256;TL0=(65536-8333)%256;time+;/*item2*/switch(time)case 200:P1_1=0;P1_0=1; break;case 210:P1_1=1;P1_0=1; break;case 400:P1_1=1;P1_0=0; break;case 450:P1_1=0;P1_0=0; break;void main( )P1=0;time=0;/*item3*/i=1;TMOD=0 x01;TH0=(65536-8333)/256;TL0=(65536-8333)%256;TR0=1;ET0=1;EA=1;for(;) 其中,i

38、tem1为中断服务程序,每10ms中断一次,重载定时器初值;item2为记录中断发生的次数;item3为初始化变量和定时器。【例6-11】 以下是一个产生占空比变化的脉冲信号的程序。它产生的脉宽调制信号可用于电机变速控制。#include#define uchar unsigned char #define uint unsigned intuchar time,staus,percent,period;bit one_round;uint oldcount,target=500;void pluse(void) interrupt 1 using 1 TH0=(65536-833)/256;

39、/*1ms(1000Hz)*/TL0=(65536-833)%256;ET0=1;if(+time=percent)P1=0;else if(time=100)time=0;P1=1; void tachmeter(void) interrupt 2 using 2 unionuint word;struct uchar hi; uchar lo;byte;newcount;newcount.byte.hi=TH1;newcount.byte.lo=TL1;period=newcount.word-oldcount;/*测得的周期*/oldcount=newcount.word;one_rou

40、nd=1;/*转一圈,引起中断,设置标志*/void mian(void)IP=0 x04;/置INT1为高优先级TMOD=0 x11;/T0设置为16位方式TCON=0 x54;/T0运行,IT1边沿触发TH0=0;TL0=0;/设置初始计数值IE=0 x86;/允许终端EX1,ET0for(;)if(one_round)/每转一圈,调整if(percent0)-percent;/占空比减one_round=0;【例【例6-12】通过定时器的定时产生一定频率的波形信号,经P1.0输出,驱动扬声器, 即发出一定频率的声调。将乐曲的声调连续发出,使其按照节拍变化即可演奏一首乐曲。 电路图如图6-

41、8所示。C51语言程序如下:#include#define uchar unsigned char#define uint unsigned int sbit P1_0=P10;uint m,i;uint rti;uint l;/音频表:高位、低位uchar code toneh14=0 xfe,0 xfe,0 xfe,0 xfe,0 xfe,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff;uchar code tonel14=0 x22,0 x56,0 x85,0 x9a,0 xc1,0 xe3,0 x03,0 x10,0 x2b,0 x42,0 x4c,0 x60,0 x71,0 x81; /乐谱uchar code song=123112313455345556543256543215111511;uchar code length=444444444444444422224422224422224444444444;void timer0(void) interrupt 1 using 1 P1_0=!P1_0;/P1.0取反TH0=tonehrti;/装入音频初值T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论