WM_PAINT 메시지에 대한 Event handler 코드로서 미리 그려 넣은 비트맵 Resourece (IDB_BITMAP_FLOWER)를 등록하고, 클라이언트 영역 정보와 비트맵 정보를 해당 객체에 등록시키며, CDC 객체인 dcMem에 비트맵을 등록하게 된다. 이 후에는 mesKind에 있는 이벤트 종류만을 보고 그림을 늘릴 지 줄일 지의 여부를 판단한다. mseKind가 LBUTTON_DOWN이면 dc.StretchBlt()에 의해 클라이언트 영역 전체로 비트맵 이미지가 확대되게 되며, 다시 LBUTTON_UP이 되면 dc.BitBlt()에 의해
{{마이크로 프로세서 실험 결과보고서(실험7. 적외선 센서 실험)마이크로 프로세서 실험차 례-------------------------------1. 실험 제목2. 조 번호 및 조원 명단3. 실험 내용 개괄1) 실험 목적2) 하드웨어에 대한 간략한 설명4. 실험 방법0) 하드웨어 세팅 방법1) 사용한 주요 함수 / Algorithm의 개요2) 프로그램 구조3) TEST 방법5. 실험 결과6. 실험 후 고찰1) 실험간 특이사항 및 애로사항2) 실험 결과의 응용 범위에 대한 고찰{실험7. 적외선 센서 실험1. 실험제목 : 적외선 센서 실험2. 조번호 :3. 실험 내용 개괄(1) 실험 목적1 실험1적외선 센서의 동작 원리를 이해하고, Target Machine(이하 테크마)에 장착된 6개의 적외선 센 서와 LED를 각각 1:1 Matching시켜 송·수신된 내용의 유무에 따라 해당 센서에 Matching된 LED의 ON/OFF를 제어해 봄으로써 적외선 센서가 제대로 동작하는지를 확인해본다.(6개 적외선 센서의 감도가 모두 다르기 때문에 임계값 설정에 유의해서 실험한다.)2 실험2+ , - 키의 입력에 따라 [Stepping Motor의 가·감속]을 제어했던 지난 실험과는 달리, 이번에 는 적외선 센서가 수신하는 빛의 양에 따라 [Stepping Motor의 가·감속]을 제어해본다. 즉, 대 상물체(반사체)가 가까이 오면 올수록 속도를 점점 빠르게 하고, 반사체가 멀어지면 멀어질수록 속도를 점점 느리게 한다. (속도 조절단계는 적어도 6단계 이상으로 실험해본다.)(2) 하드웨어에 대한 간략한 설명{테크마에 장착된 적외선 센서의 송신부는 EL-1KL3, 수신부는 ST-1KLA로 구성되어있다.테크마에 장착된 적외선 센서의 수신부는 외란광(형광등, 그 밖의 불빛)으로부터의 영향을 적 게 하기 위해 밑면에 설치되어있다.테크마에 장착된 적외선 센서의 출력포트는 IRDRIVE(0x202)이며, ADC포트는 AD10158PORT (0x208)이며, ADC포트에서는 빛의 양을 수수 */BYTE Sensor_Setting(int index){BYTE value; /* 센서의 감도를 저장하는 변수 */int i; /* 인덱스 변수 *//* ReadSensor() 함수 이용 */해당 센서의 감도를 200개 Sampling하여 순서대로 result[] 배열에 저장한다.;result[] 배열의 데이터를 오름차순으로 정렬한다.; /* bubble_sort() 함수 이용 */return result[0]; /* 가장 좋은 감도를 Return한다. */}- Exam1() 함수{BYTE sensibility[6]; /*6개 센서 각각의 (감도)임계값을 저장하는 배열 */void Exam1(){BYTE value; /* 센서의 감도를 저장하는 변수 */BYTE led_value; /* LED의 상태를 저장하는 변수 */int i; /* 인덱스 변수 */모든 LED를 OFF시킨다.(LED 초기화);for (i = 0; i < 6; i++) {/* Sensor_Setting() 함수 이용 */6개의 센서를 Sampling한 결과 값을 sensibility[] 배열에 순서대로 저장한다.;}for (;;) {led_value변수에 0xFF를 저장한다.;led_value값을 LED로 출력한다.;for (i = 0; i < 6; i++) {해당 센서의 감도를 읽어와 value에 저장한다.;switch(센서 번호){case 현재 감도를 측정한 센서가 0번 센서일 경우:if(현재 읽어온 0번 센서의 감도 값이 임계값보다 클 경우)led_value값에 0xFE를 AND연산한다.;{break;case 현재 감도를 측정한 센서가 1번 센서일 경우:if(현재 읽어온 1번 센서의 감도 값이 임계값보다 클 경우)led_value값에 0xFD를 AND연산한다.;break;case 현재 감도를 측정한 센서가 2번 센서일 경우:if(현재 읽어온 2번 센서의 감도 값이 임계값보다 클 경우)led_value값에 0xFB를 AND연산한다.;break;case 현재 감도를 측정한 센서가 1 /* 왼쪽 바퀴를 제어하기 위해 사용할 센서의 번호 */#define SELECTED_RSENSOR4 /* 오른쪽 바퀴를 제어하기 위해 사용할 센서의 번호 */#define STAGE10 /* 속도 조절 가능한 단계 수 */int L_speed, R_speed; /* 왼쪽·오른쪽 바퀴 각각의 속도값을 저장하는 변수 */int flag; /* motor_operation() 함수의 동작 여부를 결정하는 변수(1 or 0) */void Exam2(){char ch; /* 종료문자를 저장하기 위한 변수 */{BYTE L_value, R_value; /* 현재의 왼쪽·오른쪽 센서의 감도를 저장하는 변수 *//* 속도 조절을 확실하게 인지하기 위해 임계값을 세팅한다. */왼쪽 바퀴를 제어하기 위해 사용할 1번 센서의 임계값과 오른쪽 바퀴를 제어하기 위해사용할 4번 센서의 임계값을 다시 설정한다.;while(1){if (키보드가 눌려졌고 그 키가 q 일 경우)flag값을 0으로 Reset하여 인터럽트 내의 함수가 실행되지 않게 한다.;모든 모터의 전원을 끈다.;return;}}현재 실험에 사용중인 왼쪽 센서의 감도를 읽어 L_value에 저장한다.;현재 실험에 사용중인 오른쪽 센서의 감도를 읽어 R_value에 저장한다.;/* 왼쪽 바퀴의 속도 = L_speed, 오른쪽 바퀴의 속도 = R_speed */(STAGE에 정의된)단계 수에 맞게 speed값을 설정한다.;현재 왼쪽·오른쪽 센서의 감도를 콘솔 창에 출력한다.;출력결과를 보기 위한 약간의 지연시간을 준다.;}}- NewIRQ10() 함수{/* 왼쪽 바퀴를 구동하기 위한 배열 */BYTE MPhaseSingleTwo_Left[] = { 0x02, 0x0A, 0x08, 0x09, 0x01, 0x05, 0x04, 0x06 };/* 오른쪽 바퀴를 구동하기 위한 배열 */BYTE MPhaseSingleTwo_Right[] = { 0x20, 0xA0, 0x80, 0x90, 0x10, 0x50, 0x40, 0x60 };i 구동시킨다.;}}{void interrupt NewIRQ10(void){motor_operation(); /* motor_operation() 함수 호출 */if(L_count값이 L_speed값보다 커질 경우){L_count값을 0으로 초기화한다.;L_index값을 하나 증가시킨다.;}if(R_count값이 R_speed값보다 커질 경우){R_count값을 0으로 초기화한다.;R_index값을 하나 증가시킨다.;}L_count값을 하나 증가시킨다.;R_count값을 하나 증가시킨다.;HardDelayTimerCount값을 하나 증가시킨다.;종료 환경을 세팅한다.;}(2) 프로그램 구조{(3) TEST 방법[1] 응용실험 1- 테크마에 장착된 6개의 적외선 센서 각각의 감도가 모두 다르므로 각 센서의 임계값을 다르게 설정하 여 대상 물체(반사체)를 인식하도록 한다.- 대상 물체를 해당 위치의 적외선 센서가 인식하면(미리 설정된 임계값 이상의 감도로 수신될 경우), 1:1로 Matching된 LED가 ON되고, 인식되지 않으면(미리 설정된 임계값 미만의 감도로 수신될 경우) 해당 LED가 OFF됨을 확인한다.- 두 개 이상의 적외선 센서가 대상 물체를 인식하게 하여, 그에 해당하는 다수의 LED가 동시에 ON되 는 것을 확인한다.유의사항 - 초기에 임계값을 설정한 위치에 대상 물체를 위치시켰을 때 적외선 센서가 인 식 하는지를 확인한다.- 콘솔 창으로 출력되는 감도정보와 각 센서의 임계값을 비교해 보고, 임계값 이 상으로 인식하였을 때 Matching된 LED가 올바르게 ON되는지의 여부를 확인 하고, 반대의 경우 LED가 OFF되는지 확인한다.[2] 응용실험 2- 테크마에 장착된 왼쪽3개 오른쪽 3개의 적외선 센서 중 가장 감도가 좋은 센서를 하나씩 선택한다.- 선택한 적외선 센서에 대상 물체를 가까이 가져다 대면 댈수록 Stepping Motor가 점점 빠르게 동작하 는 것을 확인하고, 반대의 경우 Stepping Motor가 점점 느려지게 한다.- 좌·우서가 인식할 수 있는 상황을 만들고 실험한 결과 두 개 이상의 LED가 동시에 ON되는 것도 확인하였다.(2) 응용실험 2[응용실험 1]을 통해 가장 감도가 우수하다고 판단되는 D1, D4 센서를 [응용실험 2]에 사용하였 다. 속도가 조절되는 단계를 6단계로 설정하고, 좌·우측 바퀴는 적외선 센서의 감도에 따라 각각 의 속도가 조절되도록 설정하였다. D1센서에 반사체를 가까이 가져다 댈수록 감도가 증가하여 왼 쪽 Stepping Motor의 속도가 증가하였으며, 반사체를 멀리 떨어뜨릴수록 감도가 감소하여 왼쪽 Stepping Motor의 속도가 감소하였다. 또한 D4센서에 반사체를 가까이 가져다 댈수록 우측 Stepping Motor의 속도가 증가하였으며, 반사체를 멀리 떨어뜨릴수록 우측 Stepping Motor의 속 도가 감소하였다.[반사된 빛의 양과 속도를 제어하는 매커니즘]1 왼쪽 3개의 센서 중 가장 성능이 좋은 D2 센서와 오른쪽 3개의 센서 중 가장 성능이 좋은 D5 센 서를 선택한다.{#define SELECTED_LSENSOR1 /* D2 센서 */#define SELECTED_RSENSOR4 /* D5 센서 */2 반사체를 왼쪽이나 오른쪽 센서 가까이에 가져다 댄 후 ReadSensor()함수를 이용하여 반사된 빛의 양에 따른 감도 값을 측정한다.{L_value = ReadSensor(SELECTED_LSENSOR); /* D2 센서의 감도를 읽어옴. */R_value = ReadSensor(SELECTED_RSENSOR); /* D5 센서의 감도를 읽어옴. */3 측정된 감도 값을 미리 설정해 놓은 단계에 맞게 적당한 속도비율로 변환한다.{#define STAGE10 /* 단계를 설정해 놓은 매크로 */L_speed = STAGE - L_value / (255/STAGE);R_speed = STAGE - R_value / (255/STAGE);4 변환된 속도비율에 맞게 왼쪽·오른쪽 바퀴의 동작 함수를 호출하는 시점을 달리하며, 왼쪽·오른쪽 고찰
{{마이크로 프로세서 실험 결과보고서(실험6. 초음파 센서 실험)마이크로 프로세서 실험§ § § 차 례 § § §-------------------------------1. 실험 제목2. 조 번호 및 조원 명단3. 실험 내용 개괄1) 실험 목적2) 하드웨어에 대한 간략한 설명4. 실험 방법0) 하드웨어 세팅 방법1) 사용한 주요 함수 / Algorithm의 개요2) 프로그램 구조3) TEST 방법5. 실험 결과6. 실험 후 고찰1) 실험간 특이사항 및 애로사항2) 실험 결과의 응용 범위에 대한 고찰{실험6. 초음파 센서 실험1. 실험제목 : 초음파 센서 실험2. 조번호 :3. 실험 내용 개괄(1) 실험 목적1 실험1☞ 초음파 센서의 송·수신 원리를 이해하고, 송·수신 여부에 따라 LED의 동작을 다르게 하여 초음 파 센서가 제대로 동작하는지를 확인해본다.2 실험2{A.초음파 센서를 이용하여, Target Machine(이하 테크마)과 대상 물체와의 이격 거 리를 측정해본다. 이격 거리를 계산함에 있어서 측정된 시간(t)을 이용하여 거리 를 계산하는 매크로를 작성하고, 이를 이용하여 이격 거리를 계산해본다.B.[응용실험2-A]에서 계산된 이격 거리와 실제 이격 거리와의 오차를 극복하기 위 해 여러 가지 요소를 고려하여 보정을 하여, 정확한 이격 거리를 측정할 수 있는 구간(신뢰구간)을 설정하고, 그 신뢰구간에서는 최대 ±2.0mm의 오차만을 허용 하도록 반복적인 실험을 통하여 보정을 해본다.C.[응용실험2-A]에서 이격 거리를 계산하는 매크로의 복잡성으로 인한 CPU부담을 줄이기 위해 측정시간에 따른 실제 이격 거리를 사전에 TABLE로 작성하고, TABLE을 한번만 참조하면 실제 이격 거리를 알아낼 수 있게 프로그램을 수정해 본다.(2) 하드웨어에 대한 간략한 설명{.테크마에 장착된 초음파 센서의 송신기는 일정한 주파수의 전기신호를 진동자에 가하여 음향송신이 이루어지는 구조를 가지고, 수신기는 음향진동에 의해 전압이 발생하는 동작 을 한다..테크마에 장착된 초 발생하면)break;1초간 대기한다.;모든 LED를 끈다.;}}[2] 응용실험 21 응용실험 A{#define EX2A_RANGE(time, temp)((temp = ((0.001)*(time))*(17)), (sqrt(((temp)*(temp)) - (0.5625)))void Exam2_A(void){double temp, report, last_result;int cnt, flag;WORD Time0;{for (;;) {flag, temp, report, last_result, HardDelayTimerCount를 0으로 초기화한다.;while (!HardDelayTimerCount) /* 1이 될 때까지 대기시킴 */;SonicRxFlag를 0으로 치환한다.;초음파를 송신한다.;Time0에 현재 설치한 타이머의 port 값을 읽어온다.;50us만큼 대기한다.;초음파 송신을 정지시킨다.;왼쪽 LED를 켠다.;while (HardDelayTimerCount != 2){if (SonicRxFlag가 1이면){1초간 대기한다;break;}}if (SonicRxFlag가 1이면){/* 송신기에서 수신기까지 걸린 초음파 시간을 report에 저장 */report = Time0 - (현재 타이머 port 값);/* EX2A_RANGE() 매크로 함수에 report값을 통과시켜실제 거리를 계산하고 그 값을 last_result에 저장 */last_result = EX2A_RANGE(report, temp);last_result를 스트림에 출력한다.;if(last_result가 유효한 구간에 있지 않다면) flag = 1;if (flag가 1이면){1초간 대기한다;/* 왼쪽 LED를 5번 깜빡이기 위한 코드로 이동시킨다. */goto NOVALUE;}오른쪽 LED를 켠다.;}else{cnt=1;1초간 대기한다.;NOVALUE:모든 LED를 끈다.;HardDelayTimerCount를 0으로 초기화한다.while (!HardDelayTimerCount) /* 1이 될 때Count) /* 1이 될 때까지 대기시킴 */;while(1){if(HardDelayTimerCount < 20) continue;/* 200ms만큼 경과되면 아래로 진행된다. */왼쪽 LED를 켠다.;while(HardDelayTimerCount < 30);/* 100ms만큼 경과되면 아래로 진행된다. */모든 LED를 끈다.;if (cnt==5) break;HardDelayTimerCount = 10;cnt를 1 증가시킨다.;}}if (키 입력 q'가 발생하면)break;1초간 대기한다.;모든 LED를 끈다.;}}3 응용실험 C{double Distance_look[101][2]={ /* Exam2_C()에서 사용되는 look-up table */1628, 24.0, 1639, 24.2, 1651, 24.4, 1662, 24.6, 1674, 24.8, 1685, 25.0, 1696, 25.2,1708, 25.4, 1719, 25.6, 1731, 25.8, 1742, 26.0, 1753, 26.2, 1765, 26.4, 1776, 26.6,1788, 26.8, 1799, 27.0,1810, 27.2, 1822, 27.4, 1833, 27.6, 1845, 27.8,1856, 28.0,1867, 28.2, 1879, 28.4, 1890, 28.6, 1902, 28.8, 1913, 29.0, 1924, 29.2,1936, 29.4,1947, 29.6, 1959, 29.8, 1970, 30.0, 1981, 30.2, 1993, 30.4, 2004, 30.6, 2016, 30.8,2027, 31.0, 2038, 31.2, 2050, 31.4, 2061, 31.6, 2073, 31.8, 2084, 32.0, 2095, 32.2,2107, 32.4, 2118, 32.6, 2130, 32.8, 2141, 33.0, 2152, 33.2, 2164, 33.4, 2175, 33.6,2187, 33.8, 2198, 34.0, 2209, 34.2, 2220, 34.4, 2230,=0; i Distance_look[i][0] && report < Distance_look[i+1][0]){last_result = Distance_look[i][1];break;}}last_result를 스트림에 출력한다.;JUMP:if(last_result가 유효한 구간에 있지 않다면) flag = 1;if (flag가 1이면){1초간 대기한다;/* 왼쪽 LED를 5번 깜빡이기 위한 코드로 이동시킨다. */goto NOVALUE;}오른쪽 LED를 켠다.;}else{cnt=1;1초간 대기한다.;NOVALUE:모든 LED를 끈다.;HardDelayTimerCount를 0으로 초기화한다.while (!HardDelayTimerCount) /* 1이 될 때까지 대기시킴 */;while(1){if(HardDelayTimerCount < 20) continue;/* 200ms만큼 경과되면 아래로 진행된다. */왼쪽 LED를 켠다.;while(HardDelayTimerCount < 30);/* 100ms만큼 경과되면 아래로 진행된다. */모든 LED를 끈다.;if (cnt==5) break;HardDelayTimerCount = 10;cnt를 1 증가시킨다.;}{}if (키 입력 q'가 발생하면)break;1초간 대기한다.;모든 LED를 끈다.;}}(2) 프로그램 구조{(3) TEST 방법[1] 응용실험 1- 초음파 센서가 정상적으로 송신을 하였을 때, 왼쪽 LED가 ON되게 한다.- 초음파 센서가 인식할 수 있을만한 거리에 대상물체가 들어왔을 때, 정상적으로 수신이 되었음을 알려 주기 위해 오른쪽 LED를 ON되게 한다.- 초음파 센서가 인식할 수 있을만한 거리에 아무런 대상물체가 없을 때에는 비정상적으로 수신이 되었 음을 알리기 위해 왼쪽 LED를 1초에 정확히 5번 깜빡이게 한다.※ 유의사항 - 송신이 되었음에도 불구하고 왼쪽 LED가 OFF상태는 아닌지 확인한다.- 비정상적인 수신시 왼쪽 LED가 1초에 정확히 5번 깜빡이는지를 확인하고, 육 안으로 확인 가능 계산하는 RANGE(t) 매크로를 작성한 후 TEST한 결과 모눈종이 상의 실제 거리와 콘솔 창에 출력된 이격 거리 계산 값 사이에는 상당한 차이가 발견되었다. 이는 초음파 센서가 송·수신을 하는 과정에 영향을 미칠 수 있는 여러 가지 요소를 고려하지 않아 발생한 것으로 추 측되어진다.[RANGE(time, temp) 매크로 함수의 생성 근거와 한계]- RANGE(time, temp) 매크로{#define RANGE(time, temp) ((temp=((0.001)*(time))*(17)), (sqrt( ((temp)*(temp)) - 0.5625))- RANGE(time, temp) 매크로의 생성 근거{{1 Timer를 이용하여 초음파 센서의 송·수신 시간을 각각 체크하고, 그 시간차(RANGE 매크로의 인자로 받은 time)에 0.001을 곱하면 ms단위의 시간을 얻을 수 있다.time * 0.001 = ms단위의 시간2 초음파 센서의 음파속도인 34㎝/ms는 왕복거리이므로 편도거리를 계산하기 위해 이를 반으로 나눈 17㎝/ms로 실제 거리를 계산하는데 사용한다. 즉, 1ms에 17㎝를 이동하므로 1의 연산 결과인 ms단위의 시간에 17㎝를 곱하면 편도거리를 계산할 수 있다.(time * 0.001) * 17 = 편도거리(temp)3 테크마에 장착된 송·수신기 사이의 이격 거리는 1.5㎝이며, 편도거리를 계산하기 위해 이를 반 으로 나눈 0.75로 실제 거리를 계산하는데 사용한다.4 피타고라스의 정리를 이용하여 실제거리를 계산할 수 있다.(편도거리)2 = (실제 이격 거리)2 + (0.75)25 즉, 실제 이격 거리는 다음과 같이 구할 수 있다.(실제 이격 거리) = sqrt((편도거리)2 - (0.75)2)∴ 실제 이격 거리 = sqrt( ((temp) * (temp)) - ((0.75) * (0.75)) )- RANGE(time, temp) 매크로의 한계☞ 수학적으로 유도된 계산식으로부터 RANGE(time, temp) 매크로를 작성하여 TEST하였지
{{마이크로 프로세서 실험 결과보고서(실험5. Stepping Motor 구동 실험)마이크로 프로세서 실험§ § § 차 례 § § §-------------------------------1. 실험 제목2. 조 번호 및 조원 명단3. 실험 내용 개괄1) 실험 목적2) 하드웨어에 대한 간략한 설명4. 실험 방법0) 하드웨어 세팅 방법1) 사용한 주요 함수 / Algorithm의 개요2) 프로그램 구조3) TEST 방법5. 실험 결과6. 실험 후 고찰1) 실수연산과 정수연산에 대한 고찰2) 실험간 특이사항 및 애로사항3) 실험 결과의 응용 범위에 대한 고찰{실험5. Stepping Motor 구동 실험1. 실험제목 : Stepping Motor 구동 실험2. 조번호 :3. 실험 내용 개괄(1) 실험 목적1 실험A{1.1상 구동 방식을 이용하여 Stepping Motor를 구동해본다.2.2상 구동 방식을 이용하여 Stepping Motor를 구동해본다.3.1·2상 구동 방식을 이용하여 Stepping Motor를 구동해본다.2 실험B☞ Stepping Motor의 가·감속을 제어해본다.3 실험C☞ Stepping Motor의 좌·우 바퀴를 따로 제어해본다.(2) 하드웨어에 대한 간략한 설명{.Target Machine(이하 테크마)에 장착된 Stepping Motor는 1상이나 2상 또는 1·2상으로 제어 할 수 있다..테크마에 장착된 바퀴의 지름은 5.2㎝이며, 360°/200pulse로 동작한다..테크마에 장착된 Stepping Motor의 펄스입력은 STEPPORT(0x201)의 해당 비트를 조작 함으로써 원하는 대로 제어할 수 있다..테크마에 장착된 Stepping Motor의 전류입력은 STEPPOWER(0x203)의 해당 비트를 조 작 함으로써 원하는 전류를 인가해 줄 수 있다.{ 1상 구동방식의 원리{ 2상 구동방식의 원리{ 1·2상 구동방식의 원리{ Stepping Motor의 1상·2상 구동4. 실험 방법(0) 하드웨어 세팅 방법☞ TurboC로 프TE MPhaseTwo[] = { 0xAA, 0x99, 0x55, 0x66 }; /* 2상 구동 */void Exam_A2(void){{int I; /* 인덱스 변수 */Stepping Motor에 전력을 인가해준다.; /* 0101(0xF5) → STEPPOWER(0x203) */for(i = 0; i < 100; i++){ /* 반바퀴 전진 구동 */2상 구동방식으로 Stepping Motor를 전진 구동시킨다.; /* STEPPORT(0x201) */바퀴가 돌기 위한 약간의 지연시간을 준다.; /* Delay_10ms() 함수 이용 */}Stepping Motor의 전력을 OFF시킨다.; /* 1111(0xFF) → STEPPOWER(0x203) */}3 응용실험 A-3{/* 1, 2상 구동 */BYTE MPhaseSingleTwo[] = { 0x22, 0xAA, 0x88, 0x99, 0x11, 0x55, 0x44, 0x66 };void Exam_A3(void){int i; /* 인덱스 변수 */Stepping Motor에 전력을 인가해준다.; /* 0101(0xF5) → STEPPOWER(0x203) */for(i = 0; i < 200; i++){ /* 반바퀴 전진 구동 */1,2상 구동방식으로 Stepping Motor를 전진 구동시킨다.; /*STEPPORT(0x201)*/바퀴가 돌기 위한 약간의 지연시간을 준다.; /* Delay_10ms() 함수 이용 */}Stepping Motor의 전력을 OFF시킨다.; /* 1111(0xFF) → STEPPOWER(0x203) */}[2] 응용실험 B- NewIRQ10() 함수{void interrupt NewIRQ10(void) /*IRQ10*/{motor_operation(); /* motor_operation() 함수 호출 */HardDelayTimerCount++;outportb(IRSS, EOI);/* End-Of-Interrupt to Master 8259A */outportb(IRSM, EOI/h)을 정수연산만으로 계산하여콘솔로 출력해준다.;}- Exam_B() 함수{void Exam_B(int op_flag){char ch; /* + , - , q 의 문자를 입력받기 위한 변수 */unsigned int max_count; /* 인터럽트의 발생 빈도를 결정하는 변수 */Stepping Motor에 전력을 인가해준다.; /* 0101(0xF5) → STEPPOWER(0x203) */max_count를 10000으로 초기화한다.;초기 속도 정보를 출력해준다.; /* speedCal() 함수 이용 */while(1){{if(키보드 입력이 있을 경우){ch에 입력된 값을 저장한다.;switch(ch){case 입력된 문자가 'q'일 경우:flag에 NOP를 저장한다.;/* 1111(0xFF) → STEPPOWER(0x203) */Stepping Motor의 전력을 OFF시킨다.;return;case 입력된 문자가 '+'일 경우:if(max_count값이 300초과일 경우)(max_count-100)한 값을 max_count에 저장한다.;현재의 Timer를 Colse한다.; /* CloseTimer1()함수 이용 */속도 정보를 출력해준다.; /* speedCal() 함수 이용 */새로운 max_count값으로 Timer를 세팅한다.; /*InitTimer1() 함수 이용*/break;case 입력된 문자가 '-'일 경우:if(max_count값이 10000미만일 경우)(max_count+100)한 값을 max_count에 저장한다.;현재의 Timer를 Colse한다.; /* CloseTimer1()함수 이용 */속도 정보를 출력해준다.; /* speedCal() 함수 이용 */새로운 max_count값으로 Timer를 세팅한다.; /*InitTimer1() 함수 이용*/break;default :continue;}}}}[3] 응용실험 C{/* 곡선 주행 */BYTE MPhaseSingleTwo2[] = { 0x11, 0x15, 0x54, 0x56, 0x)*/바퀴가 돌기 위한 약간의 지연시간을 준다.; /* Delay_10ms() 함수 이용 */}Stepping Motor의 전력을 OFF시킨다.; /* 1111(0xFF) → STEPPOWER(0x203) */}(2) 프로그램 구조{(3) TEST 방법[1] 응용실험 A1 응용실험 A-1- 1상 구동방식을 이용하여 테크마가 후진하는지를 확인한다.※ 유의사항 - 바퀴가 자연스럽게 회전하는지를 확인한다.- 바퀴의 이동이 어긋나지는 않는지 확인한다.- 테크마가 테이블에서 떨어지지 않도록 주의한다.2 응용실험 A-2- 2상 구동방식을 이용하여 테크마가 전진하는지를 확인한다.※ 유의사항 - [응용실험 A-1]의 유의사항을 확인한다.-3 응용실험 A-3- 1·2상 구동방식을 이용하여 테크마가 전진하는지를 확인한다.※ 유의사항 - [응용실험 A-1]의 유의사항을 확인한다.[2] 응용실험 B- 초기상태에서 바퀴가 2초에 1바퀴를 회전하는 것을 확인한다.- 키보드로 + 를 입력했을 경우, 일정속도 증가하는 것을 확인한다.- 일정속도 이상일 경우, + 를 입력해도 속도가 증가되지 않는 것을 확인한다.- 키보드로 - 를 입력했을 경우, 일정속도 감소하는 것을 확인한다.- 일정속도 이하일 경우, - 를 입력해도 속도가 감소되지 않는 것을 확인한다.- 콘솔 창으로 현재의 속도가 올바르게 출력되는 것을 확인한다.- 키보드로 q 를 입력했을 경우, [응용실험 B]를 종료하는 것을 확인한다.※ 유의사항 - Stepping Motor 회전 중 + 나 - 입력이 들어왔을 경우, 바퀴이동의 끊김 없 이 속도가 증가·감소하는지를 확인한다.(속도 출력부분에서 실수 연산을 사용할 경우, 실수 연산으로 인한 Overhead 로 인해 바퀴이동이 끊기게 된다. 올바른 정수연산을 행하고 있다면 + 나 - 입력이 들어온다 해도 바퀴는 자연스럽게 회전하게 된다.)- pulse/sec에 맞게 시속이 출력되는지를 확인한다.- [응용실험 A-1]의 유의사항을 확인한다.[3] 응용실험 C- 테크마가 일정거리동안 직선선 주행하는 것을 확인하였다.[90°곡선주행 알고리즘]{{1 테크마의 좌·우 바퀴 속도를 1:2로 하여 원을 그리며 이동했을 경우, 그려지는 원의 반지름은 15.2㎝이다.2 부채꼴 호의 길이는 2·π·r·각도/360°로 구할 수 있다.3 반지름이 15.2㎝이고, 중심각이 90°인 부채꼴의 호의 길이⇒ 2 × 3.14 × 15.2 × 90°/360° = 23.864㎝4 1·2상 구동방식으로 동작할 경우 360°/400pulse이다.(한 바퀴 회전 ⇒ 400pulse)5 테크마의 바퀴가 한 바퀴 회전 시 16.384㎝를 이동한다.6 400pulse : 16.384㎝ = x pulse : 23.864㎝7 x pulse ≒ 584.61538...∴ 90°를 곡선주행하기 위해서는 약 584 pulse가 필요하다.6. 실험 후 고찰(1) 실수(Floating Point)연산과 정수(Integer)연산에 대한 고찰☞ 80386CPU에는 현재의 CPU(펜티엄급 이상)처럼 실수연산을 위한 FPU(Floating Point Unit)가 CPU에 내장되어 있지 않고, Co-Processor인 80387을 별도로 장착할 수 있다. 또한 별도로 장착 한다 하여도 그리 좋은 성능은 발휘되지 않는다. 이러한 이유로 테크마의 Stepping Motor가 동작 하는 도중 실수연산을 수행해야 한다면 적지 않은 Overhead가 발생하게 된다. 실제로 + 나 - 입력이 들어왔을 경우 실수연산으로 속도를 계산하도록 놔둔 상태에서 Stepping Motor를 구동시 킨 결과 테크마가 + 나 - 입력을 인지하는 순간 바퀴이동이 자연스럽지 못하고 끊기는 현상이 발생하였다. 이러한 문제는 속도를 계산하는 데에 실수연산이 필요한 부분을 정수연산만으로 수행 한 결과 테크마가 + 나 - 입력을 인지하여도 바퀴이동이 자연스럽게 유지되는 것을 확인할 수 있었다.(2) 실험간 특이사항 및 애로사항☞ Stepping Motor를 구동시키는 것은 별도의 지식이 필요하지 않고 강의내용만으로 구현할 수 있었다. 하지만 좋다.
{{마이크로 프로세서 실험 결과보고서(실험4. 비동기 직렬 통신 실험)마이크로 프로세서 실험§ § § 차 례 § § §-------------------------------1. 실험 제목2. 조 번호 및 조원 명단3. 실험 내용 개괄1) 실험 목적2) 하드웨어에 대한 간략한 설명4. 실험 방법0) 하드웨어 세팅 방법1) 사용한 주요 함수 / Algorithm의 개요2) 프로그램 구조3) TEST 방법5. 실험 결과6. 실험 후 고찰1) 인터럽트와 폴링에 대한 고찰2) 실험간 특이사항 및 애로사항3) 실험 결과의 응용 범위에 대한 고찰{실험4. 비동기 직렬 통신 실험1. 실험제목 : 비동기 직렬 통신 실험2. 조번호 :3. 실험 내용 개괄(1) 실험 목적1 실험1☞ 폴링(Polling) 방식을 이용한 송·수신기능 구현.{A.키보드로부터 입력받은 한 문자를 Target Machine(이하 테크마)에서 폴링 방식 으로 수신하고, 수신받은 데이터를 x232에 폴링방식으로 송신해본다.B.보레이트를 9600bps로 조절한 후 A번과 같은 실험을 해본다.C.키보드로부터 입력받은 한 문자를 테크마에서 폴링방식으로 수신하고, 수신받은 데이터와 같은 데이터를 x232에 폴링 방식으로 2000번씩 송신해본다.※ 폴링(Polling) : 요청한 작업이 끝났는지를 알기 위해 장치의 상태가 변할 때까지 장치의 상태 레지스터를 계속해서 읽는 방식.(소프트웨어적으로 처리)2 실험2☞ 인터럽트(Interrupt) 방식을 이용한 송·수신기능 구현.{A.키보드로부터 입력받은 한 문자를 테크마에서 인터럽트 방식으로 수신 받아 링 버퍼에 저장하고, 링버퍼에 저장된 데이터를 x232에 인터럽트방식으로 송신해본 다.B.키보드로부터 입력받은 한 문자를 테크마에서 인터럽트 방식으로 수신 받아 링 버퍼에 저장하고, 링버퍼에 저장된 데이터와 동일한 데이터를 x232에 인터럽트 방식으로 2000번씩 송신해본다.※ 인터럽트(Interrupt) : 요청한 작업이 끝났는지를 별도의 신호로 알려주어 CPU의 부하를 줄인 방식.(하드웨어적으로 처리)(2) 하드웨어에 대한 간략한 설명{.테크마에 내장된 16C450레지스터에는 시리얼 통신을 제어하는 여러 가지 레지스터들이 존재한다..테크마에 장착된 LED는 BAR_LED(0x203)의 해당비트를 조작함으로써 원하는 LED의 ON/OFF를 제어할 수 있다.{번지레지스터B7B6B5B4B3B2B1B0BASE+0RHR(R)수신데이타 (8BIT)BASE+0THR(W)송신데이타 (8BIT)BASE+1IER(W)0000모뎀상태라인상태송신INT수신INTBASE+2FCR(W)수신트리거레벨수신트리거레벨00DMAMODE송신FIFO 리셋수신 FIFO 리셋FIFO 동작허가BASE+2IIR(R)FIFOFIFO00INT B2INT B1INT B0INT 상태BASE+3LCR(W)보레이트레지스터BREAKPARITYEVENPARITY허가STOP BITWORD 길이 B1WORD 길이 B0BASE+4MCR(W)000LOOPBACKINT 허가OP1#RTS#DTR#BASE+5LSR(R)FIFO ERROR송신가능(FIFO)송신가능BREAKFRAME ERRORPARITY ERROROVERRUN ERROR수신데이타 준비BASE+6MSR(R)CDRIDSRCTSdelta CDdelta RIdelta DSRdelta CTSBASE+7SPR(R/W)사용자 읽기/쓰기 레지스터(8BIT)BASE+0DLL보레이트 레지스터 LSB (LCR.7=1일 때만 동작)BASE+1DLM보레이트 레지스터 MSB (LCR.7=1일 때만 동작)※ (R)=Read전용, (W)=Write전용, (R/W)=Read/Write가능4. 실험 방법(0) 하드웨어 세팅 방법☞ TurboC로 프로그램을 작성한 다음 테크마와 Local PC를 Serial Cable로 연결하고, X232 프로그램을 이용하여 실행파일을 Local PC에서 Target Board로 전송한 뒤 실행한다.(1) 사용한 주요 함수 / Algorithm의 개요(Pseudo Code를 사용)[1] 응용실험 1 (Polling 방식)- CheckTxByPolling() 함수{int CheckTxByPolling(void){/* LSR.5 = 1(송신가능), 0(송신불가능) */LSR.5(송신가능 여부를 나타내는 비트)의 세트여부를 Return한다.;}- PutOneByteByPolling() 함수{void PutOneByteByPolling(BYTE ch){while(송신불가능일 경우(Busy Waiting)) ; /* CheckTxByPolling() 함수 이용 *//* 송신 가능일 경우 */송신버퍼(THR)로 데이터를 보낸다.;}- SendStringByPolling() 함수{void SendStringByPolling(char *s){while(문자열의 끝( )이 아닐 경우){현재 문자를 송신한다.; /* PutOneByteByPolling() 함수 이용 */다음 문자로 이동한다.;}}1 응용실험 1-A- Exam1_A() 함수{void Exam1_A(){int led_position = RIGHT; /* 현재의 LED 상태를 나타내는 변수. */BYTE key_input; /* 수신된 데이터를 저장하는 변수. */폴링모드를 보레이트 38400bps로 세트해준다.; /* SetupCOM1_POLLING() 함수 이용 */모든 LED를 OFF한다.(초기화);while(1){/* GetOneByteByPolling() 함수 이용 */수신버퍼(RHR)에 저장된 데이터를 읽어 key_input에 저장한다.;if(수신버퍼(RHR)에서 읽어온 데이터가 '~'일 경우)break; /* while문을 빠져나간다. */else if(수신버퍼(RHR)에서 읽어온 데이터가 대문자일 경우)소문자로 변환하여 key_input에 저장한다.;else if(수신버퍼(RHR)에서 읽어온 데이터가 소문자일 경우)대문자로 변환하여 key_input에 저장한다.;else if(수신버퍼(RHR)에서 읽어온 데이터가 'n'이거나 'r'일 경우){/* SendStringByPolling() 함수 이용 */수신버퍼에 n 과 r 을 차례로 보낸다.;continue;}송신버퍼로 key_input을 보낸다.; /* PutOneByteByPolling() 함수 이용 */if(현재 오른쪽 LED가 ON일 경우){led_position에 LEFT를 저장한다.;왼쪽 LED를 ON한다.;}{else{ /* 현재 왼쪽 LED가 ON일 경우 */led_position에 RIGHT를 저장한다.;오른쪽 LED를 ON한다.;}}폴링모드 이전상태로 복구시킨다.; /* RestoreSerial() 함수 이용 */}2 응용실험 1-B- Exam1_B() 함수{void Exam1_B(){int led_position = RIGHT; /* 현재의 LED 상태를 나타내는 변수. */BYTE key_input; /* 수신된 데이터를 저장하는 변수. */x232의 통신속도를 9600bps로 수정하라는 메시지를 출력한다.;폴링모드를 보레이트 9600bps로 세트해준다.; /* SetupCOM1_POLLING() 함수 이용 */모든 LED를 OFF한다.(초기화);while(1){/* GetOneByteByPolling() 함수 이용 */수신버퍼(RHR)에 저장된 데이터를 읽어 key_input에 저장한다.;if(수신버퍼(RHR)에서 읽어온 데이터가 '~'일 경우){x232의 통신속도를 38400bps로 수정하라는 메시지를 출력한다.;break; /* while문을 빠져나간다. */}else if(수신버퍼(RHR)에서 읽어온 데이터가 대문자일 경우)소문자로 변환하여 key_input에 저장한다.;else if(수신버퍼(RHR)에서 읽어온 데이터가 소문자일 경우)대문자로 변환하여 key_input에 저장한다.;else if(수신버퍼(RHR)에서 읽어온 데이터가 'n'이거나 'r'일 경우){/* SendStringByPolling() 함수 이용 */수신버퍼에 n 과 r 을 차례로 보낸다.;continue;}송신버퍼로 key_input을 보낸다.; /* PutOneByteByPolling() 함수 이용 */{if(현재 오른쪽 LED가 ON일 경우){led_position에 LEFT를 저장한다.;왼쪽 LED를 ON한다.;}else{ /* 현재 왼쪽 LED가 ON일 경우 */led_position에 RIGHT를 저장한다.;오른쪽 LED를 ON한다.;}}폴링모드 이전상태로 복구시킨다.; /* RestoreSerial() 함수 이용 */}3 응용실험 1-C- Exam1_C() 함수{void Exam1_C(){BYTE key_input; /* 수신된 데이터를 저장하는 변수. */int I; /* 인덱스 변수. */폴링모드를 보레이트 38400bps로 세트해준다.; /* SetupCOM1_POLLING() 함수 이용 */while(1){/* GetOneByteByPolling() 함수 이용 */수신버퍼(RHR)에 저장된 데이터를 읽어 key_input에 저장한다.;if(수신버퍼(RHR)에서 읽어온 데이터가 '~'일 경우)break; /* while문을 빠져나간다. *//* PutOneByteByPolling() 함수 이용 */for(i=0; i