📄 intruder.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 + -