??? 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 |