频率是周期的倒数
51单片机定时器中TH与TL可以改变周期来改变频率。
举例如下
3000us=3ms=0.003s ? T=0.003s频率=333HZ? ? 2000us=2ms=0.002s ? T=0.002s 频率=500HZ?
1818us=1.818ms=0.001818s T=0.001818s 频率=550HZ? 1300us=1.3ms=0.0013s T=0.0013s 频率750HZ?? 1000us=1ms=0.001s ? T=0.001s ?频率=1000HZ?? 650us=0.65ms=0.00065s T=0.00065s频率1500HZ 500us=0.5ms=0.0005s T=0.0005s 频率=2000HZ 400us=0.4ms=0.0004s T=0.0004s频率2500HZ 330us=0.33ms=0.00033sT=0.00033s 频率3000HZ
可通过改变频率使PWM输出不同的值
以下为一个例子
#include<reg52.h> //包含头文件,一般情况不需要改动 sbit BUZZ=P2^5; ? ? //定义蜂鸣器接口 sbit k3=P3^2;?? ? //定义P31口是k3 sbit k2=P3^0;?? ? //定义P31口是k2 code unsigned int toneH[6]={ ? ? //音调对应的定时器计数值的高8位 第一个音为低音7 0XF8,0XFA,0XFB,0XFC,0XFE,0XFE }; code unsigned int toneL[6]={ ? ? //音调对应的定时器计数值的低8位 0XE6,0X6C,0XA9,0XFF,0X0C,0X9B }; code unsigned int soundtone[42]={ 1,2,3,4,5,6,1,2,3,4,5,6,1,2, 3,4,5,6,1,2,3,4,5,6,1,2,3,4, 5,6,1,2,3,4,5,6,1,2,3,4,5,6 }; code unsigned int soundlong[42]={ 1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; unsigned int t; unsigned char t_H,t_L; /********************************************************************/ /* ? ? ? ? ? ? ? ? ? ? ? ? 初始化定时器0 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/ /********************************************************************/ void init_T0(void) { ?? ?TMOD|= 0x01;?? ? ?//使用方式1,16位定时器?? ??? ? ? ?? ?? ?TH0=0x00;?? ? ? ? ?//给TH0和TL0赋初值,计数器由0开始计数,到65535溢出 ?? ?TL0=0x00; ?? ?EA=0; ? ? ? ? ? ?//总中断打开 ?? ?ET0=1; ? ? ? ? ? //定时器中断打开 ?? ?TR0=0; ? ? ? ? ? //关闭定时器 } /********************************************************************/ /* ? ? ? ? ? ? ? ? ? ? ? ? ? ?延时函数 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/ /* ? ? ? ? ? ? ? 延时时间的计算对应单片机12MHz的晶振 ? ? ? ? ? ? ? ?*/ /* ? ? ? ? ? ?x为延时的ms数,例:x为10时,延时时间约为10ms ? ? ? ? ?*/ /********************************************************************/ void delay1ms(unsigned int x) { ?? ?unsigned int i,j; ?? ?for(j=0;j<x;j++) ?? ??? ?for(i=0;i<123;i++); } void keypros()?? ??? ? ? //K2K3按键的设定 { ?? ?if(k3==0)?? ??? ? ?//检测按键K1是否按下 ?? ?{?? ? ?? ??? ?delay1ms(10); ? //消除抖动 一般大约10ms ?? ??? ?if(k3==0)?? ? //再次判断按键是否按下 ?? ??? ?{ ?? ??? ? ? ? ? ?? ? ? ? ? ?? ? ? EA=1;t=1; ?? ??? ?}?? ? ?? ??? ?while(!k3);?? ? //检测按键是否松开 ?? ?}?? ? ?? ? ?? ??? ?if(k2==0)?? ??? ? ?//检测按键K1是否按下 ?? ?{?? ? ?? ??? ?delay1ms(10); ? //消除抖动 一般大约10ms ?? ??? ?if(k2==0)?? ? //再次判断按键是否按下 ?? ??? ?{ ?? ? ? ? ? ?? ? ? EA=0; ?? ??? ??? ? ? TR0=0; ?? ??? ??? ? ? TR1=0; ?? ??? ?}?? ? ?? ??? ?while(!k2);?? ? //检测按键是否松开 ?? ?}?? ??? ??? ??? ??? ??? ??? ? } /********************************************************************/ /* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?主函数 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/ /********************************************************************/ void main(void)? { ? ? init_T0(); ? ? ? for(;;)? ? ? {?? ? ? ? ? ? for(t=0;t<12;t++)? ? ? ? ? {?? ? ? ?? ??? ? ? ?keypros();?? ? ?? ? ? ? ? ? ? ? t_H=toneH[soundtone[t]]; ? ? //提取音调对应的定时器初始值 ? ? ? ? ? ? t_L=toneL[soundtone[t]]; ? ? ? ? ?? ?TH0=t_H;?? ??? ? ?//给TH0和TL0赋值 ? ? ? ? ?? ?TL0=t_L; ?? ??? ??? ? ? ? ? ? ? ? TR0=1; ? ? ? ? ? ? ?//打开定时器,蜂鸣器发声 ? ? ? ? ? ? delay1ms(soundlong[t]*500); ? ?//延时soundlong[t]指定的时间长度 ? ? ? ? ? ? BUZZ=0; ? ? ? ? ? ? //蜂鸣器不发声,停顿片刻 ? ? ? ? ? ? TR0=0; ? ? ? ? } ?? ??? ?EA=0; ? ? ?}? } /********************************************************************/ /* ? ? ? ? ? ? ? ? ? ? ? 定时器0中断服务程序 ? ? ? ? ? ? ? ? ? ? ? ?*/ /********************************************************************/ char time=0; void T0_ISR(void) interrupt 1 using 1 {?? ? ? ? ?? ?TH0=t_H;?? ??? ? ?//给TH0和TL0重新赋值 ?? ?TL0=t_L; ?? ?time++; ?? ? ?? ?if(time>=1000)?? ? //再次判断按键是否按下 ?? ??? ?{ ?? ? ? ? ? ?? ? ? time=0; ?? ??? ?}?? ? ?? ??? ??? ?if(time<=500)?? ? //再次判断按键是否按下 ?? ??? ? ? ? { ?? ??? ??? ? ? ? ?BUZZ=~BUZZ ?; ?? ??? ? ? ? ?}?? ? ?? ? ? ? ? ? else BUZZ=~BUZZ; ? ? ?//BUZZ的值取反,改变蜂鸣器的状态。 }
|