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

📄 intruder.c

📁 Embedded C 这本书的范例光碟程式
💻 C
字号:
/*------------------------------------------------------------------*-

   Intruder.C (v1.00)

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

   Multi-state framework for intruder alarm system.

   COPYRIGHT
   ---------

   This code is associated with the book:

   EMBEDDED C by Michael J. Pont 
   [Pearson Education, 2002: ISBN: 0-201-79523-X].

   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 "Intruder.H"

#include "Keypad.h"
#include "PC_O.h"

// ------ Private data type declarations ---------------------------

// Possible system states
typedef 
enum {DISARMED, ARMING, ARMED, DISARMING, INTRUDER} eSystem_state;

// ------ Private function prototypes ------------------------------

bit  INTRUDER_Get_Password_G(void);
bit  INTRUDER_Check_Window_Sensors(void);
bit  INTRUDER_Check_Door_Sensor(void);
void INTRUDER_Sound_Alarm(void);

// ------ Private variables ----------------------------------------

static eSystem_state System_state_G;

tWord State_call_count_G;

char Input_G[4] = {'X','X','X','X'};
char Password_G[4] = {'1','2','3','4'};

tByte Position_G;

bit New_state_G = 0;

bit Alarm_bit = 0;

/* --------------------------------------------------------------- */
void INTRUDER_Init(void)
   {
   // Set the initial system state (DISARMED)
   System_state_G = DISARMED;

   // Set the 'time in state' variable to 0
   State_call_count_G = 0;
   
   // Clear the keypad buffer
   KEYPAD_Clear_Buffer();

   // Set the 'New state' flag
   New_state_G = 1;

   // Set the (two) sensor pins to 'read' mode
   Window_sensor_pin = 1;
   Sounder_pin = 1;
   }


/* --------------------------------------------------------------- */
void INTRUDER_Update(void)
   {
   // Incremented every time
   if (State_call_count_G < 65534)
      {
      State_call_count_G++;
      }

   // Call every 50 ms
   switch (System_state_G)
      {
      case DISARMED:
         {
         if (New_state_G)
            {
            PC_LINK_O_Write_String_To_Buffer("\nDisarmed");
            New_state_G = 0;
            }

         // Make sure alarm is switched off
         Sounder_pin = 1;

         // Wait for correct password ...
         if (INTRUDER_Get_Password_G() == 1)
            {
            System_state_G = ARMING;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         break;
         }

      case ARMING:
         {
         if (New_state_G)
            {
            PC_LINK_O_Write_String_To_Buffer("\nArming...");
            New_state_G = 0;
            }

         // Remain here for 60 seconds (50 ms tick assumed)
         if (++State_call_count_G > 1200)
            {
            System_state_G = ARMED;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         break;
         }

      case ARMED: 
         {
         if (New_state_G)
            {
            PC_LINK_O_Write_String_To_Buffer("\nArmed");
            New_state_G = 0;
            }

         // First, check the window sensors
         if (INTRUDER_Check_Window_Sensors() == 1)
            {
            // An intruder detected
            System_state_G = INTRUDER;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         // Next, check the door sensors
         if (INTRUDER_Check_Door_Sensor() == 1)
            {
            // May be authorised user - go to 'Disarming' state
            System_state_G = DISARMING;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         // Finally, check for correct password
         if (INTRUDER_Get_Password_G() == 1)
            {
            System_state_G = DISARMED;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         break;
         }

      case DISARMING:
         {
         if (New_state_G)
            {
            PC_LINK_O_Write_String_To_Buffer("\nDisarming...");
            New_state_G = 0;
            }

         // Remain here for 60 seconds (50 ms tick assumed)
         // to allow user to enter the password
         // - after time up, sound alarm
         if (++State_call_count_G > 1200)
            {
            System_state_G = INTRUDER;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         // Still need to check the window sensors
         if (INTRUDER_Check_Window_Sensors() == 1)
            {
            // An intruder detected
            System_state_G = INTRUDER;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         // Finally, check for correct password
         if (INTRUDER_Get_Password_G() == 1)
            {
            System_state_G = DISARMED;
            New_state_G = 1;
            State_call_count_G = 0;
            break;
            }

         break;
         }

      case INTRUDER: 
         {
         if (New_state_G)
            {
            PC_LINK_O_Write_String_To_Buffer("\n** INTRUDER! **");
            New_state_G = 0;
            }

         // Sound the alarm!
         INTRUDER_Sound_Alarm();

         // Keep sounding alarm until we get correct password
         if (INTRUDER_Get_Password_G() == 1)
            {
            System_state_G = DISARMED;
            New_state_G = 1;
            State_call_count_G = 0;
            }

         break;
         }
      }
   }

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

bit INTRUDER_Get_Password_G(void)
   {
   signed char Key;
   tByte Password_G_count = 0;
   tByte i;

   // Update the keypad buffer
   KEYPAD_Update();
   
   // Are there any new data in the keypad buffer?
   if (KEYPAD_Get_Data_From_Buffer(&Key) == 0)
      {
      // No new data - password can't be correct
      return 0;
      }

   // If we are here, a key has been pressed

   // How long since last key was pressed?
   // Must be pressed within 50 seconds (assume 50 ms 'tick')
   if (State_call_count_G > 1000)
      {
      // More than 50 seconds since last key
      // - restart the input process
      State_call_count_G = 0;
      Position_G = 0;
      }

   if (Position_G == 0)
      {         
      PC_LINK_O_Write_Char_To_Buffer('\n');
      }
       
   PC_LINK_O_Write_Char_To_Buffer(Key);
   
   Input_G[Position_G] = Key;             

   // Have we got four numbers?
   if ((++Position_G) == 4)
      {
      Position_G = 0;
      Password_G_count = 0;

      // Check the password
      for (i = 0; i < 4; i++)
          {
          if (Input_G[i] == Password_G[i])
             {
             Password_G_count++;
             }
          }
      }
  
   if (Password_G_count == 4)
      {
      // Password correct
      return 1;
      }
   else
      {
      // Password NOT correct
      return 0;
      }
   }

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

bit INTRUDER_Check_Window_Sensors(void)
   {
   // Just a single window 'sensor' here
   // - easily extended
   if (Window_sensor_pin == 0)
      {
      // Intruder detected...
      PC_LINK_O_Write_String_To_Buffer("\nWindow damaged");
      return 1;
      }

   // Default
   return 0;
   }

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

bit INTRUDER_Check_Door_Sensor(void)
   {
   // Single door sensor (access route)
   if (Door_sensor_pin == 0)
      {
      // Someone has opened the door...
      PC_LINK_O_Write_String_To_Buffer("\nDoor open");
      return 1;
      }

   // Default
   return 0;
   }

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

void INTRUDER_Sound_Alarm(void)
   {
   if (Alarm_bit)
      {
      // Alarm connected to this pin
      Sounder_pin = 0;
      Alarm_bit = 0;
      }
   else
      {
      Sounder_pin = 1;
      Alarm_bit = 1;
      }
   }

/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/

⌨️ 快捷键说明

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