600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 占空比输出程序c语言 关于51单片机输出频率和占空比可调的PWM波程序问题

占空比输出程序c语言 关于51单片机输出频率和占空比可调的PWM波程序问题

时间:2021-04-18 12:02:37

相关推荐

占空比输出程序c语言 关于51单片机输出频率和占空比可调的PWM波程序问题

//------------------------------------------------------------------------------------

//程序功能简介:本程序产生15HZ~~~50KHZ的方波,并且实现频率和脉宽的独立调制,即可

//在改变频率的同时不改变脉宽,再改变脉宽的同时不改变频率;同时设置

//两个调节步长------在KEY键按下时,粗调,没有按下时,细调;

//程序思路: 本程序用到两个定时器------定时器0和定时器1,其中定时器0工作在定时方式下,

//决定方波的频率;定时器1,同样工作在定时方式下,用于设定脉宽;

//------------------------------------------------------------------------------------

#include

#include

#defineuchar unsigned char

#defineuint unsigned int

#defineALL65536//定时器工作方式1时,最大基数长度 65536;

#defineF_osc 12000000 //晶振频率12M;

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; //波形输出;

uchar TIMER0_H,TIMER0_L,TIMER1_H,TIMER1_L; //定时器0和定时器1的初值设置;

uchar PERCENT=50; //初始占空比;

uchar FLAG_F=0,FLAG_W=0; //频率调节标志和脉宽调制标志;

uintFREQ=50000; //初始频率;

float temp; //临时全局变量,用于数据传递;

void delay(uchar t); //延时函数,用于按键去抖;

void init(); //初始化函数,用于定时器的初始化;

void calculate_F(); //频率计算函数,当频率变化,计算出定时器0初值;

void calculate_W(); //脉宽计算函数,脉宽变化时,计算出定时器1初值;

void key_scan();//按键扫描函数;

void timer0();//定时器0中断函数;

void timer1();//定时器1中断函数;

void delay(uchar t)

{

uchar i,j;

while(t--)//每个脉冲为1us

{

for(i=0;i<100;i++)

for(j=0;j<100;j++);

}

}

void calculate_F()

{

temp = ALL - F_osc/12.0/FREQ;

TIMER0_H = (uint)temp/256;

TIMER0_L = (uint)temp%256;

}

void calculate_W()

{

float TEMP;

TEMP = (1 - PERCENT/100.0)*ALL + temp*PERCENT/100.0;TIMER1_H = (uint)TEMP/256;

TIMER1_L = (uint)TEMP%256;

}

void key_scan()

{

delay(4);

if(!KEY_F_UP) //频率上调键按下;

{

FLAG_F=1; //置标志位;

if(!KEY)

FREQ+=10;

else

FREQ++;

if(FREQ>50000)

FREQ=1;

}

else if(!KEY_F_DOWN) //频率下调键按下;

{

FLAG_F=1; //置标志位;

if(!KEY)

FREQ-=10;

else

FREQ--;

if(FREQ<1)

FREQ=50000;

}

else if(!KEY_W_UP) //脉宽上调键按下;

{

FLAG_W=1; //置标志位;

if(!KEY)

PERCENT+=5;

else

PERCENT++;

if(PERCENT>49)

PERCENT=1;

}

else if(!KEY_W_DOWN) //脉宽下调键按下;

{

FLAG_W=1; //置标志位;

if(!KEY)

PERCENT-=5;

else

PERCENT--;

if(PERCENT<1)

PERCENT=49;

}

else ;}void timer0() interrupt 1 //决定频率

{

TH0=TIMER0_H;

TL0=TIMER0_L;

TR1=1; //开定时器1;

OUTPUT=1;

}

void timer1() interrupt 3 //决定脉宽

{

TH1=TIMER1_H;

TL1=TIMER1_L;

TR1=0; //关定时器1,一定要这一步,因为定时器1的定时短于定时器0;

OUTPUT=0;

}

void init()

{

TMOD=0x11; //定时器0和定时器1都工作在方式1,16位计数器;

calculate_F();//初始为1KHZ,占空比为50%;

calculate_W();

TH0=TIMER0_H;

TL0=TIMER0_L;

TH1=TIMER1_H;

TL1=TIMER1_L;

ET0=1;

ET1=1;

EA=1;TR0=1;

TR1=1;

}

main()

{

init();

while(1)

{

key_scan();

if(FLAG_F) //改变频率时要注意要进行脉宽的重新设置;

{

calculate_F();

calculate_W();

FLAG_F=0;

}

if(FLAG_W) // 脉宽改变,频率不改变;

{

calculate_W();

FLAG_W=0;

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。