#1 keypad_main.c를 분석하고 또 FLOW CHART 그리기!!start !int main(void)vgSetInterrupt(INTNUM_KEYSCAN, KeyISR)호출interrupt발생시void KeyISR()호출PutKey(*R_KPDR2)호출int main(void)vgEnableInterrupt(INTNUM_KEYSCAN,TRUE)while문 -> IF문KeyPadReady()호출keypadready값이 true이면 if문 활성Key_Value = GetKeyPadData()key_value값에 따라 스위치문의 case 결정switch(Key_Value)Ex)1이면 S1이라고 출력====================================================================#define KeyPadBufLEN 64U8 KeyPadBuffer[KeyPadBufLEN];int KeyPadFront=0;int KeyPadRear=0;U8 Key_Flag=0;변수type과 값을 선언함.====================================================================int main(void){U8 Key_Value=0;InitInterrupt();UartConfig(0, 115200);vgSetInterrupt(INTNUM_KEYSCAN, KeyISR);void KeyISR(){PutKey(*R_KPDR2);//uPrintf0("*R_KPDR1:0x%x,*R_KPDR2:0x%xrn",*R_KPDR1,*R_KPDR2);}?KeyIST()함수는PutKey라는 함수를 호출하면서 R_KPDR2의 주소를 넘겨준다.?vgSetInterrupt이 함수는 interrupt 발생시 KeyISR이라는 함수를 호출한다.void PutKey(U8 data){KeyPadRear %= KeyPadBufLEN;KeyPadBuffer[KeyPadRear++]=data;}?KeyPadRear를 KeyPadBufLEN으로 나눈 나머지를 KeyPadRear의 값으로해준다. 현재 KeyPadRear=0 이고 KeyPadBufLEN=64 이므로 0을 64로 나눈 나머지는 0이 된다. 따라서 KeypadRear의 값은 0이 되고,그 다음문장에서 KeyPadBuffer이라는 배열의 0번째에 data를 넣어준 뒤,후위연산자 ++ 로 인해 KeyPadRear=1 이다.이제 다시 main()으로 돌아와서 다음 문장을 실행하게 된다.vgEnableInterrupt(INTNUM_KEYSCAN,TRUE);// UART CH0 Rx Interrupt Enable*R_KSCONR = 1;?vgEnableInterrupt함수를 TRUE의 값을 줌으로써 interrupt를 활성화 시켜준 뒤,*R_KSCONR = 1로 해줌으로써 Scan Enable이 되게 한다.uPrintf0("rn < Keypad Test >>>rn");uPrintf0(" Please, push key buttonrn");while(1) {if(KeyPadReady()) {int KeyPadReady(void){return ((KeyPadFront==KeyPadRear)? 0:1);}?위 조건문은 KeyPadFront와 KeyPadRear의 값이 같으면 0다르면 1을 넘겨준다. 현재 KeyPadFront=0이고,KeyPadRear=1이므로 1의 값을 넘겨주어 if문이 동작하게 된다.Key_Value = GetKeyPadData();int GetKeyPadData(void){KeyPadFront %= KeyPadBufLEN;?KeyPadFront=0이고KeyPadBufLEN=64이므로 0을 64로 나눈 나머지는 0이므로KeyPadFront에게 0을 준다.return KeyPadBuffer[KeyPadFront++];}?KeyPadBuffer[KeyPadFront++]은 KeyPadBuffer[0]에 있는것을 return해주기 때문에 PutKey라는 함수에서 0번째자리에 data를 넣어주어 data를 return하고 배열은 KeyPadBuffer[1]로 바뀌게 된다. 그 이유는 후위연산자로 return문장을 실행한 뒤KeyPadFront++ 즉,1증가하기 때문이다.// uPrintf0("Key_Value=0x%xrn",Key_Value);switch(Key_Value) {case 1 :uPrintf0("Key 'S1'rn");break;case 2 :uPrintf0("Key 'S2'rn");break;case 3 :uPrintf0("Key 'S3'rn");break;case 6 :uPrintf0("Key 'S4'rn");break;case 7 :uPrintf0("Key 'S5'rn");break;case 8 :uPrintf0("Key 'S6'rn");break;case 11 :uPrintf0("Key 'S7'rn");break;case 12 :uPrintf0("Key 'S8'rn");break;case 13 :uPrintf0("Key 'S9'rn");break;default :uPrintf0("Unknown Key!rn");break;}}}return -1; }?스위치문에서 Key_Value로 입력된 data에 따라 1을 눌렀을 경우 S1를 눌렀다와 같은 메시지를 출력해준다.====================================================================스위치문에서의 번호가 1 2 3 4 5 6 ? 와 같이 순차적으로 증가하지 않는 이유는keypad가 위와 같기 때문에 9개의 버튼은 1 2 3 6 7 8 ? 와 같이 된다.#2GMX1000의 Key Pad Controller에서는 Key를 누른 경우(High ->Low State)를 Positive Transition으로 정의하고 있고, Key를 눌렀다 뗀 경우(Low -> High State)를 Negative Transition으로 정의하고 있다. KSCON[2:1]의 모드 설정 값에 따라 Key를 누를 때(Positive Edge Trigger Mode)또는 Key를 뗄 때(Negative Edge Trigger Mode), Key를 누를 때와 뗄 때 모두(Level Trigger Mode)인 경우에 Key Scan Interrupt를 발생시킨다.기존의 레지스터에서 KSCON;2:1]은 00으로 Default 값으로 Positive Trigger Mode에서 동작하게 되어있었다. 즉 한번의 interrupt로 두 번의 실행을 하기위해선 누를 때와 땔 때 모두 interrupt를 발생시켜야 하므로 KSCON의 끝에서 1번째와 2번째 자리의 값을 Level Trigger Mode인 경우로 바꿔줘야 한다.Ex ) □ □ □ □
<FLOW CHART>main->logo->TestItemSelectUART()->PrintBannerUART()-> 4가지의 경우 중 하나를 선택->경우 1 =UART0 TX/RX Test 경우 2 =UART1 TX/RX Test 경우 3 =UART Interrupt Test 경우 4 =Quituart는 pc와의 시리얼통신을 위한 기본적인 universal asynchronout receiver/transmitter기능을 포함하고 있다. uart ch0와 ch1은 pc와 연결하여 보드 테스트를 위한 디버깅과 모니터링에 사용될수 있다.그리고 uart ch0은 port를 통해 외부 시리얼장치와 통신에 사용될 수 있고, uart ch1은 블루투스시리얼어답터나 블루투스모듈과 연결하여 무선 통신시에 사용될 수 도 있는 특징을 가진다.그럼 uart_main.c를 분석해보자.처음으로void BufPrint1(char *type, char *Buff, int len) {int i;for(i=0; i<len; i++) {uPrintf1(type, Buff[i] & 0x00ff);}}위의 함수는 일정한 크기의 buff를 받아서 len길이 만큼을 뿌려준다.void UART0_RX()함수는{int len=0;unsigned char rxdata[32];memset(rxdata, 0, sizeof(rxdata));//0부터 rxdata사이즈만큼의 크기를 메모리 잡는다.while(RxFIFO_STAT0()) {rxdata[len] = uGetch0();