树欲静而风不止慢一点吧

树欲静而风不止慢一点吧

我们学校电气专业开始做电力电子的课设了,小组选了一项制作硬件电路的任务,里面有要求采用数控方式实现DC-DC电压变换的输出电压调节,数控在电路中的体现就是用单片机输出可调占空比的PWM作用于产生PWM波控制IGBT的芯片。考虑到可能有同学没接触过51单片机的C语言编程,特写下此篇文章,希望能够给大家带来帮助。

选用51开发板

电力电子课设—数控产生PWM波——使用51单片机输出占空比可调PWM波(按钮控制、数码管显示)控制速成教程-LMLPHP

本人买了这本书,配套了一个开发板,懂的都懂哈,这本书非常适合初学者入门

目标分析

我们的目标:数码管显示当前输出PWM波占空比,使用按键可以调节占空比。

所以,我们需要:

1.一个引脚输出PWM波;

2.一个定时器控制PWM波的占空比;

3.若干按钮对占空比进行操作;

4.数码管显示占空比。

以下对这四个任务逐一进行拆解。

数码管

数码管有共阴极和共阳极两种,它们可通过向端子输入不同的字形码,就可在数码管显示对应的数字。

大家DIY的时候选扩展数码管最好用共阳极的数码管,因为共阳极数码管通过低电平驱动发光,要求驱动功率小。不过本教程配套的开发板上配了共阴极数码管,我们就用共阴极数码管了。

以下是详细解释为什么要使用共阳极数码管的文章:

单片机驱动共阳数码管和共阴数码管的比较-昌晖仪表网 (yunrun.com.cn)

选择数码管上的2个位,对应占空比0~99。

按钮

使用按钮需消抖。原因如下:

什么是按键消抖?为什么要消抖?_百度知道 (baidu.com)

这里选用四个按钮,详细作用见代码注释。

定时器

定时器配置内容可看看此文章:

51单片机定时器/计数器_单片机计数器_KeLin&的博客-CSDN博客

定时时间=振荡周期*12*(65536-初值)。

PWM波输出

选择一个引脚,当定时器达到初始装载时间A,引脚从高电平跳转到低电平;当定时器达到初始装载时间B,引脚从低电平跳转到高电平。

完整代码

#include<reg52.h> 
#define uchar unsigned char
//PWM周期选择:1毫秒
#define PWMZHOUQI 1000
#define JISHIMAX 65536-PWMZHOUQI
#define CHUZHI	30

#define duan P0	 
sbit wei1=P2^4; //LED显示器的位
sbit wei2=P2^5;
sbit wei3=P2^6; 
sbit wei4=P2^7;
sbit k1=P3^4;	 //+1、-1
sbit k2=P3^5; //可长按
sbit k3=P3^6;	//改变变化方向
sbit k4=P3^7;	 //重置占空比
sbit output=P2^0; //PWM输出端口

int is_gd=0;
int GD=	JISHIMAX*CHUZHI;//高电平时间
int zhankongbi=CHUZHI;

uchar code num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f};//对应数字0~9



void delay(unsigned int xms)   //按键消抖用延时,单位毫秒
{
	unsigned int i,j;
	for(i=xms;i>0;i--)
		for(j=112;j>0;j--);

}

void timer0_init() 
{
	TMOD=0x01;//16位定时器
	TH0=(GD>>8)&0xFF;//初始值
	TL0=GD&0xFF;
	EA=1; //打开总中断
	ET0=1; //打开定时器T0中断
	TR0=1; //启动定时器T0

}
void main()
{
	int dir=1;
	int shi;
	int ge;
	int had_press=0;
	output=1;
	is_gd=1;
	timer0_init();
	while(1)
	{
	   if(k4==0)
		{
			delay(10);
			if(k4==0)
			{
				while(k4==0);
				zhankongbi=CHUZHI;
				had_press=1;
			}
		}

		if(k3==0)
		{
			delay(10);
			if(k3==0)
			{
				while(k3==0);
				dir=-dir;
				had_press=1;	
			}
		}

		if(k1==0)
		{
			delay(10);
			if(k1==0)
			{
				while(k1==0);
				if ((zhankongbi+dir)>=0&& (zhankongbi+dir)<=99)
					zhankongbi+=dir;
				had_press=1;	
			}
		}

		if(k2==0)
		{
			delay(10);
			while(k2==0)
			{
				delay(10);
				if ((zhankongbi+dir)>=0&& (zhankongbi+dir)<=99)
					zhankongbi+=dir;
				had_press=1;	
			}
		}
		shi=zhankongbi/10;
		ge=zhankongbi%10;

		if (had_press)
		{
			GD=JISHIMAX*zhankongbi;
			TH0=(GD>>8)&0xFF;//初始值
			TL0=GD&0xFF;
			is_gd=1;	
		}
		
		duan=num[shi];
		wei1=0;
		wei2=0;
		wei3=1;
		wei4=0;
		delay(5);
		duan=num[ge];
		wei1=0;
		wei2=0;
		wei3=0;
		wei4=1;
		delay(5);

	}
}

void timer0()interrupt 1
{	
	if(is_gd)
	{
		TH0=((JISHIMAX*(1-zhankongbi))>>8)&0xFF;//初始值
		TL0=(JISHIMAX*(1-zhankongbi))&0xFF;	
	}	
	if(!is_gd)
	{
		TH0=(GD>>8)&0xFF;//初始值
		TL0=GD&0xFF;
	}
	is_gd=-is_gd;
	output=~output;
}
05-22 05:50