Está en la página 1de 28

CE860 Advanced Embedded Systems Design Assignment-2

Task-3 Home Alarm System Report

Submitted as part of the requirements for:


CE860 Advanced Embedded Systems Design

Name: Yalcin Aygul,


Student Number: 1500865
Supervisor: Prof Dongbing Gu
Date: 16 March 2016
Contents
1-State Machine ................................................................................................................................................... 2
2-Implementation of Set_key() and Test_Code() ................................................................................................. 2
3-Implementing the function of delay_5ms() using interruption ....................................................................... 4
1-Finite State Machine

State machine consists of 6 states which are exit, un_set, set, entry, alarm and prog_mode. At the
beginning when program start first task is creating key. After that program goes into the state machine
and initially starts with unset_mode.In the unset mode user can activate any zone by using left most
switches (first switch is devoted for entry/exit mode), if the user enter the code they have two option
exit mode and program mode. If user enters the ‘#’ then program goes into the program mode and
program requesting changing exit period time, after change is finished and enter ‘#’, this time program
requesting changing entry period time. After this change is finished this time program asking changing
passcode. Entering final ‘#’ program goes back to the unset_mode. If user enter ’*’ then program goes
to the exit period and countdown starts begin.

End of the countdown program goes the set mode and all the sensors are starting being observed. If
any sensors which were activated in unset mode senses any movement then program goes to the alarm
mode and siren goes off and led starts flashing until the correct code being entered. If the users wants
to enter the zone then they have to activate entry/exit zone switches (left most switches on the board)
and enter the right key and this time program goes to the entry mode. In entry mode if users fails to
enter correct code in the entry period of time then program goes to the alarm mode again.

2-Implementation of Set_key() and Test_Code()

Set_key()
To create user password, set_key() function was created. When the main program call the set key function
firstly the function also call the getKey function, and getKey function read the character and send to the set
key function. In the set key function there is 1 for loop and it call the getKey function 4 times. If the character
is ‘ ‘ then the decrement the cursor by 1 ,thus program stay in the for loop until to read character except
space ‘ ‘. If we want to delete the character then we need to press ‘#’ and this make cursor put one step
back in the lcd display. As the code is seen below, there is a nested if-else statement created. Every time only
one if statement is executed others is ignored. If the number is entered then the final else statement is
executed. At the end, program get into the while loop end stay there until ‘* ‘ character is being entered.
static void setKey(void) // set user key code - this is the password
{
lcd_rst(); lcd_puts("Please create 4 digit key.");
lcd_xy(1, 2); lcd_puts("Code:____ ");
char ch;
int cursor;

for(cursor = 0; cursor < 4; cursor++) // pass through array elements


{
ch = getKey(); // read character from keypad and stored in ch

if(ch == ' ') //if no char enter then stay in the for loop
//indefinitely.
cursor = cursor-1;
else if(ch == '#')
{
if(cursor == 0 )
cursor = cursor-1;
else
{
cursor = cursor-1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1
}
}
else
{
code[cursor] += ch;/ assign the char. into the array.
lcd_xy(6+cursor,2);
lcd_putc('*');

lcd_rst(); lcd_puts("Please create 4 digit key.");


lcd_xy(1,2); lcd_puts("Press * to set ");
while (getKey() != '*');// shows the message ebow until enter the '*'

Test_Code()
In the test code mainly switch case statement was used. Program reads the character and decided
what to do. Again if nothing is entered, then the program stays in for loop. If ‘#’ is entered then this
makes turn the cursor previous position and delete the character presently. Cursor starts on the
second line of the display and 6. Position on the second line, as the first underscore ‘_’ is placed
that position. Default mode of the switch statement is to enter the character into the array, then there
is for loop to compare that array with the other array that stores the real passcode. After the for loop
program get into the infinite while loop and there is only two option to escape from it. One is ‘*’ for
used to select unset mode, other is ‘#’ to select program mode. At the end of the function, it return
value defined accepted that will be used in the unset mode. If the return value return have number 4,
that means all for number that were entered is correct and program can go to the unset mode. If the
accepted has a value 5 then the program will go to the program mode. If the accepted has less then
value 4 which indicate that the passcode entered is wrong and the alarm will burst 250ms and
program ask the another go for user enter the code.
int testCode()
{
int compare;
char ch;
int cursor;
int accepted = 0;
char passwrdEnter[4] = 0;
lcd_xy(1,2); lcd_puts("Code:____ ");
for (cursor=0; cursor<4; cursor++)
{
ch = getKey();// read the key
switch(ch)
{
case ' ':// if it is space then stay in the for loop
cursor = cursor-1;
break;
case '#': // if the character is '#' then delete what you
entered.
if (cursor==0)
{
cursor = cursor-1;
}
else
{
cursor = cursor-1;
passwrdEnter[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1;
}
break;
default:
passwrdEnter[cursor] += ch;
lcd_xy(6+cursor,2); lcd_putc('*');
}
}
for (compare=0; compare<4; compare++)
{
if (passwrdEnter[compare] == code[compare])
{
accepted++;
}
}
while (1)
{
if(getKey() == '#') // if it is true then go to program mode.
{
accepted++;
break;
}

if (getKey()== '*')
break;
lcd_xy(1,2); lcd_puts("Press * to set ");
}
return(accepted);
}

3-Implementing the function of delay_5ms() using interruption

To change delay time, timer interruption mechanism was used. For activation of it, appropriate line in
the IRQ.ASM file should be changed for setting up interrupt vector sequence of address.
int_tim_cnt1_ufl DC $tick_handler??

Secondly, to enable timer interrupt , two codes below also added.


rg . tim . ctrl_en = TIM_CTRL_EN_CNT1_CNT_MASK ;
rg . tim . int_en1 = TIM_INT_EN1_CNT1_EXP_MASK ;

For timer reload value initialisation the code showed below also need to be added.
rg . tim . cnt1_ld = timer_reload_value;

Next process is choosing system clock. In the task it was used LOW_REF clock which is 32.7 kHz by
adding,
fd.ssm.clk_en.low_pll = 0;
And the code below was also added to select one clock output from the divider chains. According to
the table in the pdf document 7-System support module, number 3 need to be assigned the code to get
.97 milliseconds delay.
rg.ssm.tap_sel2 =3;
Finally initial countsown point is entered and it is placed into the time_delay_ms_unit()
the rg . tim . cnt1_ld =65535.
Now we can get about 1 msecond delay. If we call the time_delay_ms_unit() function and assign it 5 we
can get 5 millisecond. The function was added below.

void timer_delay_ms_unit(int time )


{
int a; //if the time is 5 then we gain 5 ms delay.
while (1)
{
if (1 == do_pattern)
{
for(a=time ;a<0; a-- )
rg.tim.cnt1_ld = 65535;
}
}
1-Appendix

/*=============================================================================
Copyright University of Essex 2006
Author: Steve Wood

FILE - main.c
eCOG1 application.

DESCRIPTION
alarm laboratory
Cyan Ecog based eval boards and alarm 1 laboratory hardware.
Use a terminal program such as 'HyperTerminal' to communicate with the application.
The serial port configuration is shown below.
9600 Baud
8 data bits
No parity bits
One stop bit
No hardware flow control

MODIFICATION DETAILS
Based on techniques used in the eCOG1 eval board example projects
(led, eval_pcb, duart_irq), and the test routines for the alarm board.
An adapted version of driver_lib.h must be used for the #include statement.

==============================================================================*/

/******************************************************************************
Project level include files.
******************************************************************************/

#include <ecog1.h>
#include <stdio.h>
#include "driver_lib.h"
#include "util.h"

// PIOA outputs for LEDs (on port K)


#define row1 0
#define row2 1
#define row3 2
#define row4 3
#define col1 4
#define col2 5
#define col3 6
#define extSounder 7

//keypad decode
#define key_0 7
#define key_1 0
#define key_2 4
#define key_3 8
#define key_4 1
#define key_5 5
#define key_6 9
#define key_7 2
#define key_8 6
#define key_9 10
#define key_ast 3
#define key_hash 11

/******************************************************************************
Declaration of static functions.
******************************************************************************/
static void alarm_short_period(int x);
static void alarm_state(int);
static void delay_5ms(void);
static int countdown_entry(void);
static int countdown_exit(void);

static void dBounce(void);


static void setKey(void);
static void change_Key(void);
static void delay(int length);
/******************************************************************************
Declaration of non-static functions.
******************************************************************************/
void prog(int z);
void alarmConfig(void);
int testCode(void);
char getCode(void);
char getKey(void);

/******************************************************************************
Module global variables.
******************************************************************************/
static unsigned int do_pattern;
char code[4] = 0; // The password
static int exitTime = 10; // exit period multipier for countdown loop
int wrong;
int z= 0;
int p_mode=0;
//int mode_select=4;

//char code[4] = {'1','2','3','4'};


static int dummy_exit_time=10;
static int entryTime =10;

/******************************************************************************

Methods Start Here.


******************************************************************************/

/*=============================================================================
Cyan Technology Limited

FILE - main.c

DESCRIPTION
Initiates the Finite State Machine

=============================================================================*/

int main(int argc, char* argv[]) {

//locals
int sw;
//INIT
alarmConfig();
// Start tick timer and enable interrupt
rg.tim.ctrl_en = TIM_CTRL_EN_CNT1_CNT_MASK;
rg.tim.int_en1 = TIM_INT_EN1_CNT1_EXP_MASK;
rg.ssm.tap_sel2 =3; // by choosing it we can get about 1 ms delay
fd.ssm.clk_en.low_pll = 0; // low pll chosen 32khz clock frequency

//update leds from switches


sw = pio_in(PIOA); // input from PIOA,
sw = sw & 0xFF00; // mask switch inputs from all IO,
sw = sw >> 8; // shift to output IO
pio_out(PIOB, sw); // and output on PIOB
setKey(); // user supplies own key code // lcd says "set user key"

while (1)
{
if (1 == do_pattern)
{
//update leds from switches
sw = pio_in(PIOA); // PIOA CORRESPONDS FOR SWITCHES
sw = (sw & 0xFF00) >> 8;
pio_out(PIOB, sw);
sw = (sw & 0x007); // mask required switches (only first 3 switches required)
}
alarm_state(sw); // FSM routine
}
return (0);
}

//#######################################################################################
###########

enum State {exit, un_set, set, entry, alarm, report,prog_mode}; // take values of 0,1,2,3,4

static void alarm_state(int s)


{

int alarmcount;
static previous;
static State = un_set; // Initial state
pio_out(PIOB, s | State << 5); // takes the enum state value and bit shifts them
// ready to output onto the leds along with switch indicators
switch(State)
{
/*--------------------------------------------------------------------------------
UN_SET STATE (STATE 0)
un_set led enabled
Internal sounder disabledabled
Sensors not monitored.
---------------------------------------------------------------------------------*/
case un_set:
lcd_rst(); lcd_puts("Unset Mode");
previous = State;
if (getKey() != ' ')
{
if(testCode() == 4)
{
State = exit;
wrong = 0; // failure counter reset
//break;
}
else if(testCode() == 5)
{

State = prog_mode;
wrong =0;
//break;
}
else
{
if(wrong == 3)
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
pio_out(PIOB, 144); // LED6 AND LED9 ARE ON AND
HERE LED9 IS LIT FOR A DELAY TIME()

alarm_short_period(10); // i added (27/01/2016 17:40)


100*5m_s burst
delay(100);
++wrong; // increment in every wrong code

}
//break;
}

}
break;

/*------------------------------------------------------------------------------
PROGRAM MODE

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

case prog_mode :

for(z=0; z<4; z++)


{

switch(z)
{
case 0:
prog(z); // for change the entry period
break;

case 1: // for change the exit period


prog(z);
break;

case 2:
change_Key(); // change the key.
break;

case 3:
break;

}
State = un_set;
break;

//--------------------------------------------------------------------------------
// EXIT STATE (STATE 1)
// un_set led flashes
//Internal sounder enabled for 250msec every 500msec.

case exit:
if(previous!=State) // if the previous state does not change then dont rewrite it on the
screen.
{
lcd_rst();
lcd_puts("EXIT MODE");
}
previous = State;
switch(countdown_exit())
{
case 2:
State = alarm;
break;
case 1:
State = un_set;
break;
case 0:
State = set;
break;
}
break;
/*--------------------------------------------------------------------------------
SET STATE (STATE 2)
set led enabled
Internal sounder disabled.
---------------------------------------------------------------------------------*/
case set:

if(previous!=State)
{
lcd_rst();
lcd_puts("SET MODE");
}
previous = State;
s = pio_in(PIOA);
s = s & 0xFF00;
s = s >> 8;
pio_out(PIOB, s);

if(s&0x01) State = entry; //masking if s is 0001 then true

if(s&0x02) State = alarm; //masking if s 0010 is then true

if(s&0x04) State = alarm; //masking if s 0100 is then true

if(s&0x08) State = alarm; //masking if s 1000 is then true

break;
/*--------------------------------------------------------------------------------
ENTRY STATE (STATE 3)
un_set led flashes
Internal sounder enabled for 250ms every 500ms.
---------------------------------------------------------------------------------*/
case entry:
if(previous!=State) // if previous state did not change then dont
{ // refreshing the lcd.
lcd_clr(); lcd_puts("ENTRY MODE");
}
previous = State;
switch(countdown_entry())
{
case 2:
State = alarm;
break;
case 1:
State = un_set;
break;
case 0:
State = alarm;
break;
}
break;
/*--------------------------------------------------------------------------------
ALARM STATE (STATE 4)
alarm led enabled
Internal and External sounders enabled.
---------------------------------------------------------------------------------*/
case alarm:
if(previous!=State)
{
lcd_rst();
lcd_clr();
lcd_puts("ALARM MODE");
}
previous = State;
while (State == alarm) // it was while (alarmcount <= 60000 && State == alarm)
{
// external sounder config and enable ******************
ssm_pwm1_clk(SSM_LOW_PLL, 9);
rg.tim.pwm1_ld = 2;
rg.tim.pwm1_val = 1;
fd.tim.pwm1_cfg.pol = 1;
fd.tim.pwm1_cfg.sw_reload = 1;
rg.tim.cmd = TIM_CMD_PWM1_LD_MASK;
rg.tim.ctrl_en = TIM_CTRL_EN_PWM1_CNT_MASK
|TIM_CTRL_EN_PWM1_AUTO_RE_LD_MASK;
//******************************************************
alarmcount++;
delay_5ms();
pio_out(PIOB, 128);
if (getKey() != ' ')
{
if(testCode() == 4) // All 4 characters match
{
rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK; // disable external
sounder
wrong =0; // failure counter reset
State = un_set;

}
else
{
if(wrong == 3) // 3 times try to find code if the user fail 4th times
goes to alarm state
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
++wrong; // failure counter incremented
State = alarm;
}
}
}
}
rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK; // disable external sounder
pio_out(PIOB, 128);
if (getKey() != ' ')
{
if(testCode() == 4) // All 4 characters match
{
wrong =0; // failure counter reset
State = un_set;
alarmcount = 0;
}
else
{
if(wrong == 3) // 3 times try to find code if the user fail 4th
times goes to alarm state
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
++wrong; // failure counter incremented
State = alarm;
}

}
}
break;

}
}

//#######################################################################################
###########

void prog(int z)

int cursor=0;
char ch;
lcd_rst(); lcd_puts("Prog Mode");

if(z==0)
{lcd_xy(1, 2);lcd_puts("Entry: 10s");}
if(z==1)
{lcd_xy(1, 2);lcd_puts("Exit: 10s");}

for(cursor = 0; cursor < 2; cursor++) // pass through array elements


{
ch = getKey(); // get char from keypad

switch(ch)
{
case ' ':
cursor--; // stops no inputs from being read as characters
break;

case '#':
if (cursor==0)
{
cursor--;
}
else
{
cursor -= 1;

lcd_xy(8+cursor,2); lcd_putc('_');
cursor--;
}
break;
default:
if(cursor ==0)
{
lcd_xy(8+cursor,2);

lcd_putc(ch);
if( (ch-'0') >= 1 && (ch-'0') <= 6)
dummy_exit_time = (ch-'0')*10;

else
cursor--;
}

if(cursor == 1)
{
lcd_xy(8+cursor,2);

lcd_putc(ch);

if( ( dummy_exit_time == 60 ) && ( ( ch - '0' )>0 ) )


cursor--;
else
dummy_exit_time = dummy_exit_time + ( ch - '0' );
}

}
}
if(z ==0)
entryTime =dummy_exit_time;
if(z==1)
exitTime =dummy_exit_time;
lcd_rst(); lcd_putc(exitTime);
lcd_rst(); lcd_puts("time changed");
lcd_xy(1,2); lcd_puts("Press # ");
while (getKey() != '#') // shows the message below until enter the '*'
{

//#######################################################################################
############

int testCode()
{
int compare;
char ch;
int cursor;
int s;
int accepted = 0;
char passwrdEnter[4] = 0;
lcd_xy(1,2); lcd_puts("Code:____ ");
for (cursor=0; cursor<4; cursor++)
{
ch = getKey();// read the key
switch(ch)
{
case ' ':// if it is space then stay in the for loop
cursor = cursor-1;
break;
case '#': // if the character is '#' then delete what you entered.
if (cursor==0)
{
cursor = cursor-1;
}
else
{
cursor = cursor-1;
passwrdEnter[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1;
}
break;
default:
passwrdEnter[cursor] += ch;
lcd_xy(6+cursor,2); lcd_putc('*');
}
}
for (compare=0; compare<4; compare++)
{
if (passwrdEnter[compare] == code[compare])
{
accepted++;
}
}
while (1)
{
if(getKey() == '#') // if it is true then go to program mode.
{
accepted++;
break;
}

if (getKey()== '*')
break;
lcd_xy(1,2); lcd_puts("Press * to set ");
}
return(accepted);
}

/**********************************************************************************
Delays for exit timer and switch de-bounce
**********************************************************************************/

static void delay(int length)


{ // Provides a multiple of 5 msec delay.
// The multiple is specified by the value of the 'length' argument.

//locals
unsigned int h;

// making the same assumptions for timing as those in delay_5ms


for (h = 0; h < length; h++)
{
delay_5ms(); // a delay function defined elsewhere in source code
}
}

static void delay_5ms(void)


{
//locals
unsigned int m;

// Assume 25 MHz CPU and cache enabled: 5ms = 125000 NOPs


// This will be 7*18000 instructions
for (m = 0; m < 18000; m++)
{
//void nop(); // do nothing i changed
}
}

static int countdown_entry()


{

unsigned int c=0;


int cancel;
int s;

for (c=0; c < entryTime;c++)


{
lcd_xy(1,2); lcd_puts("Countdown On ");
s = pio_in(PIOA); // read input(switches)
s = s & 0xFF00;
s = s >> 8;
pio_out(PIOB, 128); // led9 on
delay(50);
alarm_short_period(50);
pio_out(PIOB, 0); // led9 off
delay(50);
switch(s)
{
case 2:
c = entryTime; // end loop count
cancel = 2; // cancellation indicator
break;

case 8:
c = entryTime; // end loop count
cancel = 2; // cancellation indicator
break;

case 4:
c = entryTime; // end loop count
cancel = 2; // cancellation indicator
break;

default:
if (getKey() == ' ')
{
cancel = 0;
}
else
{
if (testCode() == 4)
{
wrong = 0;
c = entryTime; // end loop count
cancel = 1; // cancellation indicator
}
else
{
if(wrong == 2) // Fail to match code > 3 times
{
c = entryTime;
cancel = 2;
}
else
{
wrong++; // failure counter incremented
}
}
}
break;
}
}
return cancel;
}

static int countdown_exit()


{

unsigned int c=0;


int cancel;
int s;
for (c=0; c < exitTime;c++)
{
lcd_xy(1,2); lcd_puts("Countdown On ");
s = pio_in(PIOA); // read input(switches)
s = s & 0xFF00;
s = s >> 8;
pio_out(PIOB, 128); // led9 on
delay(50);
alarm_short_period(50);
pio_out(PIOB, 0); // led9 off
delay(50);
switch(s)
{
case 2:
c = exitTime; // end loop count
cancel = 2; // cancellation indicator
break;

case 8:
c = exitTime; // end loop count
cancel = 2; // cancellation indicator
break;

case 4:
c = exitTime; // end loop count
cancel = 2; // cancellation indicator
break;

default:
if (getKey() == ' ')
{
cancel = 0;
}
else
{
if (testCode() == 4)
{
wrong = 0;
c = exitTime; // end loop count
cancel = 1; // cancellation indicator
}
else
{
if(wrong == 2) // Fail to match code > 3 times
{
c = exitTime;
cancel = 2;
}
else
{
wrong++; // failure counter incremented
}
}
}
break;
}

}
return cancel;
}

static void dBounce(void) // introduces delay between keys registered for switch de-bounce
{
//locals
unsigned int h;

// making the same assumptions for timing as those in delay_5ms


for (h = 0; h < 13;h++) //20 was 15
{
delay_5ms();
}
}

/**********************************************************************************
Configurations
**********************************************************************************/

void __irq_entry tick_handler(void)


{
fd.tim.int_clr1.cnt1_exp = 1;
do_pattern = 1;
}

void alarmConfig(void)
{
//locals
int i;

//set keypad pins as inputs (tristate)


//set the pins so they are 0 when outputs
for (i = 0; i < col3; i++)
{
gpio_cfg(i, 1);
gpio_wr(i, 0);
}

//set sounder as outputs


gpio_cfg(extSounder, 0);
gpio_wr(extSounder, 0);
}

/**********************************************************************************
Keypad functionality
**********************************************************************************/

char getKey(void) // returns characters from the keypad


{
int i, j;
int key;
char ch = ' ';
key = 0xFFFF;
for (i = 0; i <= (col3 - col1); i++)
{
gpio_wr((i + col1), 0);
gpio_cfg((i + col1), 0);
dBounce();
for (j = 0; j <= row4; j++)
{
if (gpio_rd(j) == 0)
{
key = (i * col1) + j;
switch (key) {
case key_0:
ch = '0';
break;
case key_1:
ch = '1';
break;
case key_2:
ch = '2';
break;
case key_3:
ch = '3';
break;
case key_4:
ch = '4';
break;
case key_5:
ch = '5';
break;
case key_6:
ch = '6';
break;
case key_7:
ch = '7';
break;
case key_8:
ch = '8';
break;
case key_9:
ch = '9';
break;
case key_ast:
ch = '*';
break;
case key_hash:
ch = '#';
break;
default:
ch = ' ';
}

}
}
gpio_cfg((i + col1), 1);
}
return ch;
}

void timer_delay_ms_unit(int time )


{
int a; //if the time is 5 then we gain 5 ms delay.
while (1)
{
if (1 == do_pattern)
{
for(a=time ;a<0; a-- )
rg.tim.cnt1_ld = 65535;
}
}

static void setKey(void) // set user key code - this is the password
{
lcd_rst(); lcd_puts("Please create 4 digit key.");
lcd_xy(1, 2); lcd_puts("Code:____ ");
char ch;
int cursor;

for(cursor = 0; cursor < 4; cursor++) // pass through array elements


{
ch = getKey(); // read character from keypad and stored in ch

if(ch == ' ') //if no char enter then stay in the for loop indefinitely.
cursor = cursor-1;
else if(ch == '#')
{
if(cursor == 0 )
cursor = cursor-1;
else
{
cursor = cursor-1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1
}
}
else
{
code[cursor] += ch; // assign the charcacter into the array.
lcd_xy(6+cursor,2);
lcd_putc('*');

lcd_rst(); lcd_puts("Please create 4 digit key.");


lcd_xy(1,2); lcd_puts("Press * to set ");
while (getKey() != '*'); // shows the message ebow until enter the '*'

static void change_Key(void) // set user key code - this is the password
{
int cursor;
char ch;
lcd_rst(); lcd_puts("change the key?");
lcd_xy(1, 2); lcd_puts("Code:____ ");
for(cursor = 0; cursor < 4; cursor++) // pass through array elements
{
ch = getKey(); // read character from keypad and stored in ch
switch(ch)
{
case ' ':
cursor--; // stops no inputs from being read as characters
break;
case '#':

if (cursor==0)
{
cursor--;
}
else
{
cursor -= 1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor--;
}
break;
default:
code[cursor] = ch; //put the character read from the getkey() into the array
lcd_xy(6+cursor,2);
lcd_putc('*');
break;
}

}
while (getKey() != '#') // shows the message below until enter the '#'
{
lcd_rst(); lcd_puts("change the key??");
lcd_xy(1,2); lcd_puts("Press # to set ");
}
}

static void alarm_short_period(int x){


ssm_pwm1_clk(SSM_LOW_PLL, 9);
rg.tim.pwm1_ld = 2;
rg.tim.pwm1_val = 1;
fd.tim.pwm1_cfg.pol = 1;
fd.tim.pwm1_cfg.sw_reload = 1;
rg.tim.cmd = TIM_CMD_PWM1_LD_MASK;
rg.tim.ctrl_en = TIM_CTRL_EN_PWM1_CNT_MASK |
TIM_CTRL_EN_PWM1_AUTO_RE_LD_MASK;
delay(x);

rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK;
}