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

TODAY1,308 TOTAL3,324,417
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

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


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

페이지 정보

작성자 LCDnoob 작성일2022-11-16 13:26 조회5,291회 댓글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

조회수 5,291

master님의 댓글

master 작성일

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

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
질문 MSP430런치패드를 이용한 LCD 코딩 관련 질문댓글[1] 뀨쥰이 24-05-16 95
질문 Atmega128 CLCD와 블루투스 통신 문제댓글[1] fanfan 23-12-07 828
답변 답변글 답변 : Atmega128 CLCD와 블루투스 통신 문제댓글[3] master 23-12-07 1556
질문 ATmega128에서 LCD와 블루투스 fanfan 23-12-05 715
답변 답변글 답변 : ATmega128에서 LCD와 블루투스댓글[1] master 23-12-05 917
질문 atmega128 CLCD댓글[2] 릴를 23-12-03 1361
질문 atmega128 블루투스 CLCD댓글[3] 릴를 23-12-03 1747
질문 서브모터,I2C LCD, RFID, 버튼을 이용한 아두이노댓글[1] 돕고살려주세요 23-11-30 815
질문 atmega128, lm35 온도 값을 i2c lcd에 표시댓글[1] milka 23-11-16 1164
질문 atmega128 lcd led 동시 제어 ewaesdf 23-10-09 1228
답변 답변글 답변 : atmega128 lcd led 동시 제어 master 23-10-09 1246
질문 atmega128a와 i2c lcd댓글[1] 까미 23-10-04 1376
질문 atmega128a 와 캐릭터 LCD연결 방법댓글[4] 까미 23-09-30 3494
질문 타이머 인터럽트를 이용한 LCD제어 질문입니다. Tell 23-09-27 901
답변 답변글 답변 : 타이머 인터럽트를 이용한 LCD제어 질문입니다.댓글[3] master 23-09-28 1946
질문 lcd,바코드,서보모터, 아두이노 질문 드립니다. ㅠㅠ댓글[1] 아두이노개발자 23-09-26 1357
질문 LCD에 숫자 표기법을 바꾸고 싶습니댓글[2] Bs드리프터 23-09-19 1500
질문 아두이노 lcd 디지털시계 (도와주시면 감사하겠습니다!)댓글[1] 이미지첨부파일 김리 23-06-11 1463
질문 아두이노 LCD 글자 출력질문입니다. Tell 23-06-10 1252
답변 답변글 답변 : 아두이노 LCD 글자 출력질문입니다. master 23-06-10 1287
질문 아두이노 lcd 문자 스크롤디스플레이 wnion 23-05-31 1138
답변 답변글 답변 : 아두이노 lcd 문자 스크롤디스플레이댓글[1] master 23-05-31 1514
질문 앱인벤터 아두이노 보드 LCD 글씨 나타내기 질문댓글[7] 이미지 당찬병아리 23-05-29 4615
질문 토양습도센서 이용시LCD 오류댓글[5] 윤던 23-05-23 4020
질문 LCD 부저연결질문입니다.댓글[1] Tell 23-05-19 1504
질문 세그먼트 lcd출력질문입니다.댓글[1] Tell 23-05-19 1286
질문 lcd 화면에 글자가 안보이네요댓글[7] 이미지 황룡수색 23-05-19 5358
질문 lcd 모니터를 내려서 표기하댓글[5] 수포자 23-04-06 4375
질문 아두이노 a4988 스텝모터 + LCD 모니터 + 미세먼지 센서 (GP2Y1014AU0F) 이미지 JCHJ 22-12-15 2840
답변 답변글 답변 : 아두이노 a4988 스텝모터 + LCD 모니터 + 미세먼지 센서 (GP2Y1014AU0F)댓글[2] master 22-12-15 6959
게시물 검색

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
모바일버전으로보기