51单片机按键控制输出pwm的占空比

    之前说到利用51单片机输出pwm,但是输出的pwm是固定占空比的,如果想要改变占空比,还得回过头来修改程序并重新烧写进单片机。这样做的话不但麻烦、效率低,还又把芯片的可烧写次数减少了一次,虽然51的芯片现在很便宜,但能省点就省点,能不浪费就不浪费,哈哈,开玩笑啦!最主要的还是为了灵活性,为此特地通过加入按键的功能来实现动态修改输出的pwm的占空比。这样在用pwm控制电机的时候就能使用按键来控制电机转速了。废话不多说,见下:

#include<reg51.h>

#define uint unsigned int 
#define uchar unsigned char							 

uchar time; 
double count=26;	//定义占空比,并初始占空比为26%
sbit PWM=P2^0;      //P2^0口输出PWM 
sbit key_add=P3^4;   //电机加速的按键 的I/O口
sbit key_dec=P3^5;   //电机减速的按键 的I/O口


/************函数声明**************/
void delayxms(uint z); //延时
void Motor_add();	  //电机加速,即增加占空比
void Motor_dec();	   //电机减速,即减少占空比
void timer0_init();		//定时器0初始化

/*********主函数********************/
void main()
{	 
	timer0_init();
	delayxms(5);
	while(1)
	{
	 Motor_add();
	 Motor_dec();
	}
}

/****************延时处理**********************/
void delayxms(uint z) //延时xms程序
{
    uint x,y;
	for(y=z;x>0;x--)
		for(y=110;y>0;y--);
}


void Motor_add()  //电机加速
{
  if(key_add==0)
  {
	  delayxms(2); //此处时间不能太长,否者会的中断产生冲突
  if(key_add==0)
  {
	  count+=0.5;	//每按一次加速按键占空比加0.5
   if(count>=32)	    //限定占空比上限
	{
	 count=32;
	}
  }
	while(!key_add);
  }
}

void Motor_dec()//电机减速
{
 if(key_dec==0)
 {
  delayxms(2);//此处时间不能太长,否者会的中断产生冲突
  if(key_dec==0)
  {
  	count-=0.5;	 	//每按一次减速按键占空比减0.5
   if(count<=25)    //限定占空比下限
   {
	count=25;
   }
  }
	while(!key_dec);
   }
}

/***********定时器0初始化***********/
void timer0_init()
{
  TMOD=0x01; //定时器0工作于方式1
  TH0=(65536-10)/256;
  TL0=(65536-10)%256;
  TR0=1;
  ET0=1;
  EA=1;
}

/**************定时0中断处理******************/
void timer0_int() interrupt 1 
{
	
  TR0=0;    //设置定时器初值期间,关闭定时器
  TH0=(65536-10)/256;
  TL0=(65536-10)%256;
  TR0=1;
	 
  time++;
  if(time<count)	  //count为占空比
  {
	PWM=1;	   //输出高电平
  }
  else 
	PWM=0;	
  if(time>=100)
  {
	time=0;
  }
 }


我特地标注了重要部分程序的注释。另外,可以在程序中修改按键每次增加或者减少的占空比,但有的时候发现在按键调节占空比时,不想占空比一直增加或者减少下去,还可以在程序里面修改限定占空比的上下限,当达到上限或下限时,相应的增加或减少占空比的按钮这时就不再增加或者减少占空比了。这样在电机控制时就可以防止不小心让电机速度增加到规定速度以上或以下了。这些在程序注释里面课看见在哪里改。除此之外,还可以加进来很多功能。这里就不举相应的子了。


  • 126
    点赞
  • 596
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
好的,以下是具体的代码实现: ```c #include <reg52.h> #define FREQ 1000 // 定义PWM信号的频率,单位为Hz #define PWM_MAX 255 // 定义PWM占空比的最大值 sbit KEY1 = P1^0; // 定义按键1 sbit KEY2 = P1^1; // 定义按键2 unsigned char duty_cycle = 128; // PWM占空比的初始值,取值范围为0~255 void timer_init() { TMOD |= 0x01; // 设置定时器0为模式1 TH0 = 256 - (11059200/12/FREQ); // 计算定时器初值,使得定时器中断频率为FREQ TL0 = TH0; // 设置定时器初值 ET0 = 1; // 允许定时器0中断 EA = 1; // 允许中断 TR0 = 1; // 启动定时器0 } void pwm_output() { static unsigned char cnt = 0; if(cnt < duty_cycle) // PWM占空比 { P2 = 0xFF; // P2口输出高电平 } else { P2 = 0x00; // P2口输出低电平 } cnt++; if(cnt == PWM_MAX) // 当PWM计数器达到最大值时,重新开始计数 { cnt = 0; } } void main() { timer_init(); // 定时器初始化 while(1) { if(KEY1 == 0) // 当按键1按下时,增加PWM占空比 { delay(10); // 延时去抖动 if(KEY1 == 0) { duty_cycle += 10; if(duty_cycle > PWM_MAX) { duty_cycle = PWM_MAX; } } while(!KEY1); // 等待按键1释放 } if(KEY2 == 0) // 当按键2按下时,切换PWM频率 { delay(10); // 延时去抖动 if(KEY2 == 0) { if(FREQ == 1000) { FREQ = 2000; } else { FREQ = 1000; } TH0 = 256 - (11059200/12/FREQ); // 更新定时器初值 duty_cycle = 128; // PWM占空比恢复初始值 } while(!KEY2); // 等待按键2释放 } } } void timer0_isr() interrupt 1 { pwm_output(); // PWM输出 } ``` 以上代码实现了一个简单的按键可调占空比固定频率的PWM输出程序。程序使用定时器0产生固定频率的PWM信号,通过按键1可以增加PWM占空比,按键2可以切换PWM的频率。由于程序中使用了定时器中断,需要在中断服务函数中输出PWM信号。 希望以上代码可以对您有所帮助,如有疑问请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值