0. 다이아그램 및 전체 회로도
1. 1층 회로도
2. 2층 회로도
3. 3층 회로도
4. 아두이노 코드
//Updated on 2022.5.21
/*
B I N A R Y - C A C U L A T O R
===========================================================================
* <Access to 7-segment>
* Databus1 is connected with A of 74ls47(the decoder: 4-input to 7-segment)
* Databus2 is connected with B of 74ls47(the decoder: 4-input to 7-segment)
* Databus3 is connected with C of 74ls47(the decoder: 4-input to 7-segment)
* Databus4 is connected with D of 74ls47(the decoder: 4-input to 7-segment)
*
*
* D C B A Segment_Num
* ---------------------
* 0 0 0 0 0
* 0 0 0 1 1
* 0 0 1 0 2
* 0 0 1 1 3
* 0 1 0 0 4
* 0 1 0 1 5
* 0 1 1 0 6
* 0 1 1 1 7
* 1 0 0 0 8
* 1 0 0 1 9
*
*
* < Access to Decoder for Enable >
*
* DecoderLine1 is connected with A of 74ls138
* DecoderLine2 is connected with B of 74ls138
* DecoderLine3 is connected with C of 74ls138
*
* C B A Y
* --------
* 0 0 0 Y0
* 0 0 1 Y1
* 0 1 0 Y2
* 0 1 1 Y3
* 1 0 0 Y4
* 1 0 1 Y5
* 1 1 0 Y6
*
* < Port Assignment - Display >
*
* D4 : DecoderLine1 -- A 74ls138
* D5 : DecoderLine2 -- B 74ls138
* D6 : DecoderLine3 -- C 74ls138
*
* D8 : DataBus1 -- A 74ls47
* D9 : DataBus2 -- B 74ls47
* D10 : DataBus3 -- C 74ls47
* D11 : DataBus4 -- D 74ls47
*
* < Port Assignment - Switch >
*
* A0 : Toggle Swith - 1 Digit
* A1 : Toggle Swith - 2 Digit
* A2 : Toggle Swith - 3 Digit
* A3 : Toggle Swith - 4 Digit
* A4 : Toggle Swith - 5 Digit
* A5 : Changable Resistor
* D2 : Dip Switch - Mode 1
* D3 : Dip Switch - Mode 2
* D7 : Dip Switch - Mode 3
* D12 : PushButton - NextButton
*
*
*
==============================================================
*/
const int Toggle1 = 0; //A0
const int Toggle2 = 1; //A1
const int Toggle3 = 2; //A2
const int Toggle4 = 3; //A3
const int Toggle5 = 4; //A4
const int Resistor = 5; //A5
const int NextButton = 12; //D12
const int Mode1 = 2; //D2
const int Mode2 = 3; //D3
const int Mode3 = 7; //D7
const int DecoderLine1 = 4;
const int DecoderLine2 = 5;
const int DecoderLine3 = 6;
const int DataBus1 = 8;
const int DataBus2 = 9;
const int DataBus3 = 10;
const int DataBus4 = 11;
int signalChecker(int port);
void displayNum(double num);
void displayReset(void);
int numLength(int num); void endableOn(int val); void enableOff(void);
void dataDeliver(int data);
void dataDeliverReset(void);
int binaryToDecimal(int digit5, int digit4, int digit3, int digit2, int digit1);
double decimalToBinary(int num);
void enableReset(void);
void setup() {
pinMode(DataBus1, OUTPUT);
pinMode(DataBus2, OUTPUT);
pinMode(DataBus3, OUTPUT);
pinMode(DataBus4, OUTPUT);
pinMode(DecoderLine1, OUTPUT);
pinMode(DecoderLine2, OUTPUT);
pinMode(DecoderLine3, OUTPUT);
pinMode(NextButton, OUTPUT);
pinMode(Mode1, OUTPUT);
pinMode(Mode2, OUTPUT);
displayReset();
enableReset();
Serial.begin(9600);
}
int modeNum = 0;
int stage_mode1 = 1;
int stage_mode2 = 1;
int stage_mode3 = 1;
void loop() {
//mode값을 보는 것
// <1단계: 모드 인식>
if ((signalChecker(Mode1) == 1) && (signalChecker(Mode2) == 0) && (signalChecker(Mode3) == 0) && (stage_mode1 == 1)) {
Serial.println("mode1");
if (signalChecker(NextButton) == 1) {
modeNum = 1;//mode는 중복되어 스위치 켜지면 작동 안함
stage_mode1 = 2;
Serial.println("Click!");
displayNum(111111);
delay(1000);
displayNum(000000);
}
}
else if ((signalChecker(Mode2) == 1) && (signalChecker(Mode1) == 0) && (signalChecker(Mode3) == 0) && (stage_mode2 == 1)) {
Serial.println("mode2");
if (signalChecker(NextButton) == 1) {
modeNum = 2;
stage_mode2 = 2;
Serial.println("Click!");
displayNum(222222);
delay(1000);
displayNum(000000);
}
}
else if ((signalChecker(Mode3) == 1) && (signalChecker(Mode1) == 0) && (signalChecker(Mode2) == 0) && (stage_mode3 == 1)) {
Serial.println("mode3");
if (signalChecker(NextButton) == 1) {
modeNum = 3;
stage_mode3 = 2;
Serial.println("Click!");
displayNum(333333);
delay(1000);
displayNum(000000);
}
}
int sum1, sum2, total = 0;//for mode2
double total_binary = 0;//for mode2
int num1[5] = { 0,0,0,0,0 };//피연산자1 for mode2
int num2[5] = { 0,0,0,0,0 };//피연산자2 for mode2
int num3[6] = { 0,0,0,0,0,0 };//for mode3
if (modeNum == 1) {
int val;
int num = 0;
while (stage_mode1 == 2) {
Serial.println("Mode1 Entering");
val = analogRead(Resistor) - 50;
//가변저항을 0으로 맞추면 저항값이 16으로 인식되는 문제가 발생하므로 수를 낮춰주었다. 디공의 biased exponent 차용
if (val <= 0) {
num = 0;
displayNum(num);
}
else {
num = val / 13;
if (num > 63) {
num = 63;
displayNum(num);
}
else {
displayNum(num);
}
}
Serial.println(num);
delay(150);
if (signalChecker(NextButton) == 1) {
Serial.println("Click!");
Serial.print("User Choose ");
Serial.println(num);
Serial.print("Binary Number ");
Serial.println(decimalToBinary(num));
stage_mode1 = 3;
modeNum = 0;
displayNum(decimalToBinary(num));
}
}
}
else if (modeNum == 2) {//토글 입력-> FND로 출력
// <2단계 : 피연산자1 입력 및 출력>
while (stage_mode2 == 2) {
Serial.println("Stage 2 operator1 Entering");
// <사용자 입력부>
if (signalChecker(A0) == 1) { num1[0] = 1; }//만약 스위치가 켜졌다면 피연산자 그 자리수에는 1을 넣는다.
else { num1[0] = 0; }
if (signalChecker(A1) == 1) { num1[1] = 1; }
else { num1[1] = 0; }
if (signalChecker(A2) == 1) { num1[2] = 1; }
else { num1[2] = 0; }
if (signalChecker(A3) == 1) { num1[3] = 1; }
else { num1[3] = 0; }
if (signalChecker(A4) == 1) { num1[4] = 1; }
else { num1[4] = 0; }
delay(100);
Serial.println(num1[4]);
Serial.println(num1[3]);
Serial.println(num1[2]);
Serial.println(num1[1]);
Serial.println(num1[0]);
delay(100);
if (signalChecker(NextButton) == 1) {
stage_mode2 = 3;
Serial.println("Click!");
sum1 = binaryToDecimal(num1[4], num1[3], num1[2], num1[1], num1[0]);//피연산자1을 10진수로 변환
//sum1 = num1[4] * 2 * 2 * 2 * 2 + num1[3] * 2 * 2 * 2 + num1[2] * 2 * 2 + num1[1] * 2 + num1[0];
Serial.print("deoperator1 ");
Serial.println(sum1);
stage_mode2 = 3;
displayNum(sum1);//입력한 번호 출력
delay(500);
}
}
// <3단계 : 피연산자2 입력 및 출력>
while (stage_mode2 == 3) {
Serial.println("Stage 3 operator2 Entering");
// <사용자 입력부>
if (signalChecker(A0) == 1) { num2[0] = 1; }//만약 스위치가 켜졌다면 피연산자 그 자리수에는 1을 넣는다.
else { num2[0] = 0; }
if (signalChecker(A1) == 1) { num2[1] = 1; }
else { num2[1] = 0; }
if (signalChecker(A2) == 1) { num2[2] = 1; }
else { num2[2] = 0; }
if (signalChecker(A3) == 1) { num2[3] = 1; }
else { num2[3] = 0; }
if (signalChecker(A4) == 1) { num2[4] = 1; }
else { num2[4] = 0; }
delay(100);
Serial.println(num2[4]);
Serial.println(num2[3]);
Serial.println(num2[2]);
Serial.println(num2[1]);
Serial.println(num2[0]);
delay(100);
if (signalChecker(NextButton) == 1) {
stage_mode2 = 4;
Serial.println("Click!");
sum2 = binaryToDecimal(num2[4], num2[3], num2[2], num2[1], num2[0]);//피연산자2을 10진수로 변환
total = sum1 + sum2;
Serial.print("deoperator2 ");
Serial.println(sum2);
//sum2 = num2[4] * 2 * 2 * 2 * 2 + num2[3] * 2 * 2 * 2 + num2[2] * 2 * 2 + num2[1] * 2 + num2[0];
displayNum(sum2);//입력한 번호 출력
delay(500);
}
}
//<4단계 : 합 출력>
while (stage_mode2 == 4) {
if (signalChecker(NextButton) == 1) {
total_binary = decimalToBinary(total);
Serial.print("Total Sum ");
Serial.println(total);
displayNum(total);//합 출력
delay(2000);
Serial.print("Total Sum For Binary ");
Serial.println(total_binary);
displayNum(total_binary);//합 출력
stage_mode2 == 5;
modeNum = 0;
}
}
}
else if (modeNum == 3) {
//Not desiged yet
while (stage_mode3 == 2) {
Serial.println("Mode3 : Enter Binary Number");
if (signalChecker(A0) == 1) { num3[0] = 1; }//만약 스위치가 켜졌다면 피연산자 그 자리수에는 1을 넣는다.
else { num3[0] = 0; }
if (signalChecker(A1) == 1) { num3[1] = 1; }
else { num3[1] = 0; }
if (signalChecker(A2) == 1) { num3[2] = 1; }
else { num3[2] = 0; }
if (signalChecker(A3) == 1) { num3[3] = 1; }
else { num3[3] = 0; }
if (signalChecker(A4) == 1) { num3[4] = 1; }
else { num3[4] = 0; }
delay(100);
Serial.println(num3[4]);
Serial.println(num3[3]);
Serial.println(num3[2]);
Serial.println(num3[1]);
Serial.println(num3[0]);
delay(100);
if (signalChecker(NextButton) == 1) {
stage_mode3 = 3;
Serial.println("Click!");
int convertNum = binaryToDecimal(num3[4], num3[3], num3[2], num3[1], num3[0]);//피연산자2을 10진수로 변환
Serial.print("Converted Number ");
Serial.println(convertNum);
displayNum(convertNum);//입력한 번호 출력
}
}
}
}
int signalChecker(int port) {
int total = 0;
for (int i = 0; i < 3; i++) {
total = total + digitalRead(port);
delay(10);
}
if (total >= 2) {
return 1;
}
else {
return 0;
}
}
void displayNum(double num) {//숫자입력시 그 숫자 Fnd에 발광 //303입력하면 3 , 0, 3 이렇게 fnd에 입력된다.
int digit[6] = { 0,0,0,0,0,0 };//num이 304이면 403000이렇게 입력됨 000304
double temp = num;
for (int i = 5; i >= 0; i--) {
digit[i] = (int)(temp / (pow(10, i)));
temp = temp - (digit[i] * (pow(10, i)));
}
for (int i = 0; i < 6; i++) {//enable 한 상태로 데이터 전달
enableOn(i + 1);
dataDeliver(digit[i]);
delay(10);
}
}
void displayReset(void) {
for (int i = 0; i < 6; i++) {//enable 한 상태로 데이터 전달
enableOn(i + 1);
dataDeliverReset();
delay(10);
}
}
int numLength(int num) {
for (int i = 0; i < 6; i++) {
int a = 0;
a = num / (10 ^ i);
if (a == 0) {
return (i);
}
}
}
void enableOn(int val) {// val: 몇번째 Fnd
switch (val) {
case 1://Y5(첫번째 자리 FND)
digitalWrite(DecoderLine3, HIGH);//C B A에 101 신호 전달
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, HIGH);
break;
case 2://Y4(두번째 자리 FND)
digitalWrite(DecoderLine3, HIGH);//C B A에 100 신호 전달
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, LOW);
break;
case 3://Y3(세번째 자리 FND)
digitalWrite(DecoderLine3, LOW);//C B A에 011 신호 전달
digitalWrite(DecoderLine2, HIGH);
digitalWrite(DecoderLine1, HIGH);
break;
case 4://Y2(네번째 자리 FND)
digitalWrite(DecoderLine3, LOW);//C B A에 010 신호 전달
digitalWrite(DecoderLine2, HIGH);
digitalWrite(DecoderLine1, LOW);
break;
case 5://Y1(다섯번째 자리 FND)
digitalWrite(DecoderLine3, LOW);//C B A에 001 신호 전달
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, HIGH);
break;
case 6://Y0(여섯번째 자리 FND)
digitalWrite(DecoderLine3, LOW);//C B A에 000 신호 전달
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, LOW);
break;
}
}
void enableReset(void) {
digitalWrite(DecoderLine3, LOW);//C B A에 110 신호 전달 Y6 enable
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, LOW);
delay(10);
}
void enableOff(void) {
digitalWrite(DecoderLine3, LOW);//C B A에 110 신호 전달 Y6 enable
digitalWrite(DecoderLine2, LOW);
digitalWrite(DecoderLine1, LOW);
delay(10);
}
void dataDeliverReset(void) {
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, LOW);
delay(10);
}
void dataDeliver(int data) {//출력하고 싶은 숫자를 입력받으면 그것을 databus로 송신하는 함수
switch (data) {
case 0://D C B A 에 0000 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, LOW);
break;
case 1://D C B A 에 0001 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, HIGH);
break;
case 2://D C B A 에 0010 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, HIGH);
digitalWrite(DataBus1, LOW);
break;
case 3://D C B A 에 0011 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, HIGH);
digitalWrite(DataBus1, HIGH);
break;
case 4://D C B A 에 0100 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, HIGH);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, LOW);
break;
case 5://D C B A 에 0101 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, HIGH);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, HIGH);
break;
case 6://D C B A 에 0110 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, HIGH);
digitalWrite(DataBus2, HIGH);
digitalWrite(DataBus1, LOW);
break;
case 7://D C B A 에 0111 신호전달
digitalWrite(DataBus4, LOW);
digitalWrite(DataBus3, HIGH);
digitalWrite(DataBus2, HIGH);
digitalWrite(DataBus1, HIGH);
break;
case 8://D C B A 에 1000 신호전달
digitalWrite(DataBus4, HIGH);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, LOW);
break;
case 9://D C B A 에 1001 신호전달
digitalWrite(DataBus4, HIGH);
digitalWrite(DataBus3, LOW);
digitalWrite(DataBus2, LOW);
digitalWrite(DataBus1, HIGH);
break;
}
}
double decimalToBinary(int num) {
//1011이런식으로 배열있으면 1101로 읽는다.
//2진수 값은 인덱스 i일때 시그마{ (*(arr+i))*(2^i)}
int arr[6] = { 0,0,0,0,0,0 };
int temp = num;
int devider = 0;
int remain = 0;
for (int i = 0; i < 5; i++) {
if (i != 4) {
devider = temp / 2;
remain = temp % 2;
temp = devider;
arr[i] = remain;
}
else if (i == 4) {
devider = temp / 2;
remain = temp % 2;
arr[i + 1] = devider;
arr[i] = remain;
}
}
double total = arr[5] * pow(10, 5) + arr[4] * pow(10, 4) + arr[3] * pow(10, 3) + arr[2] * pow(10, 2) + arr[1] * pow(10, 1) + arr[0];
return total;
}
int binaryToDecimal(int digit5, int digit4, int digit3, int digit2, int digit1) {
int decimalNum = digit1 + digit2 * 2 + digit3 * 2 * 2 + digit4 * 2 * 2 * 2 + digit5 * 2 * 2 * 2 * 2;
return decimalNum;
}
5. 부품
-Dip스위치 4개 짜리 1개
-토글스위치 5개
-푸쉬 스위치 1개
-Anode type 7-Segment 6개
-100Ω 저항 74개
-아두이노 우노
-74LS47 6개
-74LS75 6개
-74LS138 1개
-74LS04 1개
-땜납실
-가변저항 1개
-전선
-커넥터 케이블
6. 결선
* D4 : DecoderLine1
* D5 : DecoderLine2
* D6 : DecoderLine3
* D8 : DataBus1
* D9 : DataBus2
* D10 : DataBus3
* D11 : DataBus4
* A0 : 토글 스위치 - 1 Digit
* A1 : 토글 스위치 - 2 Digit
* A2 : 토글 스위치 - 3 Digit
* A3 : 토글 스위치 - 4 Digit
* A4 : 토글 스위치 - 5 Digit
* A5 : 가변 저항
* D2 : 딥 스위치 - Mode 1
* D3 : 딥 스위치 - Mode 2
* D7 : 딥 스위치 - Mode 3
* D12 : 푸쉬 스위치
7. 동작 알고리즘
8. 사진
1). 1층회로
2). 2층회로
3). 3층회로
4). 전체 사진
9. 참고자료
(1). 74HC138 Renesas DataSheet
(2). 74HC04 DataSheet
(3). DM74ls75 DataSheet
(4). HD74ls47
(5). Digital Design and Computer Architecture, 2nd Edition, David Harris
'6_Project > 이진 가산기' 카테고리의 다른 글
2022-1 프로젝트 : 이진 가산기 및 변환기_시연 영상 (0) | 2022.11.15 |
---|