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

📄 scc_s515.c

📁 基于8051共享时钟调度器的can总线通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------*-

   SCC_S515.c (v1.00)

  ------------------------------------------------------------------

   THIS IS A SHARED-SCHEDULER [CAN BASED] FOR 80C515C (etc.) 

   *** Both Master and Slave share the same tick rate ***
   *** - See Master code for details ***

   -----------------------------------------------------------
   --- NOTE: 'Idle mode' must be disabled (in Sch51.C)     ---
   --- or the on-chip watchdog will not function correctly ---
   -----------------------------------------------------------


   COPYRIGHT
   ---------

   This code is from the book:

   PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont 
   [Pearson Education, 2001; ISBN: 0-201-33138-1].

   This code is copyright (c) 2001 by Michael J. Pont.
 
   See book for copyright details and other information.

-*------------------------------------------------------------------*/

#include "Main.h"
#include "Port.h"

#include "SCC_S515.h"
#include "TLight_B.h"

// ------ Public variable definitions ------------------------------

// Data sent from the master to this slave
tByte Tick_message_data_G[4];

// Data sent from this slave to the master 
// - data may be sent on, by the master, to another slave  
tByte Ack_message_data_G[4] = {'1','1','1','1'}; 

// ------ Public variable declarations -----------------------------

// The array of tasks (see Sch51.c)
extern sTask SCH_tasks_G[SCH_MAX_TASKS];

// The error code variable (see Sch51.c)
extern tByte Error_code_G;

// ------ Private function prototypes ------------------------------
static void  SCC_A_SLAVE_Enter_Safe_State(void);

static void  SCC_A_SLAVE_Send_Ack_Message_To_Master(void);
static tByte SCC_A_SLAVE_Process_Tick_Message(void);

static bit   SCC_A_SLAVE_Read_Command_Bit(const tByte);
static tByte SCC_A_SLAVE_Set_Command_Bit(const tByte);
static tByte SCC_A_SLAVE_Read_Message_ID(const tByte);

static void  SCC_A_SLAVE_Watchdog_Init(void);
static void  SCC_A_SLAVE_Watchdog_Refresh(void) reentrant;


// ------ Private constants ----------------------------------------

// Each slave (and backup) must have a unique (non-zero) ID 
#define SLAVE_ID 0x01

#define NO_NETWORK_ERROR (1) 
#define NETWORK_ERROR (0)

/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Init_CAN()

  Scheduler initialisation function.  Prepares scheduler
  data structures and sets up timer interrupts at required rate.
  Must call this function before using the scheduler.  

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Init_CAN(void) 
   {
   tByte i;
   tByte Message;

   // Sort out the tasks
   for (i = 0; i < SCH_MAX_TASKS; i++) 
      {
      SCH_Delete_Task(i);
      }

   // Reset the global error variable
   // - SCH_Delete_Task() will generate an error code, 
   //   (because the task array is empty)
   Error_code_G = 0;

   // Set the network error pin (reset when tick message received)
   Network_error_pin = NETWORK_ERROR;

   // ------ SYSCON Register 
   // The access to XRAM and CAN controller is enabled.
   // The signals !RD and !WR are not activated during accesses
   // to the XRAM/CAN controller.
   // ALE generation is enabled.
   SYSCON = 0x20;  
  
   //  ------------ CAN Control/Status Register --------------
   //  Start to init the CAN module
   CAN_cr  = 0x41;  // INIT and CCE

   //  ------------ Bit Timing Register ---------------------
   // Baudrate = 333.333 kbaud 
   // - Need 308+ kbaud plus for 1ms ticks, 8 data bytes
   // - See text for details  
   //
   // There are 5 time quanta before sample point
   // There are 4 time quanta after sample point
   // The (re)synchronization jump width is 2 time quanta
   CAN_btr1  = 0x34;  // Bit Timing Register
   CAN_btr0  = 0x42; 

   CAN_gms1  = 0xFF;  // Global Mask Short Register 1
   CAN_gms0  = 0xFF;  // Global Mask Short Register 0

   CAN_ugml1 = 0xFF;  // Upper Global Mask Long Register 1
   CAN_ugml0 = 0xFF;  // Upper Global Mask Long Register 0

   CAN_lgml1 = 0xF8;  // Lower Global Mask Long Register 1
   CAN_lgml0 = 0xFF;  // Lower Global Mask Long Register 0

   //  ------ Configure 'Tick' Message Object 
   //  Message object 1 is valid
   //  enable receive interrupt
   CAN_messages[0].MCR1 = 0x55;    // Message Ctrl. Reg. 1
   CAN_messages[0].MCR0 = 0x99;    // Message Ctrl. Reg. 0

   //  message direction is receive
   //  extended 29-bit identifier
   CAN_messages[0].MCFG = 0x04;    // Message Config. Reg.

   CAN_messages[0].UAR1 = 0x00;    // Upper Arbit. Reg. 1
   CAN_messages[0].UAR0 = 0x00;    // Upper Arbit. Reg. 0
   CAN_messages[0].LAR1 = 0x00;    // Lower Arbit. Reg. 1
   CAN_messages[0].LAR0 = 0x00;    // Lower Arbit. Reg. 0


   //  ------ Configure 'Ack' Message Object 
   CAN_messages[1].MCR1 = 0x55;    // Message Ctrl. Reg. 1
   CAN_messages[1].MCR0 = 0x95;    // Message Ctrl. Reg. 0

   // Message direction is transmit
   // extended 29-bit identifier
   // 5 valid data bytes
   CAN_messages[1].MCFG = 0x5C;      // Message Config. Reg.

   CAN_messages[1].UAR1 = 0x00;    // Upper Arbit. Reg. 1
   CAN_messages[1].UAR0 = 0x00;    // Upper Arbit. Reg. 0
   CAN_messages[1].LAR1 = 0xF8;    // Lower Arbit. Reg. 1
   CAN_messages[1].LAR0 = 0x07;    // Lower Arbit. Reg. 0

   CAN_messages[1].Data[0] = 0x00;   // data byte 0
   CAN_messages[1].Data[1] = 0x00;   // data byte 1
   CAN_messages[1].Data[2] = 0x00;   // data byte 2
   CAN_messages[1].Data[3] = 0x00;   // data byte 3
   CAN_messages[1].Data[4] = 0x00;   // data byte 4

   //  ------ Configure other objects ------------------------------
   // Configure remaining message objects (2-14) - none are valid
   for (Message = 2; Message <= 14; ++Message)
      {
      CAN_messages[Message].MCR1 = 0x55;  // Message Ctrl. Reg. 1
      CAN_messages[Message].MCR0 = 0x55;  // Message Ctrl. Reg. 0
      }

   // ------------ CAN Ctrl. Reg. ---------------------
   //  reset CCE and INIT
   // enable interrupt generation from CAN Modul
   // enable CAN-interrupt of Controller
   CAN_cr = 0x02;
   IEN2 |= 0x02;

   // Start the watchdog
   SCC_A_SLAVE_Watchdog_Init();  
   }

/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Start()

  Starts the slave scheduler, by enabling interrupts.

  NOTE: Usually called after all regular tasks are added,
  to keep the tasks synchronised.

  NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!! 

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Start(void) 
   {
   tByte Tick_00, Tick_ID;
   bit Start_slave;

   // Disable interrupts 
   EAL = 0;

   // We can be at this point because:
   // 1. The network has just been powered up
   // 2. An error has occurred in the Master, and it is not generating ticks
   // 3. The network has been damaged and no ticks are being received by this slave
   //
   // Try to make sure the system is in a safe state...
   // NOTE: Interrupts are disabled here
   SCC_A_SLAVE_Enter_Safe_State();

   Start_slave = 0;
   Error_code_G = ERROR_SCH_WAITING_FOR_START_COMMAND_FROM_MASTER;
   SCH_Report_Status(); // Sch not yet running - do this manually

   // Now wait (indefinitely) for appropriate signal from the master
   do {
      // Wait for 'Slave ID' message to be received 
      do {
         SCC_A_SLAVE_Watchdog_Refresh(); // Must keep feeding the watchdog
         } while ((CAN_messages[0].MCR1 & 0x03) != 0x02);  

      // Got a message - extract the data 
      if ((CAN_messages[0].MCR1 & 0x0c) == 0x08)  // if MSGLST set
         {
         // Ignore lost message
         CAN_messages[0].MCR1 = 0xf7;  // reset MSGLST
         }

      Tick_00 = (tByte) CAN_messages[0].Data[0]; // Get data byte 0 
      Tick_ID = (tByte) CAN_messages[0].Data[1]; // Get data byte 1 

      CAN_messages[0].MCR0 = 0xfd;  // reset NEWDAT, INTPND
      CAN_messages[0].MCR1 = 0xfd;

      if ((Tick_00 == 0x00) && (Tick_ID == SLAVE_ID))
         {

⌨️ 快捷键说明

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