【Proteus仿真】51单片机8路舵机点动±90°点动控制

【Proteus仿真】51单片机8路舵机点动±90°点动控制


  • Proteus仿真
    在这里插入图片描述
  • Proteus连线图
    在这里插入图片描述

程序代码

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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include<reg52.h>

sbit PWM0 = P1^0;
sbit PWM1 = P1^1;
sbit PWM2 = P1^2;
sbit PWM3 = P1^3;
sbit PWM4 = P1^4;
sbit PWM5 = P1^5;
sbit PWM6 = P1^6;
sbit PWM7 = P1^7;

sbit ADD = P3^6;
sbit SUB = P3^7;

#define uchar unsigned char
#define uint unsigned int

uint t_up0 = 1500; //舵机PWM高电平时间 1000~2000表示1ms到2ms
uint t_up1 = 1500;
uint t_up2 = 1500;
uint t_up3 = 1500;
uint t_up4 = 1500;
uint t_up5 = 1500;
uint t_up6 = 1500;
uint t_up7 = 1500;

uint t0_h;
uint t0_l;


void delayms(uint ms)
{
unsigned char a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
void timer\_init()
{
EA = 1;
ET0 = 1;
PT0 = 1;
TMOD = 0x11;
TH0 = (65536 - t_up0)/256;
TL0 = (65536 - t_up0)%256;
}

uchar t0_flag = 0;
uint num_max = 65535; //直接用65535 - t\_up 不用变量 - t\_up 时,误差较大,原因暂时不明 【注:65536不能存到uint类型变量中】
uint t_change = 63036;//换路周期2.5ms 8路

uchar error0 = 45;
uchar error1 = 45;
uchar error2 = 52;
uchar error3 = 52;
uchar error4 = 57;
uchar error5 = 57;
uchar error6 = 63;
uchar error7 = 63;
uchar error8 = 70;
uchar error9 = 70;
uchar error10 = 76;
uchar error11 = 76;
uchar error12 = 82;
uchar error13 = 82;
uchar error14 = 88;
uchar error15 = 88;

void timer0() interrupt 1
{

if(t0_flag == 0)
{
PWM0 = 1;
TH0 = (num_max - t_up0 + error0)/256; //+error0是为了抵消执行语句花的时间
TL0 = (num_max - t_up0 + error0)%256;

t0_flag = 1;
}
else if(t0_flag == 1)
{
PWM0 = 0;
TH0 = (t_change + t_up0 +error1)/256;
TL0 = (t_change + t_up0 +error1)%256;

t0_flag = 2;
}
else if(t0_flag == 2)
{
PWM1 = 1;
TH0 = (num_max - t_up1 + error2)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up1 + error2)%256;

t0_flag = 3;
}
else if(t0_flag == 3)
{
PWM1 = 0;
TH0 = (t_change + t_up1 +error3)/256;
TL0 = (t_change + t_up1 +error3)%256;

t0_flag = 4;
}
else if(t0_flag == 4)
{
PWM2 = 1;
TH0 = (num_max - t_up2 + error4)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up2 + error4)%256;

t0_flag = 5;
}
else if(t0_flag == 5)
{
PWM2 = 0;
TH0 = (t_change + t_up2 +error5)/256;
TL0 = (t_change + t_up2 +error5)%256;

t0_flag = 6;
}
else if(t0_flag == 6)
{
PWM3 = 1;
TH0 = (num_max - t_up3 + error6)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up3 + error6)%256;

t0_flag = 7;
}
else if(t0_flag == 7)
{
PWM3 = 0;
TH0 = (t_change + t_up3 +error7)/256;
TL0 = (t_change + t_up3 +error7)%256;

t0_flag = 8;
}
else if(t0_flag == 8)
{
PWM4 = 1;
TH0 = (num_max - t_up4 + error8)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up4 + error8)%256;

t0_flag = 9;
}
else if(t0_flag == 9)
{
PWM4 = 0;
TH0 = (t_change + t_up4 +error9)/256;
TL0 = (t_change + t_up4 +error9)%256;

t0_flag = 10;
}
else if(t0_flag == 10)
{
PWM5 = 1;
TH0 = (num_max - t_up5 + error10)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up5 + error10)%256;

t0_flag = 11;
}
else if(t0_flag == 11)
{
PWM5 = 0;
TH0 = (t_change + t_up5 + error11)/256;
TL0 = (t_change + t_up5 + error11)%256;

t0_flag = 12;
}
else if(t0_flag == 12)
{
PWM6 = 1;
TH0 = (num_max - t_up6 + error12)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up6 + error12)%256;

t0_flag = 13;
}
else if(t0_flag == 13)
{
PWM6 = 0;
TH0 = (t_change + t_up6 + error13)/256;
TL0 = (t_change + t_up6 + error13)%256;

t0_flag = 14;
}
else if(t0_flag == 14)
{
PWM7 = 1;
TH0 = (num_max - t_up7 + error14)/256; //+?是为了抵消执行语句花的时间
TL0 = (num_max - t_up7 + error14)%256;

t0_flag = 15;
}
else if(t0_flag == 15)
{
PWM7 = 0;
TH0 = (t_change + t_up7 + error15)/256;
TL0 = (t_change + t_up7 + error15)%256;

t0_flag = 0;
}

}
void main()
{
uint t_while;
timer\_init();//定时器0初始化
TR0 = 1;
while(1)
{

if(ADD == 0)
{
delayms(2);
if(ADD == 0)
{
if(t_up0 <= 1950)
{
t_up0 = t_up0 + 50;
t_up1 = t_up1 + 50;
t_up2 = t_up2 + 50;
t_up3 = t_up3 + 50;
t_up4 = t_up4 + 50;
t_up5 = t_up5 + 50;
t_up6 = t_up6 + 50;
t_up7 = t_up7 + 50;
}

t_while = 50000;
while(t_while--)
{
if(ADD == 1)
break;
}

}
}

if(SUB == 0)
{
delayms(2);
if(SUB == 0)
{
if(t_up0 >= 1050)
{
t_up0 = t_up0 - 50;
t_up1 = t_up1 - 50;
t_up2 = t_up2 - 50;
t_up3 = t_up3 - 50;
t_up4 = t_up4 - 50;
t_up5 = t_up5 - 50;
t_up6 = t_up6 - 50;
t_up7 = t_up7 - 50;
}

t_while = 50000;
while(t_while--)
{
if(SUB == 1)
break;
}

}
}
}

}


程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/177TsloaIYH0yr3LfAlOxzQ 
提取码:w1s4