📄 scu_am.lst
字号:
232 1 // All operational slaves will now be in the 'READY TO START' state
233 1 // Send them a (single-byte) message to get them started
234 1 // DO THIS TWICE IN A ROW, WITH COMMAND BIT
235 1 // This cannot happen under normal circumstances
236 1 Slave_index = 0;
237 1 do {
238 2 // Refresh the watchdog
239 2 SCU_A_MASTER_Watchdog_Refresh();
240 2
241 2 // Clear 'first byte' flag
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 5
242 2 First_byte = 0;
243 2
244 2 // Find the slave ID for this slave
245 2 Slave_ID = (tByte) Current_Slave_IDs_G[Slave_index];
246 2
247 2 // Send a 'Slave ID' message
248 2 TI = 0;
249 2 TB8 = 1; // Set command bit
250 2 SBUF = Slave_ID;
251 2
252 2 // Wait to give slave time to reply
253 2 Hardware_Delay_T0(5);
254 2
255 2 // Check we had a reply
256 2 if (RI == 1)
257 2 {
258 3 // Get the reply data
259 3 Id = (tByte) SBUF;
260 3 RI = 0;
261 3
262 3 // Check reply - with command bit
263 3 if ((Id == Slave_ID) && (RB8 == 1))
264 3 {
265 4 First_byte = 1;
266 4 }
267 3 }
268 2
269 2 // Send second byte
270 2 TI = 0;
271 2 TB8 = 1;
272 2 SBUF = Slave_ID;
273 2
274 2 // Wait to give slave time to reply
275 2 Hardware_Delay_T0(5);
276 2
277 2 // Check we had a reply
278 2 Slave_replied_correctly = 0;
279 2 if (RI != 0)
280 2 {
281 3 // Get the reply data
282 3 Id = (tByte) SBUF;
283 3 RI = 0;
284 3
285 3 if ((Id == Slave_ID) && (RB8 == 1) && (First_byte == 1))
286 3 {
287 4 Slave_replied_correctly = 1;
288 4 }
289 3 }
290 2
291 2 if (Slave_replied_correctly)
292 2 {
293 3 // Slave responded correctly
294 3 Num_active_slaves++;
295 3 Slave_index++;
296 3 }
297 2 else
298 2 {
299 3 // Slave did not reply correctly
300 3 // - try to switch to backup device (if available)
301 3 if (Current_Slave_IDs_G[Slave_index] != BACKUP_SLAVE_IDs[Slave_index])
302 3 {
303 4 // There is a backup available: switch to backup and try again
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 6
304 4 Current_Slave_IDs_G[Slave_index] = BACKUP_SLAVE_IDs[Slave_index];
305 4 }
306 3 else
307 3 {
308 4 // No backup available (or backup failed too) - have to continue
309 4 // NOTE: we don't abort the loop, to allow for more flexible
310 4 // error handling (below).
311 4 Slave_index++;
312 4 }
313 3 }
314 2 } while (Slave_index < NUMBER_OF_SLAVES);
315 1
316 1 // DEAL WITH CASE OF MISSING SLAVE(S) HERE ...
317 1 if (Num_active_slaves < NUMBER_OF_SLAVES)
318 1 {
319 2 // User-defined error handling here...
320 2 // 1 or more slaves have not replied
321 2 // NOTE: In some circumstances you may wish to abort if slaves are missing
322 2 // - or reconfigure the network.
323 2
324 2 // Here we display error and shut down the network
325 2 Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
326 2 SCU_A_MASTER_Shut_Down_the_Network();
327 2 }
328 1 else
329 1 {
330 2 Error_code_G = 0;
331 2 Network_error_pin = NO_NETWORK_ERROR;
332 2 }
333 1
334 1 // Get ready to send first tick message
335 1 Message_byte_G = 1;
336 1 First_ack_G = 1;
337 1 Current_slave_index_G = 0;
338 1
339 1 // Start the scheduler
340 1 EA = 1;
341 1 }
342
343
344 /*------------------------------------------------------------------*-
345
346 SCU_A_MASTER_Update_T2
347
348 This is the scheduler ISR. It is called at a rate determined by
349 the timer settings in SCU_A_MASTER_Init_T2(). This version is
350 triggered by Timer 2 interrupts: timer is automatically reloaded.
351
352 -*------------------------------------------------------------------*/
353 void SCU_A_MASTER_Update_T2(void) interrupt INTERRUPT_Timer_2_Overflow
354 {
355 1 tByte Task_index;
356 1 tByte Previous_slave_index;
357 1
358 1 TF2 = 0; // Must manually clear this.
359 1
360 1 // Refresh the watchdog
361 1 SCU_A_MASTER_Watchdog_Refresh();
362 1
363 1 // Default
364 1 Network_error_pin = NO_NETWORK_ERROR;
365 1
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 7
366 1 // Keep track of the current slave
367 1 // FIRST VALUE IS 0
368 1 Previous_slave_index = Current_slave_index_G;
369 1
370 1 // Assume 2-byte messages sent and received
371 1 // - it takes two ticks to deliver each message
372 1 if (Message_byte_G == 0)
373 1 {
374 2 Message_byte_G = 1;
375 2 }
376 1 else
377 1 {
378 2 Message_byte_G = 0;
379 2
380 2 if (++Current_slave_index_G >= NUMBER_OF_SLAVES)
381 2 {
382 3 Current_slave_index_G = 0;
383 3 }
384 2 }
385 1
386 1 // Check that the appropriate slave responded to the previous message:
387 1 // (if it did, store the data sent by this slave)
388 1 if (SCU_A_MASTER_Process_Ack(Previous_slave_index) == RETURN_ERROR)
389 1 {
390 2 Network_error_pin = NETWORK_ERROR;
391 2 Error_code_G = ERROR_SCH_LOST_SLAVE;
392 2
393 2 // If we have lost contact with a slave, we attempt to
394 2 // switch to a backup device (if one is available) as we reset the network
395 2 //
396 2 // NOTE: We don't do this every tick (or the the network will be constantly reset)
397 2 //
398 2 // Choose a value of SLAVE_RESET_INTERVAL to allow resets (say) every 5 seconds
399 2 if (++Slave_reset_attempts_G[Previous_slave_index] >= SLAVE_RESET_INTERVAL)
400 2 {
401 3 SCU_A_MASTER_Reset_the_Network();
402 3 }
403 2 }
404 1 else
405 1 {
406 2 // Reset this counter
407 2 Slave_reset_attempts_G[Previous_slave_index] = 0;
408 2 }
409 1
410 1 // Send 'tick' message to all connected slaves
411 1 // (sends one data byte to the current slave)
412 1 SCU_A_MASTER_Send_Tick_Message(Current_slave_index_G);
413 1
414 1 // NOTE: calculations are in *TICKS* (not milliseconds)
415 1 for (Task_index = 0; Task_index < SCH_MAX_TASKS; Task_index++)
416 1 {
417 2 // Check if there is a task at this location
418 2 if (SCH_tasks_G[Task_index].pTask)
419 2 {
420 3 if (SCH_tasks_G[Task_index].Delay == 0)
421 3 {
422 4 // The task is due to run
423 4 SCH_tasks_G[Task_index].RunMe += 1; // Increment the run flag
424 4
425 4 if (SCH_tasks_G[Task_index].Period)
426 4 {
427 5 // Schedule periodic tasks to run again
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 8
428 5 SCH_tasks_G[Task_index].Delay = SCH_tasks_G[Task_index].Period;
429 5 }
430 4 }
431 3 else
432 3 {
433 4 // Not yet ready to run: just decrement the delay
434 4 SCH_tasks_G[Task_index].Delay -= 1;
435 4 }
436 3 }
437 2 }
438 1 }
439
440 /*------------------------------------------------------------------*-
441
442 SCU_A_MASTER_Send_Tick_Message()
443
444 This function sends a tick message, over the USART network.
445 The receipt of this message will cause an interrupt to be generated
446 in the slave(s): this invoke the scheduler 'update' function
447 in the slave(s).
448
449 -*------------------------------------------------------------------*/
450 void SCU_A_MASTER_Send_Tick_Message(const tByte SLAVE_INDEX)
451 {
452 1 tLong Timeout;
453 1
454 1 // Find the slave ID for this slave
455 1 tByte Slave_ID = (tByte) Current_Slave_IDs_G[SLAVE_INDEX];
456 1
457 1 // Sending one byte of data at a time, depending on index value
458 1 // If Message_byte_G is 0, send first byte (the slave ID)
459 1 if (Message_byte_G == 0)
460 1 {
461 2 Timeout = 0;
462 2 while ((++Timeout) && (TI == 0));
463 2
464 2 if (Timeout == 0)
465 2 {
466 3 // UART did not respond - error
467 3 Error_code_G = ERROR_USART_TI;
468 3 return;
469 3 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -