51单片机输出两路独立的可调占空比pwm,如何变成
发布网友
发布时间:2023-07-29 21:20
我来回答
共3个回答
热心网友
时间:2023-11-11 12:07
51单片机输出两路独立的可调占空比pwm,比较困难啊,只有两个定时器,一路就需要2个定时器了。 用52吧,有3个定时器,1个做PWM的时基,另两个做两路占空比定时,这样两路PWM的频率一样,占空可独立调节。(详细程序没有,只能给你个方法或思路参考)
要求高用ATmega8吧,带有比较模块能实现3路PWM。
热心网友
时间:2023-11-11 12:07
一个定时器做时基,用软件实现占空比。
这是一个PWM控制LED亮度的,我目前电脑只有这个
/* **********************************************************************
* Author: XXXXXXX *
* Date : 2010/03/06 *
* Description:利用PWM控制LED亮度,扫描频率50hz,亮度调节档次100 *
* *
************************************************************************/
#include<reg52.h>
#define LED P1
#define LED_ON() P1=0x00
#define LED_OFF() P1=0xff
#define LED_PWM_MAX 99
#define LED_PWM_MIN 0
#define uchar unsigned char
#define uint unsigned int
static uchar TimeCounter = 0;//时间控制
static uchar LedState = 0;//控制方向 0:渐亮 1:渐暗
static uchar LedPWMCounter = 0; //LED占空比
void Timer0Init()
{
TMOD = 0x01;
TH0 = (65536-200)/256;
TL0 = (65536-200)%256;
EA = 1;
ET0 = 1;
}
void main()
{
Timer0Init();
TR0=1;
while(1)
;
}
void Timer_0() interrupt 1
{
static PWMCounter = 0;
TH0 = (65536-200)/256;
TL0 = (65536-200)%256;
TimeCounter++;
if(TimeCounter>=100)
{
TimeCounter = 0;
if((LedPWMCounter<=LED_PWM_MAX)&&(0 ==LedState))
{
LedPWMCounter++;
if(LedPWMCounter >LED_PWM_MAX)
{
LedState = 1;
LedPWMCounter = LED_PWM_MAX;
}
}
if((LedPWMCounter>=LED_PWM_MIN)&&(1 ==LedState ))
{
LedPWMCounter--;
if(LedPWMCounter <LED_PWM_MIN)
{
LedState = 0;
LedPWMCounter = LED_PWM_MIN;
}
}
PWMCounter = LedPWMCounter;
}
if(PWMCounter > 0)
{
LED_ON();
PWMCounter--;
}
else
{
LED_OFF();
}
}
热心网友
时间:2023-11-11 12:08
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dja=P1^4; //电机a正反转控制端
sbit djb=P1^5; //电机b正反转控制端
//a电机接口
sbit in1=P1^0;
sbit in2=P1^1;
//b电机接口
sbit in3=P1^2;
sbit in4=P1^3;
uchar ysyz,ysyz1,ysd,ysx;
void bjys() //比较两电机高电平时长
{
if(ysyz>ysyz1)
{ysd=ysyz;ysx=ysyz1;}
else
{ysd=ysyz1;ysx=ysyz;}
}
void srpwm() //从P0和P2并行送入占空比
{
ysyz=P0; //并行输入a电机高电平时长,最大值200,超过则变回0
ysyz1=P2; //并行输入b电机高电平时长,最大值200,超过则变回0
if((ysyz<=200)&&(ysyz1<=200))
bjys(); //比较两电机PWM高电平时长
else
{
ysd=0;
ysx=0;
}
}
void zz() //两电机正转
{
uchar i;
srpwm();
in1=1;in3=1;
for(i=0;i<ysd;i++)
{
if((i==ysx)&&(ysyz>ysyz1))
in3=0;
if((i==ysx)&&(ysyz<=ysyz1))
in1=0;
}
in1=0;in3=0;
for(i=0;i<=(200-ysd);i++)
{
}
}
void zf() //电机一正一反
{
uchar i;
srpwm();
in1=1;in4=1;
for(i=0;i<ysd;i++)
{
if((i==ysx)&&(ysyz>ysyz1))
in4=0;
if((i==ysx)&&(ysyz<=ysyz1))
in1=0;
}
in1=0;in4=0;
for(i=0;i<=(200-ysd);i++)
{
}
}
void fz() //电机一反一正
{
uchar i;
srpwm();
in2=1;in3=1;
for(i=0;i<ysd;i++)
{
if((i==ysx)&&(ysyz>ysyz1))
in3=0;
if((i==ysx)&&(ysyz<=ysyz1))
in2=0;
}
in2=0;in3=0;
for(i=0;i<=(200-ysd);i++)
{
}
}
void ff() //两电机反转
{
uchar i;
srpwm();
in2=1;in4=1;
for(i=0;i<ysd;i++)
{
if((i==ysx)&&(ysyz>ysyz1))
in4=0;
if((i==ysx)&&(ysyz<=ysyz1))
in2=0;
}
in2=0;in4=0;
for(i=0;i<=(200-ysd);i++)
{
}
}
void main()
{
P1=0x7f; //P1.7接驱动使能端
while(1)
{
in2=0;in4=0;
while((dja==1)&&(djb==1))
zz();
in1=0;in3=0;
while((dja==0)&&(djb==0))
ff();
in2=0;in3=0;
while((dja==1)&&(djb==0))
zf();
in1=0;in4=0;
while((dja==0)&&(djb==1))
fz();
}
}
//此程序已调试通过,调试环境:(AT89C52、晶振:22.1184M、电源:5V)