51单片机如何产生8路PWM波
8路波的频率可以相同,只要占空比可调即可。或者是否有芯片有上述功能,最好可以用单片机控制其占空比。我是需要调节占空比,不是频率。...
8路波的频率可以相同,只要占空比可调即可。
或者是否有芯片有上述功能,最好可以用单片机控制其占空比。
我是需要调节占空比,不是频率。 展开
或者是否有芯片有上述功能,最好可以用单片机控制其占空比。
我是需要调节占空比,不是频率。 展开
5个回答
展开全部
我来说一下我的方案,这个我验证过,方法如下:
其实用一个定时器就够了,外部中断接按键,一个用来频率加,一个用来频率减,即做调节频率用,8路频率从P0口输出,定时器产生中断,比如1us,那么我到1us时对P0.0取反,同时中断里在定义一个变量t1,那么t1计中断次数,假如计到5时我让P1.0取反,儿至于计到几有外部中断来定义,比如定义一个全局变量f,INT0按一次则f++,INT1S按一次f- -,如此频率得以控制,定时器处理如下:
void TIME0_ISR(void) interrupt 2
{
t1++;
if(t1==f) p00=~p00;
if(t1==f) p01=~p01;
if(t1==f) p02=~p02;
if(t1==f) p03=~p03;
if(t1==f) p04=~p04;
if(t1==f) p05=~p05;
if(t1==f) p06=~p06;
if(t1==f) {p07=~p07; f=0;}
}
当然这只是简单的用51本身资源产生而已,还可以用专门的外围电路来实现,我给你一个四路频率产生程序,思想如上,已验证过
/*************************四路频率产生器***************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
/*************************常量定义***************************************/
sbit pwm1=P1^0; //第一路频率 1s内产生5000个脉冲
sbit pwm2=P1^1; //第二路频率 1s内产生1000个脉冲
sbit pwm3=P1^2; //第三路频率 1s内产生2500个脉冲
sbit pwm4=P1^3; //第四路频率 1s内产生500个脉冲
uchar cout1,cout2; //分别用来定义时间宽度
uchar t0_max=10,t1_max=100;
/*******************定时器0初始化函数***************************************/
void time0_ini() //定时0初始化
{
TMOD=0X02; //采用定时器0,选择模式2
TH0=0xA3; //0.1ms定时
TL0=0Xa3;
ET0=1; //允许定时器溢出中断
TR0=1; //启动定时器
}
/***************************外部中断0初始化***********************************/
void INT0_ini()
{
EX0=1; //外部中断0允许
IT0=1; //选择边沿触发方式
}
/***************************定时器1初始化*****************************************/
void time1_ini()
{
TMOD=0X20; //采用定时器1,选择模式2
TH1=0XA3 ; //定时0.1ms
TL1=0XA3;
ET1=1; //允许定时器中断
TR1=1; //启动定时器1
}
/*************************主函数************************************************/
void main()
{
time0_ini(); //调用定时器0初始化函数
time1_ini(); //调用定时器1初始化函数
INT0_ini();
cout1=0;
cout2=0;
pwm1=0; //没一路频率都从低电平开始
pwm2=0;
pwm3=0;
pwm4=0;
EA=1; //打开总中断
while(1); //一直停留在主函数中
}
/***************************定时器中断服务程序************************************/
void tim0_ISR() interrupt 1 //定时0中断服务程序
{
cout1++; //计数变量加1
if(cout1==t0_max)
{
pwm1=~pwm1; //每当到了1ms时取反一次电平,即周期为2ms,1s内产生500个脉冲
}
if(cout1==(t0_max+10))
{
cout1=0; //每当到了2ms时取反一次电平,即周期为4ms,1s内产生250个脉冲
pwm2=~pwm2;
}
}
/**************************定时器1中断服务程序************************************/
void time1_ISR() interrupt 3 //定时器3中断服务程序
{
cout2++;
if(cout2==t1_max)
{
pwm3=~pwm3; //每当到了10ms时取反一次电平,即周期为20ms,1s内产生50个脉冲
}
if(cout2==(t1_max+150))
{
cout2=0; //每当到了25ms时取反一次电平,即周期为50ms,1s内产生20个脉冲
pwm4=~pwm4;
}
}
/********************外部中断0服务程序**************************/
void INT0_ISR() interrupt 0
{
if(t0_max>200) t0_max=10; //清楚上限
if(t1_max>2000) t1_max=100;
t0_max=t0_max+10;
t1_max=t1_max+100;
}
其实用一个定时器就够了,外部中断接按键,一个用来频率加,一个用来频率减,即做调节频率用,8路频率从P0口输出,定时器产生中断,比如1us,那么我到1us时对P0.0取反,同时中断里在定义一个变量t1,那么t1计中断次数,假如计到5时我让P1.0取反,儿至于计到几有外部中断来定义,比如定义一个全局变量f,INT0按一次则f++,INT1S按一次f- -,如此频率得以控制,定时器处理如下:
void TIME0_ISR(void) interrupt 2
{
t1++;
if(t1==f) p00=~p00;
if(t1==f) p01=~p01;
if(t1==f) p02=~p02;
if(t1==f) p03=~p03;
if(t1==f) p04=~p04;
if(t1==f) p05=~p05;
if(t1==f) p06=~p06;
if(t1==f) {p07=~p07; f=0;}
}
当然这只是简单的用51本身资源产生而已,还可以用专门的外围电路来实现,我给你一个四路频率产生程序,思想如上,已验证过
/*************************四路频率产生器***************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
/*************************常量定义***************************************/
sbit pwm1=P1^0; //第一路频率 1s内产生5000个脉冲
sbit pwm2=P1^1; //第二路频率 1s内产生1000个脉冲
sbit pwm3=P1^2; //第三路频率 1s内产生2500个脉冲
sbit pwm4=P1^3; //第四路频率 1s内产生500个脉冲
uchar cout1,cout2; //分别用来定义时间宽度
uchar t0_max=10,t1_max=100;
/*******************定时器0初始化函数***************************************/
void time0_ini() //定时0初始化
{
TMOD=0X02; //采用定时器0,选择模式2
TH0=0xA3; //0.1ms定时
TL0=0Xa3;
ET0=1; //允许定时器溢出中断
TR0=1; //启动定时器
}
/***************************外部中断0初始化***********************************/
void INT0_ini()
{
EX0=1; //外部中断0允许
IT0=1; //选择边沿触发方式
}
/***************************定时器1初始化*****************************************/
void time1_ini()
{
TMOD=0X20; //采用定时器1,选择模式2
TH1=0XA3 ; //定时0.1ms
TL1=0XA3;
ET1=1; //允许定时器中断
TR1=1; //启动定时器1
}
/*************************主函数************************************************/
void main()
{
time0_ini(); //调用定时器0初始化函数
time1_ini(); //调用定时器1初始化函数
INT0_ini();
cout1=0;
cout2=0;
pwm1=0; //没一路频率都从低电平开始
pwm2=0;
pwm3=0;
pwm4=0;
EA=1; //打开总中断
while(1); //一直停留在主函数中
}
/***************************定时器中断服务程序************************************/
void tim0_ISR() interrupt 1 //定时0中断服务程序
{
cout1++; //计数变量加1
if(cout1==t0_max)
{
pwm1=~pwm1; //每当到了1ms时取反一次电平,即周期为2ms,1s内产生500个脉冲
}
if(cout1==(t0_max+10))
{
cout1=0; //每当到了2ms时取反一次电平,即周期为4ms,1s内产生250个脉冲
pwm2=~pwm2;
}
}
/**************************定时器1中断服务程序************************************/
void time1_ISR() interrupt 3 //定时器3中断服务程序
{
cout2++;
if(cout2==t1_max)
{
pwm3=~pwm3; //每当到了10ms时取反一次电平,即周期为20ms,1s内产生50个脉冲
}
if(cout2==(t1_max+150))
{
cout2=0; //每当到了25ms时取反一次电平,即周期为50ms,1s内产生20个脉冲
pwm4=~pwm4;
}
}
/********************外部中断0服务程序**************************/
void INT0_ISR() interrupt 0
{
if(t0_max>200) t0_max=10; //清楚上限
if(t1_max>2000) t1_max=100;
t0_max=t0_max+10;
t1_max=t1_max+100;
}
展开全部
用一个定时器作US级定时,设一个静态变量t每次定时中断减1,t从初值减到0为一个脉冲输出周期,如果t初值为100,设置一个全局变量A来调节占空比,当t>A时输出1,当t<A时输出0,多设几个A这样的变量,就可以多控制几路PWM
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
接电子电位器+ICL8038专用芯片,就可以控制器占空比了。
电子电位器x9C103S
电子电位器x9C103S
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
能产生8路PWM的单片机我没见过,不过应该能有吧……
现在一般的单片机都可以产生至少两路PWm,试试C8051F系列的,还不错
现在一般的单片机都可以产生至少两路PWm,试试C8051F系列的,还不错
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
自己可以编个程序实现的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询