질문게시판 > 3x4 키패드를 이용한 LCD 계산기 코딩 질문입니다.

TODAY437 TOTAL2,679,144
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 3x4 키패드를 이용한 LCD 계산기 코딩 질문입니다.

페이지 정보

작성자 LCDnoob 작성일2022-11-16 13:26 조회1,445회 댓글1건

첨부파일

본문

	



image.png

#define F_CPU 16000000UL

#include

#include

#include

#include

#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 YES 12 // 숫자는 의미 없음. 분별을 위한 임의의 값

#define NO 34

#define PASS 56

#define ERROR 78

unsigned char char_address = 0x80; // CLCD 1열 첫번째 문자위치 어드레스

unsigned char keypad_press = NO; // 키패드의 버튼이 눌렸는지의 여부

unsigned char operand1_complete = NO; // 피연산자1의 입력이 완료되었는지의 여부

unsigned char operand2_complete = NO; // 피연산자2의 입력이 완료되었는지의 여부

unsigned char operator_complete = NO; // 연산자의 입력이 완료되었는지의 여부

unsigned char overflow_flag = NO; // 값이 자료형의 사이즈를 벗어났는지의 여부

char val_buffer; // 데이터 값 버퍼

char key_buffer; // 키 값 버퍼

void LCD_cmd(unsigned char cmd) // LCD에 command를 입력함수

{

LCD_CMD_PORT = 0x00; // Instruction register 선택, Write Disable

LCD_DB_PORT = cmd; // LCD data bus에 command 출력

LCD_CMD_PORT = 0x01; // Write Enable

_delay_us(1); // LCD 명령처리 지연시간

LCD_CMD_PORT = 0x00; // Write Disable

_delay_us(100); // LCD 명령처리 지연시간

}

void LCD_init(void) // LCD 초기화 함수(Initialize)

{

LCD_cmd(0x38); // Function set (data length-8bit, 2행, 5x8dote)

LCD_cmd(0x0F); // Display on/off control(화면출력 ON, 커서표시 & 커서깜빡임 OFF)

LCD_cmd(0x06); // Entry mode set(커서 오른쪽 이동, 화면이동 OFF)

LCD_cmd(0x01); // Clear display

_delay_ms(2);

}

void LCD_data(unsigned char data) // LCD Data 전송 함수

{

LCD_CMD_PORT = 0x02; // Data register 선택, Write Disable

LCD_DB_PORT = data; // LCD data bus에 Data 출력

LCD_CMD_PORT = 0x03; // Write Enable

_delay_us(1);

LCD_CMD_PORT = 0x02; // Write Disable

_delay_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);

}

void buzzer(void) // 부저 울림 함수

{

PORTF = 0x01;

_delay_ms(50); // 50ms 동안만

PORTF = 0x00;

}

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 = '#';

key_buffer = 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 // 키가 눌린 적이 없다면

{

if (key_buffer != ' ' ) buzzer(); // 키가 눌리면 부저 1회 울림

keypad_press = YES;

return input;

}

}

}

void Title_display(void) // 초기 타이틀 화면 출력 함수

{

LCD_print(0x80," DIGITAL "); // 1열 문자열 출력

LCD_print(0xC0," CALCULATOR "); // 2열 문자열 출력

}

int Ch_to_int(char *val) // 입력된 문자열을 정수로 변환하는 함수

{

long total = atol(val); // 문자열 배열을 long 형 정수로

if (32768 > total && total >= 0) return total; // 입력값이 0 ~ 2^15 범위 안이면

else // 범위를 초과하면

{

overflow_flag = YES;

return 0;

}

}

int Operand1_entering() // 피연산자 1 입력함수

{

char val;

char operand[5] = {0}; // 입력값이 저장 될 문자열 배열

int operand1 = 0;

unsigned int i=0;

unsigned char entering_start = NO; // 입력이 시작되었는지의 여부(처음엔 숫자 이외엔 못 누르게 하기 위해)

while(operand1_complete != YES) // 첫번째 피연산자 입력이 완료될 때까지 무한루프

{

val = keypad_db_input();

if (val == ' ') continue; // 입력이 없으면 Continue

else if(val != '*' && val != '#') // 숫자를 누르면

{

entering_start = YES;

operand[i++] = val; // 배열에 입력된 숫자 저장

LCD_char_print(char_address++, &val); // CLCD 해당 문자주소에 문자 출력

if(i == 5) // 5자리까지 숫자가 입력되면

{

while(Keypad_input() != '*'); // 연산자 선택버튼(*)을 누를 때까지 대기

operand1_complete = YES;

}

}

else if (val == '*' && entering_start == YES) // 연산자 선택버튼(*)을 누르면 피연산자1 입력완료

{

operand1_complete = YES;

}

}

operand1 = Ch_to_int(operand);

return operand1;

}

int Operator_entering() // 연산자 입력 함수

{

char val;

unsigned int i=0;

char operator[4] = {'+','-','*','/'};

char operator_num = 0;

LCD_char_print(char_address, &operator[i++]); // CLCD 1열의 해당 문자주소에 해당 연산자 출력

while(operator_complete != YES) // 연산자 입력이 완료될 때까지 무한루프

{

val = keypad_db_input();

if (val == ' ' || val == '#') continue; // 공백문자나 '#'버튼 누름은 무시

else if(val == '*') // 연산자 선택버튼(*)이 눌러지면

{

if (i == 4 ) i = 0;

LCD_char_print(char_address, &operator[i]); // CLCD의 해당 문자주소에 해당 연산자 출력

operator_num = i++;

}

else if(val != '*' && val != '#') // 숫자를 눌렀을 때

{

val_buffer = val;

char_address++;

operator_complete = YES; // 연산자 선택 완료

}

}

return operator_num;

}

int Operand2_entering() // 피연산자 2 입력함수

{

char val;

char operand[5] = {0}; // 입력값이 저장 될 문자열 배열

int operand2 = 0;

unsigned int i=1;

operand[0] = val_buffer; // 이전에 눌렸던 숫자값을 저장

LCD_char_print(char_address++, &val_buffer); // CLCD 해당 문자주소에 문자 출력

while(operand2_complete != YES) // 두번째 피연산자 입력이 완료될 때까지 무한루프

{

val = keypad_db_input();

if (val == ' ' || val == '*') continue;

else if(val != '*' && val != '#') // 숫자를 누르면

{

operand[i++] = val; // 배열에 입력된 숫자 저장

LCD_char_print(char_address++, &val); // CLCD 해당 문자주소에 문자 출력

if(i == 5) // 5자리까지 숫자가 입력되면

{

while(Keypad_input() != '#'); // 결과출력버튼(#)을 누를 때까지 대기

operand2_complete = YES;

}

}

else if (val == '#') // 결과출력버튼(#)을 누르면 피연산자2 입력완료

{

operand2_complete = YES;

}

}

operand2 = Ch_to_int(operand);

return operand2;

}

char Result_check(long val) // 결과값이 자료형 사이즈를 오버하였는지 검사하는 함수

{

if (2147483648 > val && val > -2147483648) // 자료가 -2^31 ~ 2^31 범위(32비트) 안이라면

{

return PASS;

}

else return ERROR;

}

void Calculating(long opr1,long opr2,int opt) // 결과값 계산 함수

{

long i_result = 0;

float f_result = 0;

char check_result = 0 ;

char str[16];

switch(opt)

{

case 0: // 덧셈 연산

i_result = opr1 + opr2;

break;

case 1: // 뺄셈 연산

i_result = opr1 - opr2;

break;

case 2: // 곱셈 연삼

i_result = opr1 * opr2;

check_result = Result_check(i_result); // 곱셈은 자료형 이상의 값이 나올 수 있으므로 검사

if (check_result == ERROR) opt = ERROR; // 자료형 이상의 값이 나올경우 에러메세지 출력

break;

case 3: // 나눗셈 연산

f_result = (float)opr1 / opr2;

break;

}

switch(opt)

{

case 0: // 덧, 뺄, 곱셈 연산의 경우 정수 출력

case 1:

case 2:

sprintf(str,"%15ld",i_result);

LCD_print(0xC0,str);

break;

case 3: // 나눗셈 연산의 경우 실수 출력

sprintf(str,"%15.2f",(double)f_result); // sprintf는 float형을 지원하지 않으므로 double로 형변환

LCD_print(0xC0,str);

break;

case ERROR: // 결과값이 자료형을 초과할 경우 에러메세지 출력

sprintf(str," VALUE ERROR ");

LCD_print(0xC0,str);

}

}

void Initialize() // 변수 초기화 함수

{

char_address = 0x80;

operand1_complete = NO;

operand2_complete = NO;

operator_complete = NO;

overflow_flag = NO;

LCD_cmd(0x01); // Clear display

}

int main(void) // 메인함수

{

DDRD = 0x0F; // pin 0,1,2,3 은 키패드의 Row(출력)

PORTD = 0xFF; // pin 4,5,6 은 키패드의 Column(입력)

DDRF = 0xFF;

PORTF = 0x00;

LCD_DB_DDR = 0xFF; // LCD data bus, LCD command port 출력모드

LCD_CMD_DDR = 0xFF;

LCD_DB_PORT = 0x00;

LCD_CMD_PORT = 0x00;

int operand1,operand2,operator; // 피연산자와 연산자 선언

char str[16];

LCD_init();

_delay_us(50); // 명령처리 대기시간

Title_display();

_delay_ms(2000);

LCD_cmd(0x01); // Clear display

while(1)

{

operand1 = Operand1_entering();

operator = Operator_entering();

operand2 = Operand2_entering();

if(overflow_flag == YES) // 피연산자 중 자료형을 초과한 것이 있다면

{

sprintf(str," VALUE OVERFLOW "); // 에러메세지 출력

LCD_print(0xC0,str);

}

else Calculating(operand1,operand2,operator);

while(keypad_db_input() != '#'); // 연산이 끝나면 대기하다가 '#'를 누르면 초기화 후 연산시작

Initialize();

}

}

image.png

4x3키패드로 LCD에 사칙연산을 하는 회로이며

소스코드에서 에러가 왜 뜨는지 알 수가 없습니다 ㅠ

혹시 알려주실 수 있으신가요?

 

빨간 글씨가 에러 부분입니다. 소스코드 파일도 같이 첨부합니다.

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 1

조회수 1,445

master님의 댓글

master 작성일

#include <avr/io.h>
int main(){}
이런 간단한 코드로 컴파일 해보세요
그래도 컴파일 오류가 발생하면 컴파일 설치를 다시 하든지 설정을 체크 해보셔야 합니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
질문 토양습도센서 이용시LCD 오류댓글[5] 윤던 23-05-23 38
질문 LCD 부저연결질문입니다.댓글[1] Tell 23-05-19 52
질문 세그먼트 lcd출력질문입니다.댓글[1] Tell 23-05-19 58
질문 lcd 화면에 글자가 안보이네요댓글[7] 이미지 황룡수색 23-05-19 78
질문 lcd 모니터를 내려서 표기하댓글[5] 수포자 23-04-06 277
질문 아두이노 a4988 스텝모터 + LCD 모니터 + 미세먼지 센서 (GP2Y1014AU0F) 이미지 JCHJ 22-12-15 725
답변 답변글 답변 : 아두이노 a4988 스텝모터 + LCD 모니터 + 미세먼지 센서 (GP2Y1014AU0F)댓글[2] master 22-12-15 1413
질문 아두이노 심박센서 및 LCD로 BPM나타내기 질문있습니다.댓글[2] 이미지첨부파일 공백 22-12-12 1263
질문 (MCU) LCD와 인터럭트궁금한 부분이있어 질문드립니다댓글[1] 권철숙 22-12-03 513
질문 ATMEGA128 가변저항을 이용해 값을 LCD로 받고싶습니다.댓글[1] 납땜마스터 22-12-01 1051
질문 Atmega128 가변저항을 이용해 lcd에 설정값 띄우기 납땜마스터 22-12-01 938
답변 답변글 답변 : Atmega128 가변저항을 이용해 lcd에 설정값 띄우기 master 22-12-01 960
질문 USART를 이용한 LCD출력댓글[2] 이름두글자 22-11-29 1013
질문 stm32 tft(LCD) ILI9341 문제점 조언댓글[3] 첨부파일 지산동괴물쥐 22-11-26 1736
질문 LED, LCD, 버튼, 부저 0922tjdus 22-11-24 1423
답변 답변글 답변 : LED, LCD, 버튼, 부저 master 22-11-24 1092
질문 아두이노 우노 압력센서 LCD 코딩 문제댓글[16] 이미지첨부파일 또혀이 22-11-18 11999
답변 답변글 답변 : 아두이노 우노 압력센서 LCD 코딩 문제 이미지 master 22-11-19 1151
질문 인터럽트 활성화시 LCD 오류 발생 마프하나 22-11-16 1134
답변 답변글 답변 : 인터럽트 활성화시 LCD 오류 발생 master 22-11-17 862
현재글 3x4 키패드를 이용한 LCD 계산기 코딩 질문입니다.댓글[1] 첨부파일 LCDnoob 22-11-16 1446
질문 Lcd실드 모듈 연결해서 lcd만 사용할 수 있나요?댓글[2] 이미지첨부파일 떼잉 22-11-13 1454
질문 아두이노 lcd 오류 질문댓글[2] 이미지첨부파일 아두이노진구 22-11-11 1801
질문 (도와주세요ㅠ) 초음파센서로 lcd와 부저 울리기 첨부파일 승천 22-11-06 1602
답변 답변글 답변 : (도와주세요ㅠ) 초음파센서로 lcd와 부저 울리기댓글[4] master 22-11-06 3231
질문 초음파 센서를 이용해서 lcd거리측정에 부저 집어넣기...댓글[1] 이미지첨부파일 승천 22-11-04 1973
질문 시리얼 모니터를 통한 LCD 문자 출력 시 오류(괴문자)댓글[2] 이미지첨부파일 takeonefor 22-11-02 1709
질문 스텝모터,twi,LCD관련 질문 있습니다..!댓글[1] 이미지첨부파일 만두 22-10-31 2133
질문 LCD 7segment switch 인터럽트함수 변수제어 시속90 22-10-21 1525
답변 답변글 답변 : LCD 7segment switch 인터럽트함수 변수제어 master 22-10-23 1598
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기