📄 pidmotor.lst
字号:
194 {
195 1 int Error;
196 1 int Control_i;
197 1
198 1 // Get the current speed value (0-255)
199 1 Speed_measured_G = PID_MOTOR_Read_Current_Speed();
200 1
201 1 // Get the desired speed value (0-255)
202 1 Speed_required_G =
203 1 PID_MOTOR_Get_Required_Speed();
204 1
205 1 if (++Ticks == 100)
206 1 {
207 2 Speed_required_G = 200;
208 2 }
209 1
210 1 // Difference between required and actual speed (0-255)
211 1 Error = Speed_required_G - Speed_measured_G;
212 1
213 1 // Proportional term
214 1 Control_i = Controller_output_G + (Error / PID_PROPORTIONAL);
215 1
216 1 // Integral term [SET TO 0 IF NOT REQUIRED]
217 1 if (PID_INTEGRAL)
218 1 {
219 2 Sum_G += Error;
220 2 Control_i += (Sum_G / (1 + PID_INTEGRAL));
221 2 }
222 1
223 1 // Differential term [SET TO 0 IF NOT REQUIRED]
224 1 if (PID_DIFFERENTIAL)
225 1 {
226 2 Control_i += (Error - Old_error_G) / (1 + PID_DIFFERENTIAL);
227 2
228 2 // Store error value
229 2 Old_error_G = Error;
230 2 }
231 1
232 1 // Adjust to 8-bit range
233 1 if (Control_i > 255)
234 1 {
235 2 Control_i = 255;
236 2 Sum_G -= Error; // Windup protection
237 2 }
238 1
239 1 if (Control_i < 0)
240 1 {
241 2 Control_i = 0;
C51 COMPILER V8.08 PIDMOTOR 06/30/2007 15:58:44 PAGE 5
242 2 Sum_G -= Error; // Windup protection
243 2 }
244 1
245 1 // Convert to required 8-bit format
246 1 Controller_output_G = (tByte) Control_i;
247 1
248 1 // Update the PWM setting
249 1 PID_MOTOR_Set_New_PWM_Output(Controller_output_G);
250 1
251 1 // Update display
252 1 PID_MOTOR_data_G[4] = CHAR_MAP_G[Speed_measured_G / 100];
253 1 PID_MOTOR_data_G[5] = CHAR_MAP_G[(Speed_measured_G % 100) / 10];
254 1 PID_MOTOR_data_G[6] = CHAR_MAP_G[Speed_measured_G % 10];
255 1
256 1 PID_MOTOR_data_G[12] = CHAR_MAP_G[Speed_required_G / 100];
257 1 PID_MOTOR_data_G[13] = CHAR_MAP_G[(Speed_required_G % 100) / 10];
258 1 PID_MOTOR_data_G[14] = CHAR_MAP_G[Speed_required_G % 10];
259 1
260 1 PID_MOTOR_data_G[20] = CHAR_MAP_G[Controller_output_G / 100];
261 1 PID_MOTOR_data_G[21] = CHAR_MAP_G[(Controller_output_G % 100) / 10];
262 1 PID_MOTOR_data_G[22] = CHAR_MAP_G[Controller_output_G % 10];
263 1
264 1 PC_LINK_O_Write_String_To_Buffer(PID_MOTOR_data_G);
265 1 }
266
267 /*------------------------------------------------------------------*-
268
269 PID_MOTOR_Get_Required_Speed()
270
271 Get the required speed via the Pot and ADC.
272
273 -*------------------------------------------------------------------*/
274 tByte PID_MOTOR_Get_Required_Speed(void)
275 {
276 1 // Take sample from A-D
277 1
278 1 // Write (value not important) to ADDATL to start conversion
279 1 ADDATL = 0x01;
280 1
281 1 // Wait for conversion to complete
282 1 // NOTE: This demo software has no timeout...
283 1 while (BSY == 1);
284 1
285 1 // 10-bit A-D result is now available
286 1 // return 8-bit result
287 1 return ADDATH;
288 1 }
289
290 /*------------------------------------------------------------------*-
291
292 PID_MOTOR_Set_New_PWM_Output()
293
294 Adjust the PWM output value.
295
296 -*------------------------------------------------------------------*/
297 void PID_MOTOR_Set_New_PWM_Output(const tByte Controller_output_G)
298 {
299 1 // Changing value in CCL1 to generate appropriate PWM duty cycle
300 1 CCL1 = Controller_output_G;
301 1 }
302
303
C51 COMPILER V8.08 PIDMOTOR 06/30/2007 15:58:44 PAGE 6
304 /*------------------------------------------------------------------*-
305
306 PID_MOTOR_Read_Current_Speed()
307
308 Schedule this function at regular intervals.
309
310 Remember: max count is 65536 (16-bit counter)
311 - it is your responsibility to ensure this count
312 is not exceeded. Choose an appropriate schedule
313 interval and allow a margin for error.
314
315 For high-frequency pulses, you need to take account of
316 the fact that the count is stop for a (very brief) period,
317 to read the counter.
318
319 Note: the delay before the first count is taken should
320 generally be the same as the inter-count interval,
321 to ensure that the first count is as accurate as possible.
322
323 For example, this is OK:
324
325 Sch_Add_Task(PID_MOTOR_Read_Current_Speed, 1000, 1000);
326
327 While this will give a very low first count:
328
329 Sch_Add_Task(PID_MOTOR_Read_Current_Speed, 0, 1000);
330
331 -*------------------------------------------------------------------*/
332
333 tByte PID_MOTOR_Read_Current_Speed(void)
334 {
335 1 int C;
336 1 tByte Count = Pulse_count_G;
337 1
338 1 Pulse_count_G = 0;
339 1
340 1 // Normalised: 0 -> 255
341 1 C = 9 * ((int) Count - 28);
342 1
343 1 if (C < 0)
344 1 {
345 2 C = 0;
346 2 }
347 1
348 1 if (C > 255)
349 1 {
350 2 C = 255;
351 2 }
352 1
353 1 return (tByte) C;
354 1 }
355
356 /*------------------------------------------------------------------*-
357
358 PID_MOTOR_Poll_Speed_Pulse()
359
360 Using software to count falling edges on a specified pin
361 - T0 is *NOT* used here.
362
363 -*------------------------------------------------------------------*/
364 void PID_MOTOR_Poll_Speed_Pulse(void)
365 {
C51 COMPILER V8.08 PIDMOTOR 06/30/2007 15:58:44 PAGE 7
366 1 static bit Previous_state;
367 1 bit Current_state = Pulse_count_pin;
368 1
369 1 if ((Previous_state == PULSE_HIGH) && (Current_state == PULSE_LOW))
370 1 {
371 2 Pulse_count_G++;
372 2 }
373 1
374 1 Previous_state = Current_state;
375 1 }
376
377 /*------------------------------------------------------------------*-
378 ---- END OF FILE -------------------------------------------------
379 -*------------------------------------------------------------------*/
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 457 ----
CONSTANT SIZE = 26 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 60 3
IDATA SIZE = ---- ----
BIT SIZE = 1 1
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -