BASIC4MCU | 질문게시판 | 답변 : codevison AVR소스코드로변환
페이지 정보
작성자 master 작성일2018-12-04 17:29 조회6,294회 댓글0건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=6278
본문
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2018-12-04 오후 5:34:20// by Ok-Hyun Park//#include <mega128.h>#include <delay.h>#include <stdio.h>//#define LCD_DB_PORT PORTA // LCD_DATABUS#define LCD_DB_DDR DDRA#define LCD_CMD_PORT PORTC // LCD_COMMAND#define LCD_CMD_DDR DDRC//#define OPEN 1#define CLOSE 2#define YES 12 // 숫자는 의미 없음.분별을 위한 임의의 값#define NO 34//unsigned char keypad_press=NO; // 키패드의 눌림표시 flagunsigned char key_press=NO; // 키의 눌림표시 flagchar password[4]={ 1,2,3,4}; // 초기 도어록 패스워드 '1234' 설정//unsigned char key_input(){ // key debouncing 함수unsigned char key;key=PINE;if(key==0b00000001)// 키가 눌리지 않았을 때(혹은 키를 눌렀다 뗏을때){if(key_press==NO)return key; // 키가 이전에 눌린 적이 없다면else // 키가 이전에 눌린적이 있다면{delay_ms(20);key_press=NO;return YES; // 스위치를 누른 후,pass_change에 YES 반환}}else // 키가 눌렸을 때{if(key_press==YES)return 0b00000001; // 키가 이전에 눌린적이 있다면else // 키가 이전에 눌린적이 없다면{delay_ms(20);key_press=YES;return key;}}}//void LCD_cmd(unsigned char cmd)// LCD에 command를 입력함수{LCD_CMD_PORT=0x00; // Instruction register 선택,Write DisableLCD_DB_PORT=cmd; // LCD data bus에 command 출력LCD_CMD_PORT=0x01; // Write Enabledelay_us(1); // LCD 명령처리 지연시간LCD_CMD_PORT=0x00; // Write Disabledelay_us(100); // LCD 명령처리 지연시간}//void LCD_init(void)// LCD 초기화 함수(Initialize){LCD_cmd(0x38); // Function set(data length-8bit,2행,5x8dote)LCD_cmd(0x0C); // Display on/off control(화면출력 ON,커서표시&커서깜빡임 OFF)LCD_cmd(0x06); // Entry mode set(커서 오른쪽 이동,화면이동 OFF)LCD_cmd(0x01); // Clear displaydelay_ms(2);}//void LCD_data(unsigned char data)// LCD Data 전송 함수{LCD_CMD_PORT=0x02; // Data register 선택,Write DisableLCD_DB_PORT=data; // LCD data bus에 Data 출력LCD_CMD_PORT=0x03; // Write Enabledelay_us(1);LCD_CMD_PORT=0x02; // Write Disabledelay_us(100);}//void LCD_print(unsigned char cmd,char*str)// LCD 문자열 출력 함수{LCD_cmd(cmd); // 출력위치 지정while(*str!=0)// 문자열의 끝이 올때까지{ LCD_data(*str);str++;}}//void LCD_char_print(unsigned char cmd,char*str)// LCD 문자 출력 함수{LCD_cmd(cmd); // 출력위치 지정LCD_data(*str);}//char Keypad_input(void)// 키패드 입력받는 함수{unsigned char input=' '; // 키 패드의 입력값,초기값은 공백문자PORTD=0xFF; // pin 0,1,2,3 은 키패드의 Row(출력)DDRD=0x0F; // pin 4,5,6 은 키패드의 Column(입력)PORTD=0b11111110; // 1번 Row 선택delay_us(1); // 명령처리 딜레이 타임if((PIND&0x10)==0)input='1';else if((PIND&0x20)==0)input='2';else if((PIND&0x40)==0)input='3';PORTD=0b11111101; // 2번 Row 선택delay_us(1);if((PIND&0x10)==0)input='4';else if((PIND&0x20)==0)input='5';else if((PIND&0x40)==0)input='6';PORTD=0b11111011; // 3번 Row 선택delay_us(1);if((PIND&0x10)==0)input='7';else if((PIND&0x20)==0)input='8';else if((PIND&0x40)==0)input='9';PORTD=0b11110111; // 4번 Row 선택delay_us(1);if((PIND&0x10)==0)input='*';else if((PIND&0x20)==0)input='0';else if((PIND&0x40)==0)input='#';return input; // 입력이 없으면 공백문자 리턴}//unsigned char keypad_db_input(void)// 키패드 입력 debouncing 함수{unsigned char input; // 키패드 입력값 변수input=Keypad_input();if(input==' ')// 키가 아무것도 눌리지 않았을 때(혹은 눌렀다 뗐을 때){if(keypad_press==NO)return input; // 키가 이전에 눌린 적이 없다면else // 키가 이전에 눌린 적이 있다면{delay_ms(20);keypad_press=NO;return input;}}else // 키가 눌렸을 때{if(keypad_press==YES)return ' '; // 키가 이전에 눌린 적이 있다면else // 키가 눌린 적이 없다면{delay_ms(20);keypad_press=YES;return input;}}}//void Title_display(void)// 초기 타이틀 화면 출력{LCD_print(0x80," DIGITAL "); // 1열 문자열 출력LCD_print(0xC0," DOOR LOCK "); // 2열 문자열 출력}//void Lock_mode_display(void)// 잠금 모드 화면 출력{LCD_print(0x80,"Enter PASSWORD!"); // 1열 문자열 출력LCD_print(0xC0,"[_ _ _ _]"); // 2열 문자열 출력}//void Pass_display(void)// 잠김해제 화면 출력{LCD_print(0x80,"Correct Password"); // 1열 문자열 출력LCD_print(0xC0," DOORLOCK OPEN "); // 2열 문자열 출력}//void Pass_change_display(void)// 패스워드 변경 화면 출력{LCD_print(0x80,"Password Change "); // 1열 문자열 출력LCD_print(0xC0,"[_ _ _ _]"); // 2열 문자열 출력}//void Fail_effect(void)// 패스워드 불일치 효과{PORTF=0b00001001;delay_ms(500);PORTF=0b00000000;}//void Pass_effect(void)// 패스워드 일치 효과{PORTF=0b00001010;delay_ms(150);PORTF=0b00000010;delay_ms(100);PORTF=0b00001010;delay_ms(250);PORTF=0b00000000;}//void Change_effect(void)// 패스워드 변경완료 효과{PORTF=0b00001010;delay_ms(200);PORTF=0b00000000;}//void Servo_work(unsigned int command)// 서보모터 동작 함수{unsigned int i;switch(command)// OPEN-90도 중립위치,CLOSE-0도{case OPEN:for(i=0; i<50; i++){ PORTB=0x01; delay_us(1500); PORTB=0x00; delay_ms(20); } // 90도(중립위치)break;case CLOSE:for(i=0; i<50; i++){ PORTB=0x01; delay_us(600); PORTB=0x00; delay_ms(20); } // 0도break;}}//void Lock_mode(void){char match_count=0; // 비밀번호 일치 카운트char val; // 키패드 입력변수unsigned char char_address=0xC4; // CLCD 2열 첫번째 문자위치 어드레스unsigned int count=0; // 입력된 문자 수Lock_mode_display();Servo_work(CLOSE); // 잠금while(1){if(PINE==0b00000000)// 스위치를 눌렀을 때{if(match_count==4)// 패스워드 네 자리가 모두 맞으면{Pass_effect();break; // 메인으로 귀환}else // 패스워드가 틀리면{Fail_effect();LCD_print(0xC0,"[_ _ _ _]"); // CLCD 2열 초기화char_address=0xC4; // 문자주소를 초기위치로match_count=0;count=0;}}val=keypad_db_input(); // 디바운싱 된 문자를 저장if(val==' '||count==4)continue; // 키패드 입력이 없거나 입력칸이 꽉 차면 countinueelse // 입력된 문자가 있다면{if(password[count++]==val-'0')match_count++; // 입력문자와 패스워드 비교LCD_char_print(char_address,&val); // CLCD 2열의 해당 문자주소에 문자 출력char_address+=2;}}Pass_display();Servo_work(OPEN); // 잠금 해제delay_ms(1000);Title_display();}//void Pass_change_mode(void){ // 패스워드 변경 모드 함수char val; // 키패드 입력변수unsigned char char_address=0xC4; // CLCD 2열 첫번째 문자위치 어드레스unsigned int count=0; // 입력된 문자 수unsigned char pass_change=NO; // 패스워드 변경완료 여부 flagPass_change_display();while(1){val=keypad_db_input(); // 디바운싱 된 문자를 저장pass_change=key_input(); // 디바운싱 된 스위치 값 저장if(count==4&&pass_change==YES)// 입력칸 다 차고 패스워드 변경 완료되었다면{Change_effect();break; // 메인으로 귀환}if(val==' '||count==4)continue; // 키패드 입력이 없거나 입력칸이 꽉 차면 countinueelse // 입력된 문자가 있다면{LCD_char_print(char_address,&val); // CLCD 2열의 해당 문자주소에 문자 출력char_address+=2;password[count++]=val-'0'; // 입력된 문자를 패스워드로 지정}}Title_display();}//void main(void){DDRB=0xFF;DDRD=0x0F; // pin 0,1,2,3 은 키패드의 Row(출력)PORTD=0xFF; // pin 4,5,6 은 키패드의 Column(입력)DDRE=0xFE; // SW 입력PORTE=0x01; // 내부 pull-up 저항 사용DDRF=0xFF;LCD_DB_DDR=0xFF; // LCD data bus,LCD command port 출력모드LCD_CMD_DDR=0xFF;LCD_DB_PORT=0x00;LCD_CMD_PORT=0x00;LCD_init();delay_us(50); // 명령처리 대기시간Title_display();Servo_work(OPEN); // 개방while(1){if(PINE==0b00000000)Lock_mode(); // 스위치를 누르면 잠금 모드if(keypad_db_input()=='#')Pass_change_mode(); // 키패드 '#'누르면 패스워드 변경모드}}
댓글 0
조회수 6,294등록된 댓글이 없습니다.