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

本人买了这本书,配套了一个开发板,懂的都懂哈,这本书非常适合初学者入门
目标分析
我们的目标:数码管显示当前输出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;
}












![[MySQL]事务的浅谈](https://img-blog.csdnimg.cn/5581e9d77725491cb28fc1be522442e5.png)



