Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

2017-06-17, 마이크로컴퓨터 기말고사 문제.

학번 출석번호 이름 sign 점수

TMOD: GATE, C/T,M1,M0,GATE,C/T,M1,M0 TCON:TF1,TR1,TF0,TR0,IE1,IT1,IE0,IT0


SCON: SM0,SM1,SM2,REN,TB8,RB8,TI,RI IE: EA,-,-,ES,ET1,EX1,ET0,EX0
PCON: SMOD,-,-,-,GF1,GF0,PD,IDL IP: -,-,PT2,PS,PT1,PX1,PT0,PX0

1. (10점) 시험지 뒷면에 다음 동작이 가능하게 필요한 모든 회로를 그려라.


(1). Reset 동작 (active low) (2)외부에 crystal oscillator 연결(12MHz) (3).외부 ROM을 사용하지 않음
(4). P0.0에 switch(sw), P0.1에 led를 연결. Switch는 누르면 0이되게, led는 pin에 1을 출력하면 켜지게.
(5). Switch를 누르면 interrupt ( INT 0)가 발생 가능하게 연결
2.(10점) 1번회로의 sw를 누르면 led가 toggle되게 c 코드를 작성하라.좌측 box에는 sw를 polling 방식으로
눌러진 지 검사하고 오른쪽에는 sw의 falling edge에서 interrupt(INT0)가 걸리게 코드를 작성하라. 단,
1) 실제 동작이 가능하게 정확히 기술할 것 (동작은 1회성이 아니라 sw를 누를때마다 동작)
2) sw를 input mode 설정하고 정확히 sw가 high에서 low로 떨어지는 edge에서 toggle되게 작성
3) sw와 led라는 변수를 사용 (비트 변수로 선언), (4) header 파일 include는 생략하라.

sbit led=P0^2; sbit led=P0^2;


sbit sw=P0^1; sbit sw=P0^1;
void main() void switch_isr interrupt 0
{ char tmp; { led=~led; }
sw=1; tmp=sw ; void main()
while ( 1 ) { { EA=1;EX0=1; IT0=1;// IE=0x81;TCON=1;
if ((tmp==1)&&(sw==0)) led=~led; sw=1;
tmp = sw ; while ( 1 );
} }
}

3.(10점) PC와 통신을 하면서 PC에서 받은 문자를 다시 PC로 돌려주는 C 코드를 작성하라.(header는 생략)
1). 9600bps, 8bit 1start 1stop mode(보통 모드)
2). 좌측에는 polling 방식으로 우측에는 interrupt 방식으로 동작하게
3). 코드는 동작이 가능하게 정확히 작성하고 또박또박 작성할 것 (글자를 알아보기 힘들면 감점,or 0점)

void main() void serial_isr interrupt 4


{ char rxchar; { if (RI==1) rxchar = SBUF;
TH1=-3; SCON=0x50;TMOD=0x20;TR1=1; SBUF = rxchar; }
while ( 1 ) { void main()
while(RI==0); {TH1=-3; SCON=0x50;TMOD=0x20;
RI = 0; TR1=1;IE=0x90;
rxchar = SBUF; SBUF=rxchar; while ( 1 );
} }
}
4.(10점) 8051 내부 ROM의 크기가 작아서 내부 ROM을 무시하고 외부에 ROM을 연결하였다.
a)(3점)연결을 위한 HW를(EA/P0/P2/ALE/PSEN 연결포함) 가능한 상세히 정확하게 그려라.
b)(3점)외부 ROM을 access할 때 P0(A/D),P2(A),ALE,PSEN 핀의 출력 신호 timing을 정확히 그려라.
c)(2점) tri-state inverter는 0, 1 외에 ( high impedance )상태가 가능하
A
며 입력 중 하나인 OE는 영어로 ( output enable )의 약자이다.
(d)(2점) tri-state inverter 회로를 뒷면에 그려라. (hint: mux를 활용) P0.1

P0.0
3 2
5. (10점)오른쪽 그림과 같이 0~3를 가진 미니 keypad를 연결하였다.
INT0
P1.1
(a)(3점) 평소 키가 눌러지지 않은 상태에서는 INT0에 1이 입력되어 인터럽
1 0
트가 발생하지 않고 키를 누르면 0이 입력된다. 이를 위해 P1=( 3 )로 P1.0
설정하고 A에는 ( NOR )회로를 연결해야 한다. R
keypad
R
(b)(7점) 좌측에 polling 방식, 우측에 interrupt 방식으로 눌러진 키를 스캔
하는 코드를 C 코딩하라.

char key_scan(){ char t_key, key; void key_scan_isr() ( interrupt 0 )


P1=( 1 ); // 아래 라인 스캔 { key = key_scan(); }
t_key = P0; void main()
if ( t_key&0x01==0x01 ) key=0; // 0체크 {
if ( (t_key>>1)&0x01==0x01 ) key=1; // 1체크 char key;
P1=( 2 ); // 위 라인 스캔 P0 = 0xff;
…. ( IE=0x81; ) // EXT0 인터럽트 활성화
return(key);} ( IT0 = 1 ; ) // polling edge에서 동작
void main(){ while (1);
char key; P0 = 0xff; }
while(1) key=key_scan();
}

6. (8점) 5번 문제와 연결하여 key 입력을 조사하여 0110 패턴을 찾는(예를 들면 0010011010…) 코드를 작

성한다. 이것을 mealy FSM(finite state machine) (output이 input과 state의 함수)으로 설계한다.
(a)(4점) 먼저 0110을 찾는 FSM의 state transition diagram을 아래에 그려라. 각 상태는 SX(0을 기다리는 상
태),S0(0을 수신한 상태),S01(01을 수신한 상태),S011,S0110 로 표시하라.

(b)(4점)위 FSM을 check_key()라는 함수로 작성하라. (hint: switch 문을 사용하라, key_scan_isr에서 call)
다 적으면 복잡하니, SX, S0, S01 에 대한 처리만 적어라.
enum {SX, S0, S01, S011, S0110} ST; ST state; // enum은 이름에 숫자를 할당한다. 즉, SX=0,S0=1,…
void check_key(int key) { static int state; // 상태변수를 정적 변수로 할당
switch(state) { case SX: if (key==0) state = S0; break;
case S0: if (key==1) state = S01; break;…
case S01: state = (key==1?) S011:S0; break;}}
7.(5점) 앞의 5번 문제와 연결하여 key 입력을 cmd[4] 변수에 저장하고 저장된 배열값이 “1111”이면 P2를 토
글하는 코드를 작성한다. 아래 코드를 완성하라.
char cmd[4]; char cnt=0;
void key_scan_isr()… { ( cmd[cnt++]=key_scan(); }
void main() { while(1) { if (cnt==4) { if (!strncmp(cmd,”1111”,4)) P2=~P2; } }

8.(5점) P2로 packed BCD 값이 입력된다. 이를 각각의 ASCII 코드로 변환하는 C 코드를 작성하라.
예를 들면 P2에 0x23이 입력되면 이를 ‘2’, ‘3’,즉, ASCII 숫자로 변환하여 a1, a2 변수에 저장하라.
void main () {
char t, a1, a2 ; // t: 포트에서 읽은 값, a1: 상위 바이트 ASCII, a2: 하위 바이트 ASCII 코드
P2 = 0xff; // 입력 모드 설정
t = P2; // 포트를 읽고
a1 = (t>>4) + ‘0’; // 상위 바이트 처리
a2 = t&0x0f + ‘0’; // 하위 바이트 처리
}
9. (7점) HW4의 1번째 과제는, key를 scan하여 *을 누른후 번호 4~8자리숫자를 누르고 *을 누르면 원래 설정
되어 있던 비밀번호와 비교한다. 먼저, *와 *사이의 숫자의 수를 keyN, 눌러진 숫자들을 keyA[]배열에 저장하
는 함수 extract_key_pressed()함수를 작성하라. 다음 과정으로 코딩하라.
(a)(5점) 먼저 첫번째 *를 기다리는 상태 ST_1, 두번째 *를 기다리는 상태 ST_2를 정의하고 ST_1에서 *를 입
력받으면 ST_2로 천이하고 ST_2에서 *를 입력받으면 ST_1으로 천이하고 배열에 그 사이의 key를 저장하는
코드를 작성하라.
#define ST_1 1 // 첫번째 *를 기다리는 상태
#define ST_2 2 // 두번째 *를 기다리는 상태
char keyA[8]; // *와 * 사이에 눌러진 숫자들을 저장
char keyN=0; // *와 *사이에 눌러진 숫자의 수를 저장
char extract_key_pressed(char key) // 두번째 *가 눌러지면 1을 아니면 0을 return 한다.
{ static char state=1; char keyN = 0;
switch(state) { case ST_1:
if (key==’*’) state = 2; break;
case ST_2:
if (key!=’*’) keyA[keyN++]=key;
else { state = 1; return(1); }
break;
}
return(0);
}

(b)(2점)*를누르고 네자리를 누르기전에 *가 입력 or 8자리이상 숫자 후에도 *가 입력되지않으면 P2를 토글


void key_scan_isr()….. { char res;
res = extract_key_pressed(key_scan());
if (((res==1)&&(keyN<4)) || (keyN>8) ) P2= ~P2;
}
10.(10점) HW4의 두번째 과제를 다음 순서로 작성하라. (LED N, SEG N만 구현하자)
char rx[10]; // UART에서 carriage return 문자를 만나기 전까지 글자를 저장한다. 단,
// UART에서 carriage return 문자를 만나면 null termination을 하여 strcmp등을 사용할 수 있게 한다.
char cnt=-1; // UART에서 읽은 숫자의 수, -1부터 시작한다.
char cmd[10], N; // char 배열 rx를 sscanf(string scanf) 함수로 읽어 명령어와 숫자로 분리
void led_toggle(int n) {
P2 = P2 ^ (0x01 << N ) ; // N에 해당하는 led를 toggle, 반드시 한줄로 작성하라.
}
void process_cmd() { // cmd 문자열을 해석: 첫번째 명령어는 cmd에 뒤의 숫자는 N에 저장
sscanf(rx, “%s %d”, cmd, &N);
if (!strcmp(cmd,”LED”)) led_toggle(N); // N(0~7)에 해당하는 led를 toggle한다
if (!strcmp(cmd,”SEG”)) seg_on(N); // 이 부분은 구현하지 않는다.
}
void uart_isr() …. { // pc로 TX 할일 없으니 RI, TI체크할 필요 없다.
rx[++cnt] = SBUF; // UART 에서 rx 버퍼로 복사
if (rx[cnt]== ‘\n’) {
cmd[++cnt] = 0 ; // string을 null termination 시켜서 strcmp함수등을 쓸 수있게 한다.
process_cmd( ) ; // 만약 carriage return 문자를 만나면 명령어를 해석
}
}
void main() {
…. // 이 부분에서 UART interrupt 설정하고, baud rate 설정하고 등등 한다. 생략
while(1); // 무한루프돈다.
}

11.(15점)(a)(4점)모터의 회전속도를 감지하는 encoder 를 micom으로 구현하려고 한다. 먼저 HW 연결을 그


려라. 인터럽트 방식을 이용하게 설계하라.
(b)(6점) 위의 연결을 이용하여 모터의 회전속도를 감지하는 코드를 답안지 뒷면에 작성하라.
(c)(5점) 감지한 모터의 속도와 원하는 속도의 차이가 있는 경우에 그 값을 N=-127~127까지의 숫자로 표시
할 수 있다고 하자. 그 차이를 줄이기 위하여 모터의 속도를 N값에 따라 빠르게 혹은 느리게 제어하려고 한
다. -127에서 모터가 가장 느리게, 127에서 가장 빠르게 동작하게 하려고 한다. 이를 위하여 모터 제어 신호
를 micom의 한 핀에 연결하고 그 핀의 high level의 duration으로 (즉, PWM방식으로) 속도를 제어하는 코드
를 timer interrupt 방식으로 아래 혹은 뒷면에 작성하라).

You might also like