科创初试:小型降压电路(开关电源)

实现功能:输入15V,输出电压在3V-12V之间可调

难点:控制电路需要精心设计

实现:使用51单片机输出可调PWM波,使用IR2110驱动MOS管,使用BUCK电路实现直流降压。

原理图

参考资料

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include<reg51.h>
//===================变量定义====================
int Dratio=10; //占空比
unsigned int Dcache=0; //占空比缓存
unsigned char n=0; //显示位数
unsigned char RatioRst=20; //占空比重置周期
//数码管显示码表
unsigned char code NND[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char code NWD[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
unsigned char code WM[]={0xfe,0xfd,0xfb,0xf7};
sbit Pout=P3^1; //PWM高端输出
sbit PoutL=P3^0; //PWM低端输出
sbit ON=P3^2; //外部输入中断标志
sbit PL1=P2^4;//占空比+5
sbit MI1=P2^5;//占空比-5
sbit PL5=P2^6;//占空比+25
sbit MI5=P2^7;//占空比-25
//====================变量定义结束======================
//定时中断初始化函数
void Reset()
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0xff;
TL0=0xf6;
}
//外部输入中断初始化函数
void Reset2()
{
EA=1;
EX0=1;
IT0=0;
}
//延时函数
void Delay(unsigned int ms)
{
unsigned char i;
while(ms--)
for(i=0;i&lt;120;i++);
}
//输出模式显示函数
void DP(unsigned int i,unsigned int n)
{
unsigned char dis[4];

dis[1]=(i%1000)/100;
dis[2]=(i%100)/10;
dis[3]=i%10;
switch(n)
{
case 0:
P2=WM[0];
P1=0x5e;
break;

case 1:
P2=WM[1];
P1=NWD[dis[1]];
break;

case 2:
P2=WM[2];
P1=NND[dis[2]];
break;

case 3:
P2=WM[3];
P1=NND[dis[3]];
break;
}
}
//调节模式显示函数
void DP2(unsigned int i,unsigned int n)
{
unsigned char dis[4];

dis[0]=i/1000;
dis[1]=(i%1000)/100;
dis[2]=(i%100)/10;
dis[3]=i%10;
switch(n)
{
case 0:
P2=WM[0];
P1=NWD[dis[0]];
break;

case 1:
P2=WM[1];
P1=NWD[dis[1]];
break;

case 2:
P2=WM[2];
P1=NWD[dis[2]];
break;

case 3:
P2=WM[3];
P1=NWD[dis[3]];
break;
}
}
//定时中断子函数
void AD() interrupt 1
{
Reset();

//==========PWM处理==========
RatioRst--;
if(Dcache!=0)
Dcache--;
else
{
Pout=0;
PoutL=~Pout;
Dcache=20;
}
if(RatioRst==0)
{
RatioRst=20;
Dcache=Dratio;
Pout=1;
PoutL=~Pout;
}
//===========PWM处理结束===========

// 显示刷新开始
DP(Dratio*5,n);
n++;
if(n==4)
n=0;
// 显示刷新结束
}
//外部中断子函数
void button() interrupt 0
{

int k=1;// LOOP CONTROL
Pout=0;
PoutL=~Pout;
EA=0;
Delay(1000);
while(k)
{

//========按键检测与占空比改变=========
if(PL1==0)
{
Delay(10);
if(PL1==0)
{
Dratio=Dratio+1;
Dcache=Dratio;
}
while(!PL1);
}

if(PL5==0)
{
Delay(10);
if(PL5==0)
{
Dratio=Dratio+5;
Dcache=Dratio;
}
while(!PL5);
}

if(MI5==0)
{
Delay(10);
if(MI5==0)
{
Dratio=Dratio-5;
Dcache=Dratio;
}
while(!MI5);
}

if(MI1==0)
{
Delay(10);
if(MI1==0)
{
Dratio=Dratio-1;
Dcache=Dratio;
}
while(!MI1);
}
//=======按键检测与占空比改变结束============

// 限制占空比在正常范围内
if(Dratio&lt;0)
Dratio=20;
else if(Dratio&gt;20)
Dratio=0;
// 数码管显示刷新
DP2(Dratio*5,n);
n++;
if(n==4)
n=0;

//返回主程序
if(ON==0)
{
Delay(10);
if(ON==0)
{
while(!ON);
Delay(1000);
k=0;
}
}
}
}
void main()
{
Reset();
Reset2();

Dcache=Dratio;
Pout=1;
PoutL=~Pout;

while(1){
Reset2();
}
}

PS:项目从理论到实践只花了三天(ddl是第一生产力),最后居然还拿奖了

(有想要工程文件的可流言联系)