Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
09/10/10 13:20
Read: times


 
#178508 - I have implemented many of the suggestions
Responding to: ???'s previous message
I have implemented many of the suggestions

>> the flag_g was meant to sat as flag_general
>> lcd_disp('?'); i may want to change that '?' to some other character so i haven't put it directly
>>
 j=0;
    while (j<=100) {
    j++;
 


j is just a variable for iteration. the value is not s important as long as it is large
>> when i debug in u-keil the port 0 sfr changes but not pins when i am giving output (sfr key_pad = 0x80;). i know that i need to connect resistors for using P0 as output but can i test it in keil





#include<reg51.h>
//#include"8052.h"
//keypad values
#define KEY_0 '0'
#define KEY_1 '1'
#define KEY_2 '2'
#define KEY_3 '3'
#define KEY_4 '4'
#define KEY_5 '5'
#define KEY_6 '6'
#define KEY_7 '7'
#define KEY_8 '8'
#define KEY_9 '9'
#define KEY_ENTER 'A'
#define KEY_ESC 'B'
#define KEY_C 'C'
#define KEY_D 'D'
#define KEY_E 'E'
#define KEY_F 'F'
#define QUESTION_MARK_CHARACTER '?'

//state_var values
#define ENTER_VAL 0xaa
#define MISMATCH_VAL 0xDD
#define ERROR_VAL 0xff

// Timer register values caliculation formula "value(in decimal)=65535-(time in seconds * crystal freq / 12)
// delay timer    1 ms
#define TH_1MS 0xFC
#define TL_1MS 0x65

// delay timer    50 ms
#define TH_50MS 0xB4
#define TL_50MS 0x00


sfr lcd = 0x90;       //0x90 is port 1 address
sfr key_pad = 0x80;       //0x80 is port 0 address
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

sbit door_state = P2^3;        //let state of 1 mean door is closed and state of 0 mean door is open
sbit motor1=P2^6;
sbit motor2=P2^7;
sbit alarm_1=P2^4;

void timer_50ms(void);
void timer_1ms(void);
void delay_small(unsigned char);
void delay_large(unsigned char);
void lcd_init(void);
void lcd_line(bit);
void lcd_com(unsigned char);
void lcd_disp(unsigned char);
void lcd_disp1(unsigned char dat[],bit delay1);
unsigned char keypad(void);
unsigned char invalid(unsigned char,unsigned char);
unsigned char compare(unsigned char one[], unsigned char two[], bit);
void change_key(void);
void close_lock(void);
void open_lock(void);
void alarm(void);

unsigned char  present_key[]="12345600" ,wrong_count=0,right_count=0;
code unsigned char zero2nine[]="0 to 9 only", wrong[]="wrong key..", lock_error[]="Lock error";

code unsigned char key_state[]=        {0xEE , 0xED , 0xEB , 0xE7,
                                        0xDE , 0xDD , 0xDB , 0xD7,
                                        0xBE , 0xBD , 0xBB , 0xB7,
                                        0x7E , 0x7D , 0x7B , 0x77
                                       };

code unsigned char digit[]=        { KEY_0 , KEY_4 , KEY_8  , KEY_C ,
                                     KEY_1 , KEY_5 , KEY_9  , KEY_D ,
                                     KEY_2 , KEY_6 ,KEY_ENTER,KEY_E ,
                                     KEY_3 , KEY_7 , KEY_ESC , KEY_F
                                   };
// main program starts here
void main()
{
    unsigned char i,j,temp,password[8]=0,state_var=0;
    code unsigned char right[]= "Right Key",p_wd[]= "Key :";
    code unsigned char lcd_open[]= "Open...", lcd_close[]= "Close...";
    code unsigned char lcd_door[]= "A-> Open/Close";
    code unsigned char lcd_change[]= "B-> Change Key", lcd_exit[]= "E-> Exit";

    while(1)
    {
        lcd_init();
        lcd_disp1(p_wd,0);
        lcd_line(1);
        state_var=0;

        //This is where password is taken as input

        for(i=0; i<8; i++)
        {
            password[i]=keypad();                      // reading from keypad

            state_var=invalid(password[i],i);

            if(state_var==ENTER_VAL || state_var==ERROR_VAL || state_var==MISMATCH_VAL)
            {
                break;
            }
            lcd_disp( QUESTION_MARK_CHARACTER );     
        }

        if(state_var==ERROR_VAL || state_var==MISMATCH_VAL)
        {
            continue;
        }
        right_count=0;

        //comparing is done here
        state_var = compare(password,present_key,1);
        if(state_var==ERROR_VAL)
        {
            continue;
        }
        if(right_count==7)
        {
            wrong_count=0;
            lcd_disp1(right,1);
        }

        // The menu is shown here
        for(j=0;j<=200;j++)
          {
            for(i=0; i<1; i++)
            {
                lcd_disp1(lcd_door,0);
                temp=keypad();
                if(temp != ERROR_VAL)  break;

                lcd_disp1(lcd_change,0);
                temp=keypad();
                if(temp != ERROR_VAL)  break;

                lcd_disp1(lcd_exit,0);
                temp=keypad();
                if(temp != ERROR_VAL)  break;
            }

            if(temp==KEY_C)
            {
                if(door_state==1)
                {
                    lcd_disp1(lcd_open,0);
                    open_lock();
                }
                else
                {
                    lcd_disp1(lcd_close,0);
                    close_lock();
                }
            }
            else if(temp==KEY_D)
            {
                change_key();
            }
            else if(temp==KEY_ESC)
            {
                break;
            }
        }
    }
}

// Timer value caliculation formula "value(in decimal)=65535-(time in seconds * crystal freq / 12)
//if crystal frequency is 11.0592 MHz the delay due to timer is about 1 ms
void timer_50ms()
{
    TMOD = 0x01;
    TH0 = TH_50MS;
    TL0 = TL_50MS;
    TR0 = 1;
}
//if crystal frequency is 11.0592 MHz the delay due to timer is about 1 ms
void timer_1ms()
{
    TMOD = 0x01;
    TH0 = TH_1MS;
    TL0 = TL_1MS;
    TR0 = 1;
}
/*
   Purpose: This function is used to create delay between operations with a minimum of 1 ms and maximum
            of about 256 ms of delay
   Input: input is 8 bit i.e. unsigned char. The input specifies the amount of delay called in ms
*/
void delay_small(unsigned char u)
{
    unsigned char i;

    for(i=0; i<u; i++)
    {
        timer_1ms();
        while(!TF0);
        TF0 = TR0 =0;
    }
}
/*
   Purpose: This function is used to create delay between operations with a minimum of 50 ms and maximum
            of about 256*50 ms of delay
   Input: input is 8 bit i.e. unsigned char. The input specifies the amount of delay called in 50ms
*/
void delay_large(unsigned char u)
{
    unsigned char i;
    for(i=0; i<u; i++)
      {
          timer_50ms();
        while(!TF0);
        TF0 = TR0 =0;
      }
}
/*
        Purpose: This function is used to pass on commands to the LCD display connected to port P1.
        Input: input is 8 bit i.e. unsigned char. The input specifieds command to be given to the LCD.
*/
void lcd_com(unsigned char x)
{
    RS=0;                             //command mode
    RW=0;
    EN=1;

    lcd=x;
    delay_small(5);
    EN=0;
    delay_small(5);
}
/*
        Purpose: This function initialises the LCD screen
*/
void lcd_init()
{
    lcd_com(0x0E);
    lcd_com(0x38);
    lcd_com(0x06);
}
/*
        Purpose: This function is used to change/define the line which is to be used in the LCD.
        Input: input is 1 bit.
               The input of '0' makes the cursor to go to the line 0
               and input of '1' makes the cursor to go to line 1.
*/
void lcd_line(bit line)
{
    if(line==0)
        lcd_com(0x80);                    //line one
    else
        lcd_com(0xC0);                    //line two
}
/*
        Purpose: This function is used to pass on data to the LCD display connected to port P1.
        Input: Input is 8 bit i.e. unsigned char. The input specifieds data to be given to the LCD.
*/
void lcd_disp(unsigned char x)
{
    RS=1;
    RW=0;
    EN=1;

    lcd=x;
    delay_small(5);
    EN=0;
    delay_small(5);
    //lcd_com(0x06);
}


void lcd_disp1(unsigned char dat[], bit a)
{
    unsigned char i;
    lcd_com(0x01);
    lcd_line(0);

    for(i=0; i <sizeof(dat) ; i++)
    {
        if(i==8)
        {
            lcd_line(1);
        }
        lcd_disp(dat[i]);
    }

    if(a==1)
    {
        delay_large(80);// Four second delay is to be expected
    }
    else
    {
        delay_large(10);// 0.5 second delay is to be expected
    }
}
/*
        Purpose: This function is used to get data from the keypad connected to port P0.
        Return: Return is 8 bit i.e. unsigned char. The Return is the value of the button pressed in the keypad.
*/
unsigned char keypad()
{
    unsigned char i,col=0,row=0,temp2=0xff,wait=0;//,wait1=0;
    bit flag_exit=0;
    while(1)
    {
        timer_50ms();
        key_pad = 0x0f;

        for(i=0; i<4; i++)
        {
            if(i==0)        key_pad = row = 0xEF;
            else if(i==1)   key_pad = row = 0xDF;
            else if(i==2)   key_pad = row = 0xBF;
            else if(i==3)   key_pad = row = 0x7F;
            
            delay_small(1);
            col = key_pad;
            col &= 0x0f;
            row &= 0xf0;

            if(col != 0x0F)
            {
                delay_large(6);

                col = key_pad;
                col &= 0x0F;
                if(col != 0x0F)
                {
                    col = col | row;
                    flag_exit=0x01;
                    break;
                }
            }
        }
        //variable col will contain both row and column data
        for(i=0; i<16; i++)
        {
            if(key_state[i]==col)
            {
                temp2=digit[i];
                break;
            }
        }

        if(flag_exit==0x01)  break;

        if(TF0)
        {
            wait++;
            TF0=TR0=0;
            if(wait==255)
            return ERROR_VAL;
        }
    }
    return temp2;
}
/*
        Purpose: This function should be used to close the lock of the door
*/
void close_lock()
{
    unsigned char a=0;
    if(door_state==0)
    {
        motor1=0;
        motor2=1;
        while(a<=200)
        {
            a++;
            if(door_state==1)
            {
                return;
            }
            delay_small(5);
        }
        lcd_com(0x01);
        lcd_line(0);

        lcd_disp1(lock_error,1);
        return;
    }
}
/*
        Purpose: This function should be used to open the lock of the door
*/
void open_lock()
{
    unsigned char a=0;
    if(door_state==1)
    {
        motor1=0;
        motor2=1;
        while(a<=200)
        {
            a++;
            if(door_state==0)
            {
                return;
            }
            delay_small(5);
        }
        lcd_com(0x01);
        lcd_line(0);

        lcd_disp1(lock_error,1);
        return;
    }
}
/*
    Purpose: This function checks for illegal buttons pressed and gives appropriate return
    Input: (x,i) : x is the input from the keypad and i is the index of the key presed
    Return: (state_var) :return value of 0xaa is given if enter is pressed(ENTER_VAL)
                    0xDD is returned if there is mismatch (MISMATCH_VAL)
                    and 0xff is given if escape is pressed or due to error     (ERROR_VAL)
*/
unsigned char invalid(unsigned char x,unsigned char i)
{
    unsigned char state_var=0x00,temp;
    while(i==7)
    {
        temp=keypad();

        if(temp==KEY_ENTER)
        {
            state_var=ENTER_VAL;
            break;
        }
        else if(temp == KEY_ESC || temp == ERROR_VAL)
        {
            state_var=ERROR_VAL;
            break;
        }
    }

    if(x==KEY_ENTER)
    {
        state_var=ENTER_VAL;
    }
    /*
        Do not accept the values of C,D,E,F. Password must contain only 0 to 9 only
    */
    else if(x==KEY_C || x==KEY_D || x==KEY_E || x==KEY_F)
    {
        state_var=MISMATCH_VAL;
        lcd_disp1(zero2nine,1);
    }
    else if(x==KEY_ESC || x==ERROR_VAL)
    {
        state_var=ERROR_VAL;
    }
    return state_var;
}
/*
        Purpose: this is used to compare the 2 variables and give corresponfing output
*/
unsigned char compare(unsigned char one[],unsigned char two[], bit a)
{
    unsigned char state_var,i;
    code unsigned char mismatch[]="Key mismatch", try_again[]="Try again";;
    state_var=0x00;
    right_count=0;
    for(i=0; i<8; i++)
    {
        if(one==two)
        {
            right_count++;
        }
        else
        {
            wrong_count++;
            right_count=0;
            state_var=ERROR_VAL;
            break;
        }
    }
    if(state_var==ERROR_VAL)
    {
        if(a==1)
        {
            lcd_disp1(wrong,1);
            if(wrong_count>=5)
            {
                alarm();
                return ERROR_VAL;
            }
        }
        else if(a==0)
        {
            lcd_disp1(mismatch,0);
            delay_large(4);
            lcd_disp1(try_again,0);
            return ERROR_VAL;
        }
    }
    return state_var;
}
/*
        Purpose: 1. This function is used to get data from the keypad connected to port P0 twice.
                 2. Then compare them and then change the password.
*/
void change_key()
{

    unsigned char i,temp, password[8]=0, pass_confirm[8]=0,state_var;
    code unsigned char new_key[]= "New key:",confirm[]= "Confirm:";
    code unsigned char key_changed[]= "Key Changed...";

    while(1)
    {
        lcd_disp1(new_key,0);
        lcd_line(1);
        state_var=0;
        temp=0;

        /*   take new password    */
        for(i=0; i<8; i++)
        {
            // count++;
            password[i]=keypad();

            state_var=invalid(password[i],i);
            if(state_var==ENTER_VAL || state_var==MISMATCH_VAL)
            {
                break;
            }
            else if(state_var==ERROR_VAL)
            {
                return;
            }
            lcd_disp( QUESTION_MARK_CHARACTER );
        }

        if(state_var==MISMATCH_VAL)
        {
            continue;
        }

        //confirmation is done here

        lcd_disp1(confirm,0);
        lcd_line(1);

        /*  take new password   */
        for(i=0; i<8; i++)
        {
            pass_confirm[i]=keypad();

            state_var=invalid(pass_confirm[i],i);
            if(state_var==ENTER_VAL || state_var==MISMATCH_VAL)
            {
                break;
            }
            else if(state_var==ERROR_VAL)
            {
                return;
            }
            lcd_disp( QUESTION_MARK_CHARACTER );
        }
        if(state_var==MISMATCH_VAL)
        {
            continue;
        }

        state_var=compare(password,pass_confirm,0);
        if(state_var==ERROR_VAL)
        {
            continue;
        }

        if(right_count==7)
        {
            for(i=0; i<8; i++)
            {
                present_key[i] = password[i];
            }
            lcd_disp1(key_changed,1);
            right_count=0;
        }
    }
    return;
}
/*
    Purpose:This function calls alarm and switches off the LCD display until a 5 digit master password is pressed
*/
void alarm()
{
    code unsigned char crack[]="0F3C7";
    unsigned char temp[5],a,b,count;
    /*   Program to switch off lcd display here    */
    lcd_com(0x08);
    alarm_1=1;

    while(1)
    {
        for (a=0; a<5; a++)
        {
            temp[a]=keypad();
        }
        count=0;
        for (a=0 ; a<5 ; a++)
        {
            if(temp[a] != crack[a])
            {
                alarm_1=1;
                for (b=0; b<5; b++)
                {
                    temp[a]=0;
                }
                break;
            }
            else if(temp[a]==crack[a])
            {
                count++;
            }
        }
        if(count!=4)
        {
            continue;
        }
        else
        {
            delay_large(5);
            alarm_1=0;
            return;
        }
    }
}

 





List of 9 messages in thread
TopicAuthorDate
Please assess the c code written by me            01/01/70 00:00      
   Lots of details to improve on            01/01/70 00:00      
      REALLY confusing            01/01/70 00:00      
      timer delay review            01/01/70 00:00      
      what about this timer program            01/01/70 00:00      
         Still a lot of work to do            01/01/70 00:00      
            I have implemented many of the suggestions            01/01/70 00:00      
               Still not thinking about your symbol names            01/01/70 00:00      
                  variable name dilema            01/01/70 00:00      

Back to Subject List