본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형]한원우_9월19일 보고서

by 알 수 없는 사용자 2011. 9. 20.
728x90
반응형

ADC

AT91SAM7S256은 8채널 10비트 또는 8비트 분해능의 축차비교형 A/D컨버터를 가지고 있다.

ARM = 8채널

Atmega = 8채널

8채널의 아날로그 입력신호 중에서 AD0 ~ AD3은 병렬 I/O 포트와 겸용으로 사용하고 있고,

AD4 ~ AD7은 전용의 핀을 가지고 있다.

A/D변환이 가능한 아날로그 입력전압의 범위는 0 ~ ADVREF이며, 변환은 10비트 모드 또는 8비트 모드를

사용할 수 있다. A/D 변환된 디지털 데이터는 각 채널에 내장된 전용의 데이터 레지스터 ADC_CDRx에 저장되며

모든 채널에 공통인 데이터 레지스터 ADC_LCDR에도 저장된다.

특정 채널을 읽어 들일 때는 ADC_CDRx레지스터를 읽고, 최근 것을 읽어 들일 때는 ADC_LCDR레지스터를 읽는다.

8비트 분해능과 10비트 분해능의 차이.

A/D변환 결과는 ADC_CDRx 레지스터와 ADC_LCDR 레지스터 동시에 두 곳에 저장된다.

 축을 놔두고 축과 같아 질 때까지 쌓아서 비교하여 찾는 방법을 축자 비교법이라 한다.

 

소스로 구현해보자.

ADC.C

   1:  #include "Adc.h"
   2:   
   3:  void Adc_Init(void)
   4:  {
   5:    // 전원공급
   6:    PMC_PCER = 1 << ADC;
   7:    // ADC 리셋
   8:    ADC_CR = 1<< SWRST  ;    // 컨트롤 레지스터 리셋
   9:    // 채널 선택
  10:    ADC_CHER = 1 << ADC_CH7;  // 채널 7번 활성화
  11:    // 프리스컬 분해기능 시작
  12:    ADC_MR  = (5 << PRESCAL) |(0 << LOWRES);
  13:  }
  14:   
  15:  unsigned char * Adc_Run7(void)
  16:  {
  17:    // 컨버팅 스타트 변환 시작
  18:    ADC_CR = 1<< START;  
  19:    // 컨버팅 대기
  20:    // while()
  21:    // 컨버팅 읽기
  22:    // ADC_CDR[7];
  23:    
  24:    return ;
  25:  }

 

ADC.H

   1:  #ifndef  __ADC_H__
   2:  #define  __ADC_H__
   3:   
   4:  #include "pmc.h"
   5:   
   6:  #define  ADC      4  //ADC 사용
   7:  #define  START    1  //스타트 컨버터
   8:  #define  SWRST    0  //리셋 
   9:  #define  ADC_CH7  7  //채널7사용
  10:   
  11:  #define  PRESCAL  8
  12:  #define  SLeep    5
  13:  #define  TRGEN    0
  14:  #define  STARTUP  18
  15:  #define  LOWRES   4
  16:  #define  TRGSEL   2
  17:  #define  SHTIM    24
  18:   
  19:  #define  ADC_CR    (*((volatile unsigned int *)0xFFFF8000))  //제어 레지스터 (Write-only)
  20:  #define  ADC_MR    (*((volatile unsigned int *)0xFFFF8004))  //모드 레지스터 (read/write)
  21:  #define  ADC_CHER  (*((volatile unsigned int *)0xFFFF8010))  // 채널 허용 레지스터 (write-only)
  22:  #define  ADC_SR    (*((volatile unsigned int *)0xFFFF801C))  // 상태 레지스터 ( read-only)
  23:  #define  ADC_LCDR  (*((volatile unsigned int *)0xFFFF8020))  // 최신 데이터 레지스터 (read-only)
  24:  #define  ADC_CDR  (((volatile unsigned int *)0xFFFF8030))  // 채널 데이터 레지스터 (read-only)
  25:   
  26:  void Adc_Init(void);
  27:  unsigned char * Adc_Run7(void);
  28:   
  29:  #endif  //end __ADC_H__ 
  30:   
  31:   

 

 

C 실력으로 프로그램을 잘한다고 평가하기는 힘들다. 스팩을 보고 코드가 아닌 타이밍도에 의해 프로그램을

작성하느냐 못하느냐에 따라 프로그래머의 실력이 평가된다. 앞에 자료가 없으면 못한다는 것은 실력이 없다는

것이다.  실제로 우수한 프로그래머는 HOW TO(어떻게)를 알고 있다. 프로젝트가 주어 졌을 때 이걸 어떻게

하느냐가 아니라 문제를 파악하고 해결하려는 자세가 절실하다. 기준 따윈 존재하지 않는다. 자신의 주관을

가지려면 실력이 있어야 한다. 자신에게 당장 주어진 일을 남의 위해서가 아니라 내 것으로 만들어라. 자기

스스로가 기준을 만들자.

 

일을 던져 줬을 때 이걸 어떻게 해! 라고 생각한다면 그 순간부터 끝이다.

사람이 대답을 주저하는 이유는 스스로가 자신의 답이 오답이라 판단하기 때문이다. 기준을 세우자.

 

공모씨의 오전 9시부터 10시 30분까지의 정신상태.

정신없제? 아침부터 잠이 와 없는 6층 엘레베이터까지 만들어 내며 자신의 기준을 만들지 못하고 계속 2분

얘기만 하고 있는 붕 뜬 상태. 5분이 어떻게 나온 건지 얘기해줄래?

 

일을 시키는데 일을 안하고 일을 하라고 계속 시킬 때까지 안하는 사람은 회사에서 스트레스를 엄청나게

받는다. 스트레스를 받지 않으려면 시킬 때 잘하자. 그러기 위해선 우리의 라이프 스타일을 바꾸자.



API

컨트롤의 정의

컨트롤이란 상자와 인터페이스를 이루는 도구. 인터페이스를 이룬다는 말은 사용자로부터 명령과 입력을 받아들이고 출력 결과를

보여준다는 뜻이므로 컨트롤은 곧 입출력 도구를 뜻한다.

컨트롤은 “버튼, 에디트, 리스트 박스, 스크롤 바등을 묶어서 이해하는 것이 더 빠르다. 컨트롤도 하나의 윈도우이다. 화면상의

일정한 영역을 차지하며 자신의 고유 메시지를 처리 할 수 있는 능력을 가지고 있다. 컨트롤은 윈도우즈가 운영체제 차원에서

제공하기 때문에 윈도우 클래스를 등록할 필요없이 미리 등록되어 있는 윈도우 클래스를 사용하기만  하면 된다.

 

버튼

컨트롤중에서 제일 간단하고 익숙한 먼저 컨트롤을 먼저 만들어 보자. Button프로젝트를 만들어 lpszClass

문자열을 다음과 같이 수정하자.

통상 lpszClass 문자열을 프로젝트명으로 정희하여 사용하고 있지만 이 프로젝트의 경우 Button이라는 클래스명은

윈도우즈가 미리 사용하고 있기 때문에 lpszClass문자열에 예제명으로 쓸 수 없다.

아래의 예제를 이용하여 버튼을 만들어 보자.

Button.cpp open

실행화면

버튼이 눌러졌음을 확인하기 위해 메시지 박스만 열었는데 실제 프로젝트에서는 버튼의 의미에 맞는 명령, 예를

들어 게임 시작, 파일 열기, 인쇄 등의 동작을 해야 한다.

 

버튼 만들기

컨트롤은 윈도우이기는 하지만 홀로 사용될 수 없으며 반드시 부모 윈도우의 차일드로 존재해야 한다. 컨트롤도

하나의 윈도우이므로 CreateWindow함수를 호출하여 만든다.

함수 호출문에서 각 인수가 가지는 의미를 하나씩 순서대로 짚어보자.

“button”

만들고자 하는 윈도우의 윈도우 클래스이다. 별도의 등록없이 이 인수에 만들고자 하는 컨트롤의 윈도우 클래스명

을 적어주면 된다. 대소문자는 구분하지 않으므로 “BUTTON”이라고 적어도 상관없다.

 

“Click Me”

두 번째 인수는 윈도우의 타이틀 바에 나타날 윈도우의 제목이며, 컨트롤에 따라 캡션이 나타날 위치가 달라진다.

버튼은 버튼 위에 캡션이 나타나며 체크, 라디오 버튼은 그 오른쪽에 갭션이 나타난다. 리스트 박스나 스코롤 바처럼

캡션이 필요없고 내용만 있는 컨트롤은 NULL을 지정한다. 단순한 문자열일 뿐이므로 한글도 물론 사용할 수 있다.

 

"스타일"

세 번째 인수는 윈도우의 속성값이다. 컨트롤은 차일드 윈도우이므로 예외없이 WS_CHILD스타일은 반드시 주어야

한다. WS_VISIBLE 스타일 또한 ShowWindow함수를 호출하지 않아도 컨트롤이 화면에 나타나므로 컨트롤의 경우

이 두 스타일값은 거의 예외없이 지정하는 것이 정석이다. 그 외에 버튼의 스타일 값은 BS_ 접두어로 시작된다.




"위치"

4번째부터 7번째 인수까지는 윈도우의 위치와 크기를 지정한다. 컨트롤의 경우는 부모 윈도우의 작업 영역을 기준으로

한 좌표가 사용된다.


"부모 윈도우"

8번째 인수는 컨트롤의 부모 윈도우를 지정하는데 컨트롤은 차일드이므로 반드시 부모윈도우가 있어야 한다.

메인 윈도우의 핸들인 hWnd를 적어줌으로써 부모 윈도우를 지정해주었다.


"ID"

9번째 인수는 위도우에서 사용할 메뉴의 핸들이다. 단 차일드 컨트롤의 경우는 메뉴를 가지지 않으므로 이 인수를 컨트롤의

ID를 정하는 용도로 사용한다. 컨트롤의 ID는 컨트롤간의 구분을 위해 사용하는 것이므로 한 부모 아래의 컨트롤까리 중복되지

않는 ID를 가지기만 하면 된다. 사용되는 컨트롤이 많다면 #define으로 매크로 상수를 정의해 쓰는 것이 좋다.

컨트롤을 생성한 후에 CreateWindow함수는 생성된 차일드 컨트롤의 윈도우 핸들을 리턴해 주는데 필요할 경우 별도의 변수에

핸들값을 저장해 주면 된다.



부모와의 통신

다음은 버튼이 눌러질 경우의 처리를 해주어야 한다. 컨트롤들은 버튼을 클릭했다거나 에디트에 문자열을 입력했다거나 할 경우 부모

윈도우로 통지 메시지를 보내준다. 부모 윈도우는 차일드 컨트롤이 보내주는 통지 메시지를 받아 적절한 처리를 해준다. 버튼을 클릭

할 경우 WM_COMMAND 메시지는 부모 윈도우에게 보내며 이때 전달되는 정보는 다음과 같다.



컨트롤의 ID는 CreateWindow의 아홉번째 인수에서 지정한 정수값이며 어떤 컨트롤이 통지메세지를 보냈는지를 알려준다.

통지코드는 차일드 컨트롤이 왜 메시지를 보냈는가를 나타내는 값이다. 부모 윈도우는 WM_COMMAND에서 LOWORD(wParam)

값은 조사하여 어떤 컨트롤이 눌러졌는지에 따라 적절한 처리를 한다.

WM_COMMAND 메시지는 컨트롤의 통지 메시지뿐만 메뉴, 항복, 엑셀러레이터 등의 명령을 처리하는 중요한 일을 한다.

컨트롤의 ID, 메뉴 ID, 액셀러레이터 ID등은 모두 LOWORD(wParam)으로 전달되므로 이 세가지 명령들끼리는 0 ~ 65535의 범위

에서 상호 중복되지 않는 ID를 가져야 한다.

사용자로부터 명령을 많이 받아들이는 프로그램 일수록 WM_COMMAND 메시지 처리는 더욱 복잡해진다.

728x90