<div>//------------------------------------------------------------------------------------
//程序功能简介:本程序产生15HZ~~~50KHZ的方波,并且实现频率和脉宽的独立调制,即可
//在改变频率的同时不改变脉宽,再改变脉宽的同时不改变频率;同时设置
//两个调节步长------在KEY键按下时,粗调,没有按下时,细调;
//程序思路: 本程序用到两个定时器------定时器0和定时器1,其中定时器0工作在定时方式下,
//决定方波的频率;定时器1,同样工作在定时方式下,用于设定脉宽;
//------------------------------------------------------------------------------------ </div><div>
</div><div> #include <reg52.h>
#include <math.h></div><div>
</div><div> #define uchar unsigned char
#define uint unsigned int
#define ALL 65536 //定时器工作方式1时,最大基数长度 65536;
#define F_osc 12000000 //晶振频率12M;</div><div>
</div><div> sbit KEY_F_UP=P0^2; //频率上调按钮;
sbit KEY_F_DOWN=P0^3; //频率下调按钮;
sbit KEY_W_UP=P0^4; //脉宽上调按钮;
sbit KEY_W_DOWN=P0^5; //脉宽下调按钮;
sbit KEY=P0^6; //粗细调节按钮-----按下为粗调,否则为细调;
sbit OUTPUT=P1^0; //波形输出;</div><div>
</div><div> uchar TIMER0_H,TIMER0_L,TIMER1_H,TIMER1_L; //定时器0和定时器1的初值设置;
uchar PERCENT=50; //初始占空比;
uchar FLAG_F=0,FLAG_W=0; //频率调节标志和脉宽调制标志;
uint FREQ=50000; //初始频率;
float temp; //临时全局变量,用于数据传递;</div><div>
</div><div> void delay(uchar t); //延时函数,用于按键去抖;
void init(); //初始化函数,用于定时器的初始化;
void calculate_F(); //<font style="background-color: red;">频率计算函数,当频率变化,计算出定时器0初值;</font>
void calculate_W(); //<font style="background-color: red;">脉宽计算函数,脉宽变化时,计算出定时器1初值;</font>
void key_scan(); //按键扫描函数;
void timer0(); //定时器0中断函数;
void timer1(); //定时器1中断函数;</div><div>
</div><div> void delay(uchar t)
{
uchar i,j;</div><div>
</div><div> while(t--) //每个脉冲为1us
{
for(i=0;i<100;i++)
for(j=0;j<100;j++);
}
}</div><div>
</div><div> void calculate_F()
{
<font color="red"> temp = ALL - F_osc/12.0/FREQ;</font></div><div>
</div><div> TIMER0_H = (uint)temp/256;
TIMER0_L = (uint)temp%256;
}</div><div>
</div><div> void calculate_W()
{
float TEMP;</div><div>
</div><div> <font color="red">TEMP = (1 - PERCENT/100.0)*ALL + temp*PERCENT/100.0;</font></div><div>
</div><div> TIMER1_H = (uint)TEMP/256;
TIMER1_L = (uint)TEMP%256;
}</div><div>
</div><div> void key_scan()
{
delay(4);</div><div>
</div><div> if(!KEY_F_UP) //频率上调键按下;
{
FLAG_F=1; //置标志位;</div><div>
</div><div> if(!KEY)
FREQ+=10;</div><div>
</div><div> else
FREQ++;</div><div>
</div><div> if(FREQ>50000)
FREQ=1;
}</div><div>
</div><div> else if(!KEY_F_DOWN) //频率下调键按下;
{
FLAG_F=1; //置标志位;</div><div>
</div><div> if(!KEY)
FREQ-=10;</div><div>
</div><div> else
FREQ--;</div><div>
</div><div> if(FREQ<1)
FREQ=50000;
}</div><div>
</div><div> else if(!KEY_W_UP) //脉宽上调键按下;
{
FLAG_W=1; //置标志位;</div><div>
</div><div> if(!KEY)
PERCENT+=5;</div><div>
</div><div> else
PERCENT++;</div><div>
</div><div> if(PERCENT>49)
PERCENT=1;
}</div><div>
</div><div> else if(!KEY_W_DOWN) //脉宽下调键按下;
{
FLAG_W=1; //置标志位;</div><div>
</div><div> if(!KEY)
PERCENT-=5;</div><div>
</div><div> else
PERCENT--;</div><div>
</div><div> if(PERCENT<1)
PERCENT=49;
} </div><div>
</div><div> else ;</div><div>
</div><div> }</div><div>
</div><div> void timer0() interrupt 1 //决定频率
{
TH0=TIMER0_H;
TL0=TIMER0_L;
TR1=1; //开定时器1;
OUTPUT=1;
}</div><div>
</div><div> void timer1() interrupt 3 //决定脉宽
{
TH1=TIMER1_H;
TL1=TIMER1_L;
TR1=0; <font style="background-color: red;"> //关定时器1,一定要这一步,因为定时器1的定时短于定时器0;</font>
OUTPUT=0;
}</div><div>
</div><div> void init()
{
TMOD=0x11; //定时器0和定时器1都工作在方式1,16位计数器;
calculate_F(); //初始为1KHZ,占空比为50%;
calculate_W();</div><div>
</div><div> TH0=TIMER0_H;
TL0=TIMER0_L;</div><div>
</div><div> TH1=TIMER1_H;
TL1=TIMER1_L;</div><div>
</div><div> ET0=1;
ET1=1;</div><div>
</div><div> EA=1;</div><div>
</div><div> TR0=1;
TR1=1;
}</div><div>
</div><div> main()
{
init();</div><div>
</div><div> while(1)
{
key_scan();
if(FLAG_F) //改变频率时要注意要进行脉宽的重新设置;
{
calculate_F();
calculate_W();
FLAG_F=0;
}</div><div>
</div><div> if(FLAG_W) // 脉宽改变,频率不改变;
{
calculate_W();
FLAG_W=0;
}
}
}
</div>