__________

Designing the Future with Circuits

반도체 회로설계 취준기

하만(Harman) 세미콘 반도체 설계 과정/임베디드 시스템을 위한 SW 구조설계

하만(Harman) 세미콘 아카데미 17일차 - SW 구조설계(주방 타이머 설계 이어서)

semicon_circuitdesigner 2024. 3. 29. 11:21

[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. 수정 후 작동 영상

 

  • 사용 전체 코드정리, 주석으로 변수와 함수 설명
  • 남은 과제: 실행 시 시간 표시할 수 있는 기능 추가