⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scc_m515.lst

📁 时间触发嵌入式系统设计模式:使用8051系列微控制器开发可靠应用
💻 LST
📖 第 1 页 / 共 5 页
字号:
 278          /*------------------------------------------------------------------*-
 279          
 280            SCC_A_MASTER_Start()
 281          
 282            Starts the scheduler, by enabling interrupts.
 283          
 284            NOTE: Usually called after all regular tasks are added,
 285            to keep the tasks synchronised.
 286          
 287            NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!! 
 288          
 289          -*------------------------------------------------------------------*/
 290          void SCC_A_MASTER_Start(void) 
 291             {
 292   1         tByte Num_active_slaves;
 293   1         tByte i;
 294   1         bit Slave_replied_correctly;
 295   1         tByte Slave_index, Slave_ID;
 296   1      
 297   1         // Refresh the watchdog
 298   1         SCC_A_MASTER_Watchdog_Refresh();
 299   1      
 300   1         // Place system in 'safe state'
 301   1         SCC_A_MASTER_Enter_Safe_State();
 302   1      
 303   1         // Report error as we wait to start
 304   1         Network_error_pin = NETWORK_ERROR;
 305   1      
 306   1         Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
 307   1         SCH_Report_Status(); // Sch not yet running - do this manually
 308   1      
 309   1         // Pause here (300 ms), to time-out all the slaves
 310   1         // (This is the means by which we synchronise the network)
 311   1         for (i = 0; i < 10; i++)
 312   1            {
 313   2            Hardware_Delay_T0(30);
C51 COMPILER V6.10  SCC_M515                                                               04/19/2001 14:10:31 PAGE 20  

 314   2            SCC_A_MASTER_Watchdog_Refresh();
 315   2            }     
 316   1      
 317   1         // Currently disconnected from all slaves
 318   1         Num_active_slaves = 0;
 319   1      
 320   1         // After the initial (long) delay, all (operational) slaves will have timed out.
 321   1         // All operational slaves will now be in the 'READY TO START' state
 322   1         // Send them a 'slave id' message to get them started
 323   1         Slave_index = 0;
 324   1         do {
 325   2            // Refresh the watchdog
 326   2            SCC_A_MASTER_Watchdog_Refresh();
 327   2      
 328   2            // Find the slave ID for this slave 
 329   2            Slave_ID = (tByte) Current_Slave_IDs_G[Slave_index]; 
 330   2      
 331   2            Slave_replied_correctly = SCC_A_MASTER_Start_Slave(Slave_ID);
 332   2      
 333   2            if (Slave_replied_correctly)
 334   2               {
 335   3               Num_active_slaves++;
 336   3               Slave_index++;
 337   3               }
 338   2            else
 339   2               {
 340   3               // Slave did not reply correctly 
 341   3               // - try to switch to backup device (if available)
 342   3               if (Current_Slave_IDs_G[Slave_index] != BACKUP_SLAVE_IDs[Slave_index])
 343   3                  {
 344   4                  // There is a backup available: switch to backup and try again
 345   4                  Current_Slave_IDs_G[Slave_index] = BACKUP_SLAVE_IDs[Slave_index];
 346   4                  }
 347   3               else
 348   3                  {
 349   4                  // No backup available (or backup failed too) - have to continue
 350   4                  Slave_index++;
 351   4                  }
 352   3               }
 353   2            } while (Slave_index < NUMBER_OF_SLAVES);
 354   1      
 355   1         // DEAL WITH CASE OF MISSING SLAVE(S) HERE ...
 356   1         if (Num_active_slaves < NUMBER_OF_SLAVES)
 357   1            {
 358   2            // User-defined error handling here...
 359   2            // 1 or more slaves have not replied
 360   2            // NOTE: In some circumstances you may wish to abort if slaves are missing
 361   2            // - or reconfigure the network.
 362   2      
 363   2            // Simplest solution is to display an error and carry on
 364   2            // (this is what we do here)      
 365   2            Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
 366   2            Network_error_pin = NETWORK_ERROR;
 367   2            }
 368   1         else
 369   1            {
 370   2            Error_code_G = 0;
 371   2            Network_error_pin = NO_NETWORK_ERROR;
 372   2            }
 373   1      
 374   1         // Start the scheduler
 375   1         IRCON = 0;
C51 COMPILER V6.10  SCC_M515                                                               04/19/2001 14:10:31 PAGE 21  

 376   1         EAL = 1;   
 377   1         }
 378          
 379          /*------------------------------------------------------------------*-
 380          
 381            SCC_A_MASTER_Update_T2
 382          
 383            This is the scheduler ISR.  It is called at a rate determined by 
 384            the timer settings in SCC_A_MASTER_Init_T2().  This version is 
 385            triggered by Timer 2 interrupts: timer is automatically reloaded.
 386           
 387          -*------------------------------------------------------------------*/
 388          void SCC_A_MASTER_Update_T2(void) interrupt INTERRUPT_Timer_2_Overflow  
 389             {
 390   1         tByte Index;
 391   1         tByte Previous_slave_index;
 392   1         bit Slave_replied_correctly;
 393   1      
 394   1         TF2 = 0;  // Must clear this. 
 395   1      
 396   1         // Refresh the watchdog
 397   1         SCC_A_MASTER_Watchdog_Refresh();
 398   1      
 399   1         // Default
 400   1         Network_error_pin = NO_NETWORK_ERROR;
 401   1      
 402   1         // Keep track of the current slave
 403   1         Previous_slave_index = Slave_index_G;   // First value of prev slave is 0...
 404   1      
 405   1         if (++Slave_index_G >= NUMBER_OF_SLAVES)
 406   1            {
 407   2            Slave_index_G = 0;
 408   2            }    
 409   1      
 410   1         // Check that the appropriate slave responded to the previous message:
 411   1         // (if it did, store the data sent by this slave)
 412   1         if (SCC_A_MASTER_Process_Ack(Previous_slave_index) == RETURN_ERROR)
 413   1            {
 414   2            Error_code_G = ERROR_SCH_LOST_SLAVE;
 415   2            Network_error_pin = NETWORK_ERROR;
 416   2      
 417   2            // If we have lost contact with a slave, we attempt to
 418   2            // switch to a backup device (if one is available)
 419   2            if (Current_Slave_IDs_G[Slave_index_G] != BACKUP_SLAVE_IDs[Slave_index_G])
 420   2               {
 421   3               // There is a backup available: switch to backup and try again
 422   3               Current_Slave_IDs_G[Slave_index_G] = BACKUP_SLAVE_IDs[Slave_index_G];
 423   3               }
 424   2            else
 425   2               {
 426   3               // There is no backup available (or we are already using it) 
 427   3               // Try main device.
 428   3               Current_Slave_IDs_G[Slave_index_G] = MAIN_SLAVE_IDs[Slave_index_G];
 429   3               }
 430   2      
 431   2            // Try to connect to the slave
 432   2            Slave_replied_correctly = SCC_A_MASTER_Start_Slave(Current_Slave_IDs_G[Slave_index_G]);
 433   2      
 434   2            if (!Slave_replied_correctly)
 435   2               {
 436   3               // No backup available (or backup failed too) - we shut down
 437   3               // OTHER BEHAVIOUR MAY BE MORE APPROPRIATE IN YOUR APPLICATION
C51 COMPILER V6.10  SCC_M515                                                               04/19/2001 14:10:31 PAGE 22  

 438   3               SCC_A_MASTER_Shut_Down_the_Network();
 439   3               }
 440   2            }
 441   1        
 442   1         // Send 'tick' message to all connected slaves
 443   1         // (sends one data byte to the current slave)
 444   1         SCC_A_MASTER_Send_Tick_Message(Slave_index_G);
 445   1      
 446   1         // Check the last error codes on the CAN bus via the status register
 447   1         if ((CAN_sr & 0x07) != 0)
 448   1            {
 449   2            Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
 450   2            Network_error_pin = NETWORK_ERROR;
 451   2         
 452   2            // See Infineon c515c manual for error code details
 453   2            CAN_error_pin0 = ((CAN_sr & 0x01) == 0);
 454   2            CAN_error_pin1 = ((CAN_sr & 0x02) == 0);
 455   2            CAN_error_pin2 = ((CAN_sr & 0x04) == 0);
 456   2            }
 457   1         else
 458   1            {
 459   2            CAN_error_pin0 = 1;
 460   2            CAN_error_pin1 = 1;
 461   2            CAN_error_pin2 = 1;
 462   2            }
 463   1      
 464   1         // NOTE: calculations are in *TICKS* (not milliseconds)
 465   1         for (Index = 0; Index < SCH_MAX_TASKS; Index++)
 466   1            {
 467   2            // Check if there is a task at this location
 468   2            if (SCH_tasks_G[Index].pTask)
 469   2               {
 470   3               if (SCH_tasks_G[Index].Delay == 0)
 471   3                  {
 472   4                  // The task is due to run
 473   4                  SCH_tasks_G[Index].RunMe += 1;  // Incr. the 'Run Me' flag
 474   4      
 475   4                  if (SCH_tasks_G[Index].Period)
 476   4                     {
 477   5                     // Schedule rperiodic tasks to run again
 478   5                     SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
 479   5                     }
 480   4                  }
 481   3               else
 482   3                  {
 483   4                  // Not yet ready to run: just decrement the delay 
 484   4                  SCH_tasks_G[Index].Delay -= 1;
 485   4                  }
 486   3               }         
 487   2            }
 488   1         }   
 489          
 490          /*------------------------------------------------------------------*-
 491          
 492            SCC_A_MASTER_Send_Tick_Message()
 493          
 494            This function sends a tick message, over the CAN network.
 495            The receipt of this message will cause an interrupt to be generated
 496            in the slave(s): this invoke the scheduler 'update' function
 497            in the slave(s).
 498          
 499          -*------------------------------------------------------------------*/
C51 COMPILER V6.10  SCC_M515                                                               04/19/2001 14:10:31 PAGE 23  

 500          void SCC_A_MASTER_Send_Tick_Message(const tByte SLAVE_INDEX) 
 501             {
 502   1         // Find the slave ID for this slave 
 503   1         // ALL SLAVES MUST HAVE A UNIQUE (non-zero) ID
 504   1         tByte Slave_ID = (tByte) Current_Slave_IDs_G[SLAVE_INDEX];
 505   1         CAN_messages[0].Data[0] = Slave_ID;   
 506   1      
 507   1         // Fill the data fields 
 508   1         CAN_messages[0].Data[1] = Tick_message_data_G[SLAVE_INDEX][0];   
 509   1         CAN_messages[0].Data[2] = Tick_message_data_G[SLAVE_INDEX][1];   
 510   1         CAN_messages[0].Data[3] = Tick_message_data_G[SLAVE_INDEX][2];   
 511   1         CAN_messages[0].Data[4] = Tick_message_data_G[SLAVE_INDEX][3];   
 512   1      
 513   1         // Send the message on the CAN bus
 514   1         CAN_messages[0].MCR1 = 0xE7;  // TXRQ, reset CPUUPD
 515   1         }
 516          
 517          /*------------------------------------------------------------------*-
 518          
 519            SCC_A_MASTER_Process_Ack()
 520          
 521            Make sure the slave (SLAVE_ID) has acknowledged the previous
 522            message that was sent.  If it has, extract the message data
 523            from the USART hardware: if not, call the appropriate error
 524            handler.
 525          
 526            PARAMS:   The index of the slave. 
 527          
 528            RETURNS:  RETURN_NORMAL - Ack received (data in Ack_message_data_G)
 529                      RETURN_ERROR  - No ack received (-> no data)
 530          
 531          -*------------------------------------------------------------------*/
 532          
 533          bit SCC_A_MASTER_Process_Ack(const tByte SLAVE_INDEX) 
 534             {
 535   1         tByte Ack_ID, Slave_ID;
 536   1      
 537   1         // First time this is called there is no ack tick to check 
 538   1         // - we simply return 'OK'
 539   1         if (First_ack_G)
 540   1            {
 541   2            First_ack_G = 0;
 542   2            return RETURN_NORMAL;
 543   2            }
 544   1      
 545   1         if ((CAN_messages[1].MCR1 & 0x03) == 0x02)    // if NEWDAT
 546   1            {
 547   2            // An ack message was received
 548   2            //
 549   2            // Extract the data
 550   2            Ack_ID = CAN_messages[1].Data[0];   // Get data byte 0
 551   2      
 552   2            Ack_message_data_G[SLAVE_INDEX][0] = CAN_messages[1].Data[1];   
 553   2            Ack_message_data_G[SLAVE_INDEX][1] = CAN_messages[1].Data[2];   
 554   2            Ack_message_data_G[SLAVE_INDEX][2] = CAN_messages[1].Data[3];   
 555   2            Ack_message_data_G[SLAVE_INDEX][3] = CAN_messages[1].Data[4];   
 556   2      
 557   2            CAN_messages[1].MCR0 = 0xfd;  // reset NEWDAT, INTPND
 558   2            CAN_messages[1].MCR1 = 0xfd;
 559   2            
 560   2            // Find the slave ID for this slave 
 561   2            Slave_ID = (tByte) Current_Slave_IDs_G[SLAVE_INDEX];
C51 COMPILER V6.10  SCC_M515                                                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -