[2024.03.29.금] 인천인력개발원 하만 세미콘 아카데미
임베디드 시스템을 위한 SW 구조설계
실습 1: 주방 타이머 설계
1. 처음 실행 시 시간을 설정하기 위해 화면이 깜빡이는 코드 작성
case 0: //처음 시간 설정 모드
switch(settimeth){
case 0:
timeup = 0; timedown = 0; complete = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){
display_character(settimeth, 1);
_delay_ms(500);
display_character(settimeth, 0);
_delay_ms(500);
}
if ( time >= 0 & timeup != 0 ){
display_digit(settimeth, time);
_delay_ms(500);
display_character(settimeth, 1);
_delay_ms(500);
}
if(complete == 1){
timearr[settimeth] = time;
_delay_ms(500);
break;
}
}
display_character(settimeth, 1); settimeth++; complete = 0;
break;
case 1:
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){
display_character(settimeth, 1);
_delay_ms(500);
display_character(settimeth, 0);
_delay_ms(500);
}
if ( time >= 0 & timeup != 0 ){
display_digit(settimeth, time);
_delay_ms(500);
display_character(settimeth, 1);
_delay_ms(500);
}
if(complete == 1){
timearr[settimeth] = time;
_delay_ms(500);
break;
}
}
display_character(settimeth, 1); settimeth++; complete = 0;
break;
case 2:
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){
display_character(settimeth, 1);
_delay_ms(500);
display_character(settimeth, 0);
_delay_ms(500);
}
if ( time >= 0 & timeup != 0 ){
display_digit(settimeth, time);
_delay_ms(500);
display_character(settimeth, 1);
_delay_ms(500);
}
if(complete == 1){
timearr[settimeth] = time;
_delay_ms(500);
break;
}
}
display_character(settimeth, 1); settimeth++; complete = 0;
break;
case 3:
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){
display_character(settimeth, 1);
_delay_ms(500);
display_character(settimeth, 0);
_delay_ms(500);
}
if ( time >= 0 & timeup != 0){
display_digit(settimeth, time);
_delay_ms(500);
display_character(settimeth, 1);
_delay_ms(500);
}
if(complete == 1){
timearr[settimeth] = time;
_delay_ms(500);
break;
}
}
display_character(settimeth, 1); settimeth++; complete = 0;
break;
}//시간 설정 종료
break;
- 각 케이스의 숫자는 시간을 입력할 자릿수를 나타냄
- 아직 입력이 없다면 -를 표시
- 입력이 생기면 0~9까지의 숫자를 표시
- SW3버튼을 누르면 값을 숫자배열에 저장 후 다음 칸으로 넘김
2. 시간 설정 후 mode가 1로 넘어가며 설정한 시간이 화면에 나타나도록 코드 작성
switch (mode){ //처음 시작하면 mode가 0이므로 초기 시간 설정화면 코드
case 0: //처음 시간 설정 모드
switch(settimeth){
case 0: //10분 단위 설정
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){ //timeup이 0이면 버튼을 누르지 않았으므로 - 표시
display_character(settimeth+1, 1);
_delay_ms(500);
display_character(settimeth+1, 0);
_delay_ms(500);
}
else{ //timeup이 0이 아니면 버튼을 눌렀으므로 화면에 숫자 표시
if ( time > 9) time = 9; //10분 단위는 9이상 올라갈 수 없으므로 최댓값 9로 설정
if ( time <= 0) time = 0; //시간은 0 이하 내려갈 수 없으므로 최솟값 0로 설정
timearr[3-settimeth] = numb[time];
display_digit(settimeth+1, time);
_delay_ms(500);
display_character(settimeth+1, 1);
_delay_ms(500);
}
if(complete == 1){ //sw3을 누르면 탈출, 다음 숫자로 넘김
_delay_ms(1000);
break;
}
}
_delay_ms(500);
complete = 0;
settimeth = 1;
break;
case 1: //1분 단위 설정
complete = 0;
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){ //timeup이 0이면 버튼을 누르지 않았으므로 - 표시
display_character(settimeth+1, 1);
_delay_ms(500);
display_character(settimeth+1, 0);
_delay_ms(500);
}
else{ //timeup이 0이 아니면 버튼을 눌렀으므로 화면에 숫자 표시
if ( time > 9) time = 9; //10분 단위는 9이상 올라갈 수 없으므로 최댓값 9로 설정
if ( time <= 0) time = 0; //시간은 0 이하 내려갈 수 없으므로 최솟값 0로 설정
timearr[3-settimeth] = numb[time]+0x80;
display_digit(settimeth+1, time);
_delay_ms(500);
display_character(settimeth+1, 1);
_delay_ms(500);
}
if(complete == 1){ //sw3을 누르면 탈출, 다음 숫자로 넘김
_delay_ms(1000);
break;
}
}
_delay_ms(500);
settimeth =2;
break;
case 2: //10초 단위 설정
complete = 0;
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){ //timeup이 0이면 버튼을 누르지 않았으므로 - 표시
display_character(settimeth+1, 1);
_delay_ms(500);
display_character(settimeth+1, 0);
_delay_ms(500);
}
else{ //timeup이 0이 아니면 버튼을 눌렀으므로 화면에 숫자 표시
if ( time > 9) time = 9; //10분 단위는 9이상 올라갈 수 없으므로 최댓값 9로 설정
if ( time <= 0) time = 0; //시간은 0 이하 내려갈 수 없으므로 최솟값 0로 설정
timearr[3-settimeth] = numb[time];
display_digit(settimeth+1, time);
_delay_ms(500);
display_character(settimeth+1, 1);
_delay_ms(500);
}
if(complete == 1){ //sw3을 누르면 탈출, 다음 숫자로 넘김
_delay_ms(1000);
break;
}
}
_delay_ms(500);
settimeth =3;
break;
case 3://1초 단위 설정
complete = 0;
timeup = 0; timedown = 0;
while(1){
time = timeup - timedown;
if(timeup == 0){ //timeup이 0이면 버튼을 누르지 않았으므로 - 표시
display_character(settimeth+1, 1);
_delay_ms(500);
display_character(settimeth+1, 0);
_delay_ms(500);
}
else{ //timeup이 0이 아니면 버튼을 눌렀으므로 화면에 숫자 표시
if ( time > 9) time = 9; //10분 단위는 9이상 올라갈 수 없으므로 최댓값 9로 설정
if ( time <= 0) time = 0; //시간은 0 이하 내려갈 수 없으므로 최솟값 0로 설정
timearr[3-settimeth] = numb[time];
display_digit(settimeth+1, time);
_delay_ms(500);
display_character(settimeth+1, 1);
_delay_ms(500);
}
if(complete == 1){ //sw3을 누르면 탈출, 다음 숫자로 넘김
_delay_ms(1000);
break;
}
}
_delay_ms(500);
mode = 1;
break;
}//시간 설정 종료
break;
//시간 설정 종료 후 sw1을 누르면 타이머 작동 시작
case 1:
opt = 0;
switch(opt){//타이머 작동 후 sw1 opt에 대한 작업
case 0: //시작하기 전 설정 시간 표시
FND_4(timearr);
break;
case 1: //시간 흘러가도록 설정
while(1){
if(cnt > 0x10000) cnt = 0; //
Display(cnt);
}
break;
}
break;
}//switch mode
3. 작동 확인
4. 시간 설정 후 SW1을 누르면 타이머가 시작되고, 설정 시간에 도달하면 타이머 정지(case1)
case 1:
opt = 0;
endtime = min10 * 600 + min1 * 60 + sec10 * 10 + sec1; //끝나는 시간이 cnt와 맞을 때 종료하도록 값 설정
if (opt == 0) {
while(opt == 0){
FND_4(timearr);
}
}
while(cnt != endtime){
if(cnt > 0x10000) cnt = 0; //
Display(cnt);
}
if(cnt == endtime){ //시간이 맞으면 LED 점멸, RESET을 누르면
}
break;//타이머 작동 종료
}//switch mode
5. 작동 확인
6. 작동 종료 후 LED가 깜빡이도록 하기 위해 기본 설정 묶음에 DDRA = 0x07;로 led가 연결된 a의 7번 포트를 출력용으로 설정
DDRA |= 0x80; //A포트의 7번 비트를 출력으로 설정1000 0000
7. case1(타이머 작동) 구문 내에 if문과 while문을 이용하여 시간에 도달하면 LED를 점멸하고, RESET버튼을 누르면 처음으로 도달하도록 설정
if(cnt == endtime){ //시간이 맞으면 LED 점멸, RESET을 누르면
while(reset == 0){ //reset이 눌리면 끝나도록
PORTA |= 0x80; //Port A의 7번째 비트를 1(HIGH)로 설정
_delay_ms(500);
PORTA &= ~0x80; //Port A의 7번째 비트를 0(LOW)로 설정
_delay_ms(500);
}
}
if (reset != 0){ //reset버튼을 누르면 모두 초기화 후 초기 화면으로 복귀
opt=0, settimeth=0, reset=0, timeup = 0,timedown = 0, complete = 0; mode = 0;
}
8. 작동 확인
9. 타이머 실행 중 sw2를 누르면 초기화면으로 돌아가도록 while문 내에 if문 작성
while(cnt != endtime){
if(cnt > 0x10000) cnt = 0; //
Display(cnt);
if (timedown != 0){ //reset버튼을 누르면 모두 초기화 후 초기 화면으로 복귀
opt=0, settimeth=0, reset=0, timeup = 0,timedown = 0, complete = 0; mode = 0; break;
}
}
10. 작동 확인 및 전체 코드
main-timer.c
0.01MB
myHeader.h
0.00MB
Segment.c
0.00MB
11. 개선사항: 시간 설정 시 이미 설정한 시간은 함께 깜빡이도록 설정, 버튼이 두 번 눌리는 현상 해결 필요
설정 시간만 깜빡이도록 수정 완료 후 코드
main-timer.c
0.01MB
12. 위 코드 작동 영상
13. 개선사항: 작동 후 reset버튼을 누르면 제대로 초기화가 되지 않는 현상 발생
코드 수정 및 함수 적용
main-timer.c
0.01MB
14. 수정 후 작동 영상
- 사용 전체 코드정리, 주석으로 변수와 함수 설명
- 남은 과제: 실행 시 시간 표시할 수 있는 기능 추가
'하만(Harman) 세미콘 반도체 설계 과정 > 임베디드 시스템을 위한 SW 구조설계' 카테고리의 다른 글
하만(Harman) 세미콘 아카데미 60일차 - SW 구조설계(UART 시리얼 통신) (3) | 2024.06.07 |
---|---|
하만(Harman) 세미콘 아카데미 56일차 - SW 구조설계(Git 다운로드, GitHub 설정) (2) | 2024.05.31 |
하만(Harman) 세미콘 아카데미 16일차 - SW 구조설계(8비트 타이머/카운터, 16비트 타이머/카운터, 주방 타이머 설계 실습) (1) | 2024.03.28 |
하만(Harman) 세미콘 아카데미 15일차 - SW 구조설계(Pullup 저항, ATmega128 인터럽트, 스탑워치 설계) (20) | 2024.03.27 |