频率是周期的倒数
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
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;
void init_T0(void)
{
TMOD|= 0x01; //使用方式1,16位定时器
TH0=0x00; //给TH0和TL0赋初值,计数器由0开始计数,到65535溢出
TL0=0x00;
EA=0; //总中断打开
ET0=1; //定时器中断打开
TR0=0; //关闭定时器
}
void delay1ms(unsigned int x)
{
unsigned int i,j;
for(j=0;j
}
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;
}
}
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的值取反,改变蜂鸣器的状态。
}



