| ??? 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;
}
}
}
|
| Topic | Author | Date |
| 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 |



