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