블루투스 모듈을 사용하실때 주로 3.3V를 만들어주기위해서 사용하는 IC입니다 ^^


잘 쓰신다면 ADJ를 쓰시면 되지만~ 귀찮다~ 그냥 바로 어플리케이션만 보고 땡겨 쓰시겠다는 분은


아래의 데이터 시트를 참고해주세요~ㅎ



LD1117.pdf


좋은자료가 보여서 프랑켄님의 블로그에서 담아왔습니다! 주소는 아래와 같습니다!

http://blog.naver.com/PostList.nhn?from=postList&blogId=ranken&categoryNo=43&currentPage=5


상 수 (추가 : 2010. 4. 5, 수정 : 2010. 5. 4)

  RAMEND : 칩에 존재하는 RAM의 마지막 주소 (byte 주소)

  XRAMEND : 지정 가능한 램의 마지막 주소 (외부램의 없다면 RAMEND와 동일)

  E2END : EEPROM의 마지막 주소

  FLASHEND : flash memory 끝 주소 (byte 주소)

  SPM_PAGESIZE : flash memory page size (byte 단위)

  E2PAGESIZE : EEPROM의 페이지 크기

  SIGNATURE_0 : device signature (byte 0)

  SIGNATURE_1 : device signature (byte 1)

  SIGNATURE_2 : device signature (byte 2)

 

  FUSE_MEMORY_SIZE : FuseBit bytes의 크기 (fusebit bytes는 low, high, extended로 구성)

 

  F_CPU : 사용자가 제공하는 CPU 클럭 정보

 

 * SIGRD가 정의되어 있지 않다는 컴파일러 에러가 발생하는 버그가 존재하므로

  #ifndef SIGRD

  #define SIGRD  5

  #endif

  위의 코드를 추가하여 컴파일.

 

 

매크로(추가 : 2010. 4. 5,  수정 : 2011, 11. 17)

  _BV() : bit value    특정 비트 플래그의 값을 검사하기 위한 비트마스크를 만드는 매크로

  예) 1 << TXC   =====>   _BV(TXC)

        while( !(UCSRA & (1<<TXC) );        ====>    while( !(UCSRA & _BV(TXC) );

  sei() : 전역 인터럽트 활성화, 어셈블리 명령어 sei와 동일함.

  cli() : 전역 인터럽트 비활성화, 어셈블리 명령어 cli와 동일함.

  bit_is_set(sfr, bit) : sfr레지스터의 bit가 set이면 참(0이아닌 값).

  bit_is_clear(sfr, bit) : sfr레지스터의 bit가 clear면 참(0이아닌 값).

  loop_until_bit_is_set(sfr, bit) : sfr레지스터의 bit가 set 될 때까지 대기. (while 루프)

  loop_until_bit_is_clear(sfr, bit) : sfr레지스터의 bit가 clear 될 때까지 대기. (while 루프)

 

헤더파일

  avr/io.h : device에 관련된 기본적인 정의 (추가 : 2010. 4. 23)

  컴파일러 옵션 '-mmc='으로 전달된 avr에 대한 적절한 입출력 관련된 정의들을 불러들인다.

  <avr/ioXXXX.h>를 include함으로써 이 작업을 수행한다. 모든 AVR에 공통적인 레지스터는

  <avr/common.h>에 정의 되어 있고, avr/io.h에서 읽어들인다.

  읽어들이는 헤더파일

  <avr/sfr_defs.h>

  <avr/portpins.h>

  <avr/common.h>

  <avr/version.h>

 

  avr/boot.h : 부트로더 지원 (추가 : 2010. 4. 16)

  부트로더에서 제공하는 기능들에 대한 C 언어 지원 매크로, 함수, 상수

  전역 인터럽트는 자동으로 disable 되지 않고 프로그래머가 결정하도록 한다.

  페이지 기록하는 예제 코드도 포함되어 있다.

 

  avr/pgmspace.h : flash memory에 접근 기능 제공 (추가 : 2010. 4. 16)

  장치의 플래시 메모리 영역에 저장된 데이터에 접근하기 위한 인터페이스를 제공한다.

  대상 장치는 LPM이나 ELPM 명령을 지원해야 한다. 

  IAR C의 헤더파일과의 호환성을 위해 제공되지만 100% 호환되지는 않는다.

  ram에 기초한 문자열을 다루는 경우에는 avr_string에서 설명하는 표준 문자열 함수를 사용.

 

  inttypes.h : 정확한 길이의 정수형 타입 정의 (추가 : 2010. 4. 16)

  그 길이를 정확하게 사용할 필요가 있는 정수형 데이터를 정의하는 stdint.h를 확장한다.

  "far" 포인터(64kbytes 초과하는 주소를 위한), printf/scanf에 사용하는 formatting options


 

  avr/interrupt.h : 인터럽트 서비스 루틴 작성에 필요한 매크로 지원(추가 : 2010. 5. 4)

  C언어는 하드웨어에 종속적이지 않은 추상화된 언어이기 때문에 하드웨어에 따라서 달라지

  는 인터럽트 서비스 루틴을 직접 지원할 수가 없다. 따라서, AVR 컴파일러에 따라서 인터럽트

  지원 방법을 나름대로의 방식으로 구현한다. avr-gcc에서는 인터럽트 벡터 테이블이 미리

  정의된 특정 이름을 가지고 있다.

 

  util/setbaud.h : 보오레이트 계산에 필요한 매크로 지원(추가 : 2010. 5. 11)

  F_CPU(시스템 클럭), BAUD_TOL(허용 오차율%, 기본값은 2%), BAUD(보오레이트)의 3개의

  상수를 제공 받아서 UBRRH_VALUE, UBRRL_VALUE, USE_2X(2배속 사용여부)를 전처리기에

  서 계산해서 상수로 쓸 수 있도록 한다.

 

 

 #undef BAUD      // 이전에 BAUD를 define 했다면 컴파일러 오류를 피한다.
 #define BAUD 38400
 #include <util/setbaud.h>
   UBRRH = UBRRH_VALUE;
   UBRRL = UBRRL_VALUE;
 #if USE_2X
   UCSRA |= _BV(U2X);
 #else
   UCSRA &= ~_BV(U2X);
 #endif

 

  avr/eeprom.h : EEPROM에 읽기/쓰기 위한 지원 매크로 및 함수 지원(추가 : 2010. 5. 13)

  EEPROM이 사용 가능한가를 알아보는 eeprom_is_ready()와 사용 가능할 때까지를 기다리는

  eeprom_busy_wait()를 제공하고, EEPROM에 읽고, 쓰는 eeprom_read_XXX, eeprom_write_XX

  제공. 단, 모든 함수는 폴링을 위한 인터페이스로서 인터럽트 기반 처리를 위해서는 스스로

  구현해야 한다.


  stdio.h :  C언어의 표준 입출력 함수를 제공 (추가 : 2010. 5. 14)

  AVR과 MCU는 제한된 기능으로 인해서 모든 표준 IO 인터페이스가 구현될 수가 없다.

  printf와 scanf를 AVR의 특정 IO로 연결 시키고 싶다면 입출력 함수를 작성해서 이 함수를

  fdev_setup_stream()을 이용해서 stream을 생성/등록하고 이것을 stdin, stdout, stderr과

  연결하면 된다.

ATmega128이나 ARM을 이용하여 작품을 만드는 졸작시즌이 드디어 다가왔습니다! ㅎㅎ

전국의 공대생분들께선 벌써부터 인터넷에 자료를 긁어모으시면서 이리저리 캡스톤을 구상하고 계실텐데요~

오늘은 가장 많이들 사용하시는 CLCD (문자표시용 LCD모듈)에 대해서 정리해보겠습니다! 

저 까짓게..정리라고 하니..우습군요...ㅎㅎ...ㅠㅠ..ㅋㅋ 암튼..필요한분들께 사막이 오아시스가 되길 바라며~ 장황한 설명을 시작하겠습니다! ^^  (70%이해와 실전사용을 목표로 설명하겠습니다.)



1. LCD모듈의 구조


LCD모듈은 문자표시용과 그래픽표시용으로 나누어 집니다. 그중에서 지금 다룰것은 문자표시용입니다.

주로 범용으로 많이 쓰시는 CLCD는 16문자 2라인입니다. (이것은 가로16칸, 세로2칸에 글자를표시할수있다는걸 의미합니다)


먼저 아래의 구조도를 봐주세요~




왼쪽에 5V, RS,RW,E, D0~D7,VL, 0V는 외부핀을 의미합니다. 사각형라인 밖은 외부핀입니다. 당연히 사각형 안은 내부의 데이터흐름을 나타내고 있습니다. 우리는 이 구조도만 이해하면 앞으로 프로그램코딩과 하드웨어 설계가 가능할 것입니다!


하드웨어적인 부연설명을 하자면, LCD모듈은 보통 1~16핀으로 구성되어있고요 위 그림의 왼쪽의  5V, RS,RW,E, D0~D7,VL, 0V이 이 외부핀을 의미하는 것입니다. 실제적으로 LCD모듈이 사용자가 의도하는 어떤 동작을 하기원한다면 MCU를 통해 연결된 이 16핀의 몇개핀에 타이밍에 맞춰서 High Voltage를 흘려주어야 하는거지요.  여기에 대한 구체적인 예가 아래의 2) 데이터 레지스터 DR part에 나와있습니다. 아무래도 글로 설명하기엔 힘듭니다만, 아래의

http://blog.naver.com/meelong0?Redirect=Log&logNo=140104604266

한방인생님의 블로그에 있는 캐릭터LCD사용법을 참조해주세요 ^^;..그림과 함께 아주 알기쉽게 설명되어있습니다.

그런다음, 다시 오셔서 소스를 보시면 이해가 그나마 되실 거에요~


모듈의 구조는 크게 3가지로 나누어 집니다.

 

1) 인스트럭션 레지스터 IR (명령어 레지스터)

 ▶ LCD모듈의 설정 및 동작이 이루어지도록 하는 레지스터입니다. 이것을 통하여 우리는 LCD모듈 화면에 문자를 쓰기도 읽기도 그   

     리고 화면 클리어 등 명령을 줄 수있습니다.


2) 데이터 레지스터 DR

 ▶ 값을 쓰는 곳입니다. AVR을 통해서 원하는 값을 전달하면 (8핀이니깐 AVR에서 Char형 변수로 전달하면 1클럭에 가겠군요^^)

     이곳 데이터 레지스터가 버퍼역할 하여 값을 임시적으로 가지고 있어줍니다. 모든 명령과 디스플레이를 원하는 문자는 이곳을 

     거쳐서 지나간다고 생각하세요 ^^


    //아래의 예제는 ATmega를 기본적으로 사용하실 수 있는분이 아니시라면 나머지 글을 다 읽으시고 보시는게 좋을거 같습니다.

    예시) 구체적인 데이터의 흐름으로 설명하겠습니다.

             AVR에서 LCD화면에 'A'라는 알파벳을 디스플레이하기를 원한다고 가정하겠습니다. 그리고

             AVR의 I/O핀중 PORTA(0~7)가 LCD모듈의 D0~7핀에 모두 연결되어있다고 가정하겠습니다. 

         

 DDRA = 0xFF; //PORTA를 모두 출력으로 설정

             Char value = 'A' ; //value라는 캐릭터형(8bit)변수에 문자 'A'를 대입하라.

             //아래의 ↓소스코드가 실행되기전 IR(명령레지스터)에 LCD에 문자를 뿌려주는 설정을 합니다.

             PORTA = value;  //PORTA에 value값을 전달하라.



또한, 사용자는 위와같은 소스를 작성했다고 하겠습니다.

(사실 데이터 레지스터를 사용하기 위해서는 RS,RW,E 에 대한 신호도 인가해야하지만 나중에 아래에서 설명할것이 때문에

넘어가겠습니다.)

저 코드에서 중요한 부분은 PORTA에 값을 그대로 넣어주었다는 것입니다. 즉 하드웨어적으로 포트A와 LCD모듈의 데이터핀8핀이 1:1로 대응하기에 저런식으로 코드를 작성하는 것입니다 (4핀으로도 제어가 가능합니다. 차후 설명)

            LCD모듈내부에는 AVR에서 'A'라는 문자형변수를 입력했지만 자동적으로 아스키코드로 변환되도록 설계가 되어있기때문             

            에 사용자는 문자를 아스키코드로 변환하여 모듈로 실어 보내지 않아도 됩니다^^


           [흐름] LCD모듈 데이터핀과 연결된 AVR I/O핀에 출력되길 원하는 값을 씁니다. 

                     (RS=1 : 데이터레지스터사용, R/W=0 : 쓰기, E=1 : Enable신호)


                     LCD모듈의 데이터핀은 해당값을 가지고 있어줍니다.

                     LCD모듈의 명령어핀과 연결된 핀에 LCD화면에 해당문자를 출력하라고 명령합니다.

                     LCD모듈은 데이터핀에 있는 값을 화면에 뿌려줍니다.

                     AVR로 LCD모듈에게 중지명령을 내립니다. (RS=1, R/W=1, E=0)

 

           이렇게 위와 같은 형태로 동작을 합니다. 차후 설계된 하드웨어와 LCD구조도를 예제소스와 함께 해석하겠습니다.


3)  DDRAM 과 CGRAM


 DDRAM : 만약 구현하는 모듈이 20(열)X2(행)의 LCD라면 DDRAM은 아래와 같은 주소값을 가지고 있습니다.

              그리고 80X8비트 또는 80문자의 용량을 가지고있습니다. 사용자가 출력할 문자들을 가지고 있을 곳입니다.

              그러나 RAM이기 때문에 전원을 껐다키면 다 삭제되겠지요



CGROM : 8비트 문자패턴을 저장하고 있습니다. 208개의 문자 도트패턴, 문자코드 0x31~0xFF 까지는 아스키코드와 일치합니다

              아스키코드의 번호와 일치하기때문에 위에 설명한 예시에서 처럼 소프트웨어적으로 아스키변환함수를 쓰지않고도 문자를 

              쉽게 출력할수가 있습니다.


CGRAM : 사용자가 직접 문자도트패턴을 만들어 넣을수있는 공간입니다. 한글폰트도 노가다를 좀 하시면 만드실수 있습니다.




2. LCD모듈의 PIN




따라서 위의 핀의 설명대로 ATmega128에 적용하면 아래의 회로도와 같습니다.




3. LCD모듈의 타이밍도


               [읽기 동작 타이밍]


             


              [쓰기 동작 타이밍]



타이밍도를 분석해보면 쓰기와 읽기의 차이는 결국 R/W신호의 High , Low라는것을 알수 있습니다.

그리고 LCD모듈을 컨트롤하기위해서는 반드시 RS, R/W , E 핀제어가 필요하다는것도 알수있구요..

구체적인 타이밍은 아래의 표에 정리되었습니다. 그리고 타이밍도따른 프로그램코딩은 아래의 예제에서 한꺼번에 다루겠습니다.




4. LCD모듈의 레지스터



IR(명령 레지스터)-----------------------------

LCD 화면 클리어, 커서시프트, 문자표시 ON/OFF 등 LCD의 제어에 필요한 명령을 저장.

표시데이터 RAM(DDRAM)의 위치 주소와 문자 발생기 RAM(CGRAM)의 위치를 지정하기 위한 주소 정보를 저장. 


DR(데이터 레지스터)--------------------------

DR 레지스터에 데이터를 쓰면 LCD의 내부적인 동작에 의해서 IR에 의해 지정된 DDRAM 또는  CGRAM의 주소로 전달.

DR 레지스터의 데이터를 읽으면, IR에 의해 지정된 DDRAM 또는 CGRAM의 주소 데이터가 마이크로컨트롤러로 전달. 



[레지스터의 선택]

 RS

R/W 

동작수행

0

0

 IR을 선택하여 제어 명령 쓰기(디스플레이 클리어 등)

0

1

 DB7로부터 비지플래그를 읽기/주소 카운터의 내용을 DB0~DB6으로부터 읽기

 1

 0

 DR을 선택하여 데이터 값을 쓰기(DR 에서 DDRAM 또는 CG RAM로)

 1

 1

 DR을 선택하여 데이터 값을 읽기(DDRAM 또는 CGRAM에서 DR로)

우리가 주로 사용하게 될 레지스터의 선택은 아래의 3,4항목입니다.

RS & R/W 핀에 High 와 Low신호를 인가하게 되고 Enable pin에 High를 주게되면 그때부터 CLCD는 쓰기 모드로 동작합니다. 반대로

RS & R/W 핀에 High 와 High신호를 인가하게 되고 Enable pin에 High를 주게되면 그때부터 CLCD는 읽기 모드로 동작합니다.

따라서 하드웨어 설계시 CLCD핀에 연결한 AVR I/O핀으로 제어를 하게 됩니다 ^^ 그래서 시스템설계자는 반드시 자신이 디자인한 하드웨어를 완벽히 이해하고서 프로그래밍을 하게되겠죠??


덧붙여서 비지플래그도 설명하고 넘어가겠습니다.


[ 비지 플래그] 

연속적으로 LCD 모듈에 제어명령이 입력될 때 LCD모듈이 이 명령을 처리 할 수 있는가를 나타내는 상태 표시 플래그입니다.

LCD모듈은 읽기나 쓰기중일때 다음명령을 바로 처리할수없기 때문에 이전 명령어를 처리할 일정한 시간을 기다려줘야합니다.

말그대로 괜히 Busy라고 붙은게 아니겠죠? ㅎ 코딩하실때 이 값을 읽어서 LCD의 상태를 확인하고 명령을 처리하시면 최상의 시간으로 LCD모듈을 제어하실수 있습니다 ^^ 귀찮으시면 대충 딜레이 조금만 주시고 넘기셔도 무방합니다~


RS=0,          일 때 출력되며, 이 때 BF 플래그는 데이터버스의 DB7로 출력.

BF = 0 : LCD 모듈로 다음명령을 쓸 수 있음.

BF = 1 : LCD 컨트롤러(HD44780U)는 현재 IR로 입력된 명령어를 처리하고 있는 상태로서, 다음 제어 명령을 쓸 수 없는 상태. 


[주소카운터] : LCD 디스플레이창은 아래와 같이 하나의 셀마다 주소값을 가지고있습니다.


위의 경우는 20문자 X 2라인 경우인데 흔히사용하시는 16 X 2라인도 표의 16번째 라인까지만 있다고 생각하시면 동일합니다! 


주소카운터는 DDRAM과 CGRAM의 주소를 지정하는데 사용되며 주소 카운터의 값은 IR레지스터에 기록됩니다.

또한 주소정보는 IR레지스터에서 내부의 주소 카운터로 자동으로 전송되어 해당 주소 카운터의 값으로 세트됩니다.

그리고 DDRAM  또는 CGRAM의 선택은 LCD명령에 의해서 결정이 되며 DDRAM 또는 CGRAM에 데이터를 써 넣으면 주소 카운터는 모드에 따라서 자동으로 1씩 증가하거나 또는 1씩 감소합니다. 나중에 예제를 보시면 이해가 되실겁니다.


[문자발생기 CGROM] : CLCD는 기본적으로 아스키코드와 일치하는 값으로 8비트 문자패턴을 가지고있습니다.

아래의 그림은 CGROM에 저장된 문자패턴입니다. 




[문자발생기 DDRAM] : 위의 기본저장된 문자패턴말고도 CLCD는 사용자가 원하는 문자패턴을 새롭게 만들어 저장하여 사용할수가 있습니다. 약 8비트로 문자로 80문자정도의 용량을 가지고 있습니다.




DDRAM은 사용자가 프로그램에 의해서 원하는 문자 패턴을 만들고자 할 때 사용하는 RAM영역으로써
5Χ8도트의 문자 패턴을 만들 경우, 최대 8종류의 패턴 생성이 가능하며, 5Χ10도트의 경우, 4종류의 문자 패턴 생성 가능합니다.

[새로운 문자를 만드는 방법]


설계된 비트 패턴은 CGRAM 주소로 지정되고, 주소는 6비트를 사용합니다.
5Χ8도트일 경우에 한 문자당 8바이트를 사용되어 문자는 8개로 제한됩니다.

위 그림의 예시를 봐주세요.

문자코드의 비트 4~7이 0일대 선택 (3번 비트는 무효비트)
‘R’문자의 설계- CG 패턴내의 주소 ‘0b000000’∼'0b000111'에 저장- 저장된 문자 코드는 0x00 또는 0x08에 의해 선택- CGRAM으로의 데이터 쓰기/읽기 명령과 함께 사용됨. 


[컨트롤(제어) 명령 모음] : CLCD를 제어하기 위한 명령들입니다. 코드에 해당하는 AVR의 핀에 1,0 신호를 주게 되면 해당되는 명령이 실행이 됩니다.




몇가지를 예로 들어서 설명을 드린다면,

화면클리어를 하고싶다면

RS : 0 R/W : 0 각 핀에 0을 주고 DB7~DB0 핀에 0x01값만 써넣게 되면 CLCD의 화면의 내용은 클리어됩니다.


[CLCD와 AVR간의 인터페이스 회로]



만약 위의 회로대로 하드웨어을 구성하시고 아래의 예제소스 코드를 AVR에 주입하시면 TEST라는 문자가 출력될것입니다.



[예제 소스코드] : 인터넷에 있는 소스코드를 조금 수정해보았습니다 ^^; 컴파일러는 AVR studio 4.0 입니다.


#include<avr/io.h>

#include<avr/interrupt.h>      //인터럽트 헤더 파일

#include<util/delay.h>        //딜레이 헤더 파일


#define LCD_WDATA PORTA     //LCD데이터 포트 정의

#define LCD_WINST PORTA    //

#define LCD_CTRL PORTG    //LCD 제어 포트 정의

#define LCD_EN 0         //LCD 제어(PING0~2)를 효과적으로 하기위한 정의

#define LCD_RW 1

#define LCD_RS 2

#define Byte unsigned char //자주쓰이는 무부호 문자형 자료형을 Byte로 선언




   


/*   [ 정 리 by 도닦는 공돌이] 


     **아래의 프로그램은 다음과 같은 하드웨어용 프로그램입니다.            **

**데이터포트(PORTA의 0~7핀을 모두 사용함), 제어포트(PORTG의 0~2 사용) **


   1) ::IR 명령레지스터 ::


      RS=0 , RW=0 명령레지스터 선택 - 제어명령 쓰기

     RS=0 , RW=1 Busy플래그 읽기, 주소카운터의 내용을 읽기

   


   2) ::DR 데이터레지스터 ::


      RS=1 , RW=0 데이터레지스터 선택 - 쓰기명령

 RS=1 , RW=1 데이터레지스터 선택 - 읽기명령

   

   3) 명령 및 쓰기를 위해서는 RS, RW, E, DATA 신호들을 타이밍에 맞게 입력해야한다.


   4) 데이터를 쓰기전에는 bf값을 읽어보고 실행해야하지만 이 프로그램에선 실행마다 충분한 Delay를 주었고

      BF 프래그를 사용할 만한 처리는 안했기에 함수를 사용하진 않았다. (함수는 존재함)


   5) 주소카운터(ac)로 문자커서 위치선택(DDRAM의 주소)

      윗줄좌측   0X00 ~ 0X0F

      아랫줄좌측 0X40 ~ 0X4F 


   6) ::커서 시프트::


      DB4 =1, DB3=S/C , DB2= R/L


 S/C = 0, R/L =0 : 커서를 좌로 이동 (AC를 -1)

      S/C = 0, R/L =1 : 커서를 우로 이동 (AC를 +1)

      S/C = 1, R/L =0 : 화면전체를 좌로 이동 (커서도 따라감)  

      S/C = 1, R/L =1 : 화면전체를 우로 이동 (커서도 따라감)  

 

 

  

   7) 딜레이 함수의 사용

      IR,DR명령 사용시 화면지움과 커서홈을 제외하고는 40us의 실행시간이 소요됨

 화면지움과 커서홈 IR명령은 1.64ms의 실행시간이 소요


*/



void LCD_Data(Byte ch)

{

LCD_CTRL |=  (1 << LCD_RS);    //RS=1, R/W=0 으로 데이터 쓰기 싸이클

LCD_CTRL &= ~(1 << LCD_RW); 

LCD_CTRL |=  (1 << LCD_EN);    //LCD 사용

_delay_us(50);

LCD_WDATA = ch;                //데이터 출력

_delay_us(50);

LCD_CTRL &= ~(1 << LCD_EN);    //LCD 사용안함


}

  //  0         1      2

void LCD_Comm(Byte ch)   //PG0-EN , PG1-RW, PG2-RS , PG4-TOSC1핀(사용안함)

{       //LCD_CTRL = LCD제어부 포트(4핀인데 실질적인 사용3핀)

LCD_CTRL &= ~(1 << LCD_RS);    // RS=0, RW=0 으로 정의함.

LCD_CTRL &= ~(1 << LCD_RW);    

LCD_CTRL |=  (1 << LCD_EN);    //LCD 사용허가

_delay_us(50);

LCD_WINST = ch;                //명령어 쓰기

_delay_us(50);

LCD_CTRL &= ~(1 << LCD_EN);    //LCD 사용안함

}


void LCD_CHAR(Byte c)  //한문자 출력 함수

{

LCD_Data(c); //CGROM 문자코드의 0x31 ~ 0xFF 는 아스키코드와 일치함!

_delay_ms(1);

}


void LCD_STR(Byte *str)    //↑문자열을 한문자씩 출력함수로 전달

{ while(*str !=0)

{

LCD_CHAR(*str);

str++; 

}

}



void LCD_pos(unsigned char col, unsigned char row)  //LCD 포지션 설정

{

LCD_Comm(0x80 | (row+col*0x40));  // row=행 / col=열 ,DDRAM주소설정

}


void LCD_Clear(void)  // 화면 클리어

{

LCD_Comm(0x01);

_delay_ms(2); //1.6ms이상의 실행시간소요로 딜레이필요 

}



void LCD_Init(void)   //LCD 초기화

{

LCD_Comm(0x38);   //데이터 8비트 사용, 5X7도트 , LCD2열로 사용(6)

_delay_ms(2);

LCD_Comm(0x38);   //데이터 8비트 사용, 5X7도트 , LCD2열로 사용(6)

_delay_ms(2);

LCD_Comm(0x38);   //데이터 8비트 사용, 5X7도트 , LCD2열로 사용(6)

_delay_ms(2);

LCD_Comm(0x0e);   //Display ON/OPFF

_delay_ms(2);

LCD_Comm(0x06);   //주소 +1 , 커서를 우측으로 이동 (3)

_delay_ms(2);

    LCD_Clear();

}



 int main()

 {

DDRA = 0xff; //PORTA(LCD연결포트)를 출력으로 설정

DDRG = 0x0f; //PORTG(LCD컨트롤)의 하위 4비트를 출력으로설정


Byte str1[] = "TEST";


LCD_Init(); //LCD 초기화

LCD_pos(0,1); //LCD 포지션 0열 1행 지정

        LCD_STR(str1); //문자열 str을 LCD출력

LCD_Comm(0x18); //LCD 커서 이동

        while(1);

  }


 








 CLCD 사용하기-2에서는 실질적으로 각각의 파트별로 소스코드를 해체하여 해석해보겠습니다 ^^




TS601 과 CLCD를 ATmega8에서 사용 하기위한 회로도.


이번에 구입한 초음파센서는 가격이 약간 높은 제품입니다ㅎ

하지만 그만큼 측정거리도 길고~ 필터도 내장되어있어서 믿을만합니다^^

http://vctec.co.kr/front/php/product.php?product_no=538&main_cate_no=136&display_group=1



제품설명

HRXL-MaxSonar-WRC 센서는 매우 컴팩트한 형태의 인기있는 초음파 거리측정기 입니다. 만약 크기나 무게에 제한이 없으시다면 비슷한 HRXL-MaxSonar-WR 제품을 검토하여 보십시오.

HRXL-MaxSonar-WRC 센서는 튼튼한 초음파 센서 모듈로 PVC 하우징되어 있으며, 매우 짧은 거리에서 먼거리까지 탐지가 가능한 제품입니다. 이 센서는 IP67 등급의 방수방진 지수를 가지고 있으며, 표준 3/4 인치 전자용 PVC 파이프와 사용이 가능합니다.

높은 음향 출력은 계속적으로 변경되는 gain, 실시간 백그라운드 자동 보정, 실시간 웨이브폼 signature 분석과 함께 결합되면서 사실상 노이즈를 신경쓰지 않고 데이터를 읽을 수 있습니다. 다양한 소리나 전기적인 노이즈가 있는 경우에도 거리 측정이 가능합니다. HRXL‑MaxSonar‑WRC센서 제품군은 공장에서 센서 빔 패턴에 대한 보정을 하였으며 먼 거리에 대한 검출 능력을 제공합니다.

MB7360 은 본 센서의 표준형 버전입니다.
MB7387 은 본 센서의 TTL serial 출력 버전입니다.

제품 개요

  • 분해능: 1 mm
  • 읽기속도: 7.5Hz reading rate(MB7360, MB7380)
  • 빌트인 온도 보정 기능
  • 거리측정용 42kHz 초음파 센서
  • RoHS Compliant
  • 세개의 센서 출력(Analog Voltage, Serial, Pulse Width)에서 데이터 읽음
  • 사실상 데드존이 없음. 30cm보다 가까운 물체는 30cm로 표시함
  • 최대 측정거리: 5000mm
  • 동작전압: 2.7-5.5V
  • 저전력: 2.9mA
  • 작고 가벼운 크기
  • 타켓에 쉽게 연결할 수 있도록 디자인 됨
  • 동작온도: -40˚C to +65˚C
  • 전압, 습도, 노이즈에 대한 실시간 자동 보정
  • 좀더 낳은 노이즈 tolerance와 clutter reject을 위한 펌웨어 필터링
  • 방수방진지수: IP67, Chemical Resistant F-Option (옵션임)
  • 표준 전기 3/4 인치 PVC 파이프와 쉽게 연결
  • 길고 얇은 빔 패턴
  • RS232 Serial 출력

방수방진(IP67) 센서 제품 및 Optional Chemical Resistance

산업용 실외용 HRXL-MaxSonar-WRC 센서 제품군은 방수방진지수 IP67을 만족시키기 위하여 강한 PVC 하우징으로 디자인되었습니다.본 센서들은 짧은 거리에서 먼거리까지 좁은 빔 패턴을 통하여 탐지를 할 수 있습니다. HRXL-MaxSonar-WRC 실외용 초음파 센서는 높은 출력 전력을 가지고 있으며, noise rejection, auto calibration, factory calibrated beam pattern을 가지고 있습니다. 사용자는 어플리케이션에 맞는 출력방법과 필터를 가진 센서를 선택할 수 있습니다. analog voltage 출력, serial digital 출력, pulse width 출력 이나 real-time analog envelope 출력을 가진 모델들을 선택할 수 있습니다.

또 몇몇 위험한 화학적 환경에서 제품을 보호하기 위한 F-Option 을 제공합니다. 매우 부식성이 높은 가스나 액체는 센서의 동작을 저하 시킬 수 있어 이러한 옵션은 극단적인 안좋은 화학적 환경을 제외하고 센서가 정상적으로 동작할 수 있다록 만들어 주며, 또한 습기나 먼지가 많은 환경에서 좋은 성능을 낼수 있도록 도와 줍니다.

방수방진 제품

적절하게 설치된 HRXL-MaxSonar-WRC 센서 제품군의 노출부는 알루미늄(oxidized surface, 트랜스듀서 커버), PVC(하우징 재질), 실리콘 고무 (VMQ, O-ring) 입니다.

F-Option

F-option이 장착되어 설치된 HRXL-MaxSonar-WRC 센서 제품군의 노출부는 트랜스듀서 커버), PVC(하우징 재질), Flourosilicone (with an additional back up FEP Teflon® seal,O-ring)입니다.

추가적인 고려사항

센서의 오랜 동작을 담보하기 위해서는 전기적 연결부위가 물, 먼지나 다른 화학품에 노출되지 않아야 합니다. 센서를 설치할때 이점을 유의하시기 바라며, 표준 3/4인치 파이프를 사용하시면 쉽게 설치가 가능합니다. MB7950 Mounting hardware 또한 구매가 가능합니다.

센서는 공기중에서 동작하도록 디자인 되어 있지만 다른 가스에서도 동작이 가능합니다. 공기와 다른 가스는 소리의 전달 속도가 다르기 때문에 올바른 동작을 위해서는 충분한 테스트가 필요하며, 소리 전달 속도 차이에 따른 보정이 필요합니다. 이러한 보정은 2 point linear calibration을 통하여 종종 이루어 집니다.

튼튼하고 신뢰성 높은 실외용 초음파 센서

산업용 HRXL‑MaxSonar‑WRC 제품군은 시장에 있는 제품들중에 비용대비 최고의 품질을 자랑합니다. 이 제품군은 사용하기 쉽고, 방수방진이 되며, 센서 데드존이 없고, 좁은 빔 패턴을 가지도록 보정되었으며, 안정적인 데이터 리딩과, 저전력 등의 기능을 가진 산업용 제품입니다. 좀 더 자세한 사항은 데이터쉬트를 참고하십시오.

HRXL-MaxSonar-WRC 센서 제품군은 불안정한 읽기 능력, 높은 전력 및 크기 등으로 인해 전통적으로 초음파 센서가 사용되지 않았던 어플리케이션에 많이 사용됨으로써 초음파 센서 산업에서 혁신의 아이콘으로 자리잡았습니다.

노이즈 필터링

센서는 외부의 전기적, 음향적 노이즈 소스에 대해 동적으로 자신의 감도를 조정합니다.

내부 온도 보정

공기중 소리의 속도는 초당 0.6m/s 이며 온도변화시 속도가 변하게 됩니다. 이러한 이유 때문에 HRLV‑MaxSonar‑EZ 은 내부 온도센서를 장착하고 있으며, 온도에 대한 보정을 적용하게 됩니다.

내부 온도 센서 때문에 초음파 센서를 Power-up시키고 읽는 거리값(20초이내)은 매우 정확합니다. 그렇기 때문에 대부분의 경우 센서를 끄고 있는 어플리케이션의 경우에 매우 이상적입니다. 하지만 센서의 self heating (15mW at 5V, or 8mW at 3.3V)은 센서의 온도를 약 3도가량 변경(어떻게 설치하였느냐에 따라 편차가 존재)시키고 결과적으로 공기중의 온도를 부정확하게 읽게 만듭니다.

외부 온도 센서

HRXL-MaxSonar-WR 제품에 연결된 HR‑MaxTemp 온도센서를 통해서 실시간 온도 자동 보정이 가능합니다. HR-MaxTemp 은 HRXL-MaxSonar-WRC 센서가 공기중 온도 변화는 관찰할 수 있게하며 self-heating은 무시됩니다.

Self-heating은 내부 온도 센서의 온도가 2에서 5도 정도 증가하는 문제인데, 이러한 self-heating을 제대로 처리하지 않으면 대략 3%정도의 결과값에 오차를 유발하게 됩니다.

HRXL-MaxSonar-WRC 제품은 HR‑MaxTemp 온도 센서와 같이 사용할 수 있게 디자인 되었습니다. HRXL-MaxSonar-WRC 에 전원 인가시 붙어 있는 온도센서를 검출하고 온도변화에 따른 소리 속도 변화에 대한 보정을 모든 출력값에 적용합니다.

인터페이스

HRXL‑MaxSonar‑WR 인터페이스는 사용하기 쉽게 직관적으로 디자인 되었습니다. 인터페이스의 출력은 pulse width 출력, analog voltage 출력과 asynchronous serial RS232 or TTL출력이 있습니다. 모든 인터페이스는 사용자코드나 복잡한 셋업없이 동작합니다.

전력 요구사항

HRXL‑MaxSonar‑WR 제품군은 2.7V 에서 5.5V 동작전압범위를 가집니다. 이것은 3.3V 나 5V 시스템에 쉽게 연결이 가능하게 하고 저전압의 MCU사용자나 배터리로 동작하는 시스템에서도 사용가능한 것을 의미합니다. 센서에 추가적인 전원을 공급할 필요가 없습니다.

HRXL‑MaxSonar‑WR 센서 제품군은 동작시 평균적으로 3.1mA 전류를 필요로합니다.

Controlled Narrow Beam Shape

시중의 초음파 센서 제품들은 잦은 side lobe detection과 센서 옆이나 또 뒤에 있는 물체까지도 검출할 때가 있습니다. HRXL‑MaxSonar‑WR 제품군은 controlled narrow beam shape으로 빔 공간 영역 바깥의 작은 물체(clutter)들은 reject하고 올바른 타켓에 대한 긴 측정 범위의 감도를 제공합니다.

보정

각각의 HRXL‑MaxSonar‑WR 제품은 적절한 동작을 위해서 공장에서 생산시에 테스트 되었고, 생산된 제품들이 동일한 동작을 하게 하기 위해 공장에서 보정된 빔 패턴을 가지고 있습니다.

HRXL‑MaxSonar‑WR 제품군은 측정값을 읽을 때마다 주위 환경에 대해 자동적으로 보정을 합니다. 이러한 보정은 온도, 전압, 습도, acoustic noise, 전기적인 노이즈 및 온도변화를 고려한 보정값입니다.



MB7367.pdf



'Nobody tells you about.. > Ultrasonic' 카테고리의 다른 글

[NT-TS601] 3핀 초음파센서  (10) 2012.10.23

USB전원으로 저전압 스피커를 하나 만들생각이 있어서 하나 만들어봤습니다 ㅎㅎ

DATAsheet는 게시판에 존재하는 LM386N-1 입니다 ^^

 

 

아래는 완성된 스피컵(?)의 초기형태입니다..^^; 뭔가 수정해야할게 많아보이네요..ㅜㅜㅋㅋ

 

 

 


이번에 프로젝트때문에 초음파센서가 필요해서 하나 주문해서 구현해봤습니다.^^



기존의 많이 사용하시는 SRF-04 (핀4개) 와는 다르게 핀이 3개밖에 없어서 처음에 이게 뭔가 했는데요..

원리는 간단했습니다. 




[제품의 동작방법]


먼저 MCU 의 출력핀으로 NT-TS601 의 SIG 핀에 Input trigger pulse(t1)를 보내줍니다.

NT-TS601 의 SIG 핀에 Input trigger pulse 를 받은 NT-TS601 의 초음파센서 TX pin 에서

40kHz 로 Burst pulse 를 발생합니다.

Output echo pulse 가 나타날 때까지 Echo postpone(t2)을 기다립니다.

Burst pulse 가 물체에 반사되어 올 때까지 Output echo pulse 를 체크합니다.

MCU 가 입력받은 Output echo pulse 의 폭을 측정하여 거리로 나타낼 수 있습니다.

다시 측정하기 위해서는 최소 200 μs 이상 기다린 후에 Input trigger pulse 를 보냅니다.




즉, 간단하게 말해서 MCU에게 High신호를 센서핀에게 줘라 -> 센서는 초음파를 쏘고 -> 기다렸다가 동일한 핀으로 초음파에서 출력했던 펄스가 물체를 감지후 돌아온 에코펄스를 읽어라. 그러나 여기서 중요한것은 에코펄스를 읽을때 인터럽트가 걸리는 시간을 이용해서 물체의 거리를 측정한다는 것입니다.


음파 속도 V = 331.5 + 0.60714 T [m/s]


그러나 센서의 동작 범위의 0 ℃에서 70 ℃까지로 오차는 약 11 ~ 12 % 정도입니다. 따라서 주위 온도에 의해서 음속이 변함으로 정밀도가 높은 거리를 측정할 경우에는 온도 보상을 필요로 합니다. 아무래도..온도센서를 사용해서 함께 구현해야지 않을까 생각이 되네요.그리고 초음파의 특성상 측정되는 오브젝트의 형태(곡면일경우 또 반사되겠죠?)와 재질(천인지 금속인지에따라)에 또 측정값이 변할테니..신뢰성있는 값을 얻어내려면 평균값필터나 무빙에버레지도 필요할듯 합니다.


아래는 업체(엔티렉스)에서 제공하는 공개소스입니다.


/********************************************************************************

Title : TS601 module TEST Code

MCU : Atmega32

외부 xtal : 16MHz

File Name : ultra00.c

  

Data : 2008/06/27 (Ver1.1)

Notice : 아래 코드는 TS601 module TEST 프로그램이며

이 프로그램을 이용하여 발생하는 모든 문제에 대해서는

(주)엔티렉스에서는 어떠한 법적 책임도 지지 않습니다.

 참고

 1. TS601 module의 SIG pin과 Atmega32 PD3 pin 사이에

1kΩ을 넣도록 권장합니다.

 2.RS-232C 통신을 통한 하이퍼터미널로 확인할 수 있습니다.

( 9600 bps / 8-n-1 )

*******************************************************************************/

#include "io.h"

#include "interrupt.h"

#include "delay.h"


#include "avrlibdefs.h"

#include "avrlibtypes.h"


#define PD3pin_clear cbi(PORTD, 3)

#define PD3pin_set sbi(PORTD, 3)

#define PD3pin_IN cbi(DDRD, 3)

#define PD3pin_OUT sbi(DDRD, 3)


#define TEMPERATURE 25


// global variable

volatile u16 tick = 0;

volatile u16 pulse_check = 0;

volatile u16 pulse_end = 0;


void PORT_init(void)

{

PORTA = 0x00;

DDRA = 0xFF;

PORTB = 0x00;

DDRB = 0xFF;

PORTC = 0x00;

DDRC = 0xFF;

PORTD = 0x08;

DDRD = 0xFA;

}


void EXTINT_init(void)

{

MCUCR = 0x6F;

GICR = (1<<INT1);

GIFR = 0x00;

}


void TIMER0_COMPA_init(void)

{

TCCR0 = (1<<WGM01)|(1<<CS01);

TCNT0 = 0;

OCR0 = 19; // 1cycle --> 20us = 1/(16M/(2*8*(19+1))

TIMSK = (1<<OCIE0);

TIFR = 0x00;

}


void USART_Init( void )

{

/* Set baud rate 16MHz, 9600 bps */

UBRRH = 0x00;

UBRRL = 103;

/* Enable transmitter */

UCSRB = (1<<TXEN);

/* Set frame format: 8data, 1stop bit */

UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

}


void USART_Transmit( unsigned char ultrasonic )

{

/* Wait for empty transmit buffer */

while ( !(UCSRA & (1<<UDRE)) );

/* Put data into buffer, sends the data */

UDR = ultrasonic;

}


ISR(TIMER0_COMP_vect) //핵심소스는 이부분이 되겠네요..ㅎ

{

tick++;

}


ISR(INT1_vect)

{

u16 pulse_tick;

pulse_tick = tick;


if( MCUCR & 0x0C ) {

MCUCR &= 0xF3;

tick = 0;

}

else {

MCUCR |= 0x0C;

pulse_end = pulse_tick;

}

}



int main(void)

{

unsigned char thousand, hundred, ten, one;

float distance;

PORT_init();

EXTINT_init();

TIMER0_COMPA_init();

USART_Init();

_delay_ms(50);


while(1)

{

cli();

PD3pin_clear;

PD3pin_OUT; // PD3 pin is output

_delay_us(500);


PD3pin_set; // output set during 5us

_delay_us(5);


PD3pin_clear;

_delay_us(100);


PD3pin_IN; // PD3 pin is input

_delay_us(100);


sei();


/* distance = velocity * time */

distance = (331.5+(0.6*TEMPERATURE))*(pulse_end*0.00001/2)*1000;


/* distance digit display */

thousand = distance/1000;

USART_Transmit(thousand + 48);

distance = distance - (thousand * 1000);


hundred = distance /100;

USART_Transmit(hundred + 48);

distance = distance - (hundred * 100);


ten = distance/10;

USART_Transmit(ten + 48);

distance = distance - (ten * 10);


one = distance;

USART_Transmit( one + 48);

USART_Transmit(109);

USART_Transmit(109);

USART_Transmit('\n');

USART_Transmit('\r');

_delay_ms(100);


}

return 0;

}



USART통신으로 PC상에 뿌려주는 코드입니다. 저는 이게 귀찮아서 바로 ATmega8에 연결한 CLCD에 뿌려봤습니다.
처음 ATmega8을 사용하시는 분이 계실까봐 아래에 주석을 남깁니다.^^
(그리고 ATmega8로 CLCD를 사용하시면 데이터핀을 8개 쓸만큼 여유가 없기때문에 설계하실때 4핀으로 제어하셔야 합니다.)

/* -------------------------------------------인터럽트 서비스 루틴----------------------------------------------- */


ISR(TIMER2_COMP_vect) //타이머 인터럽트 서비스 루틴 ->언제 실행되는가? -> 비교일치 
{
tick++;
}

ISR(INT1_vect) //외부 인터럽트 서비스 루틴
{
u16 pulse_tick;
pulse_tick = tick;  //타이머 인터럽트 서비스루틴에서 계수된 인터럽트값을 pulse_tick 에 저장.

if( MCUCR & 0x0C ) // INT1이 The rising edge일때 인터럽트를 감지하는 상태라면
{
MCUCR &= 0xF3;  //로우레벨 감지로 변경시키고(인터럽트를 끄는느낌) 초기화.

tick = 0;  //타이머 인터럽트의 변수를 초기화.
}
else  //그리고 다음 싸이클에서 다시 인터럽트 시작.
{
MCUCR |= 0x0C;  // INT1을 The rising edge 감지상태로 다시 만들어줌.
pulse_end = pulse_tick; //계수된 펄스값을 저장함.
}
}

결국 아트메가32나 8이나 동일하더군요..ㅎㅎ 그냥 ATmega128과 MCUCR때문에 조금 차이가 있을뿐입니다.
128에서 TIFR, TIMSK와 같은 레지스터가 있어서 인터럽트에 대한 설정들을 했었지만 ATmega 8과 32 시리즈는 MCUCR레지스터로 제어 한다것만 달랐습니다. ^^



어쨌든 위와 같이 ATmega8A 로 2개의 TS601을 구현할수가 있었습니다~ 온도센서는 제 블로그에 있는 NTC-10KD-5J를 사용해서 보상했으며 평균값함수를 사용하니 거리의 오차는 1%미만, 최대 측정거리는 3.3M 였습니다 ^^



NT-TS601.pdf


'Nobody tells you about.. > Ultrasonic' 카테고리의 다른 글

[HRLV-MaxSonar-WRC] MB7367 초음파센서  (0) 2012.10.23

올해 초 처음으로 만든 기판입니다 ^^;

처음이라 엉성하고..이것저것 잘못된게 많더군요...지적은 말아주세요..ㅠㅠ

기본적으로 부저,키패드,온도,조도센서,CLCD,LED 정도 사용이 가능합니다.






너무 오랜만에 포스팅을 하는거 같습니다..ㅠㅠ 몇달만인지...

그래서 하루방문자는..여전히..2자리에..1과~2를 왔다갔다..ㅋㅋ

이제부터 열심히 하겠습니다!ㅎ 그동안 쌓아놓은 자료들이 참 많습니다! ㅎ

여튼 여담은 여기서 끝내고 MCU 내부구조에 대해서 자세히 알아보겠습니다^^

-------------------------------------------------------------------------------

STACK POINTER 의 뒤를 이어서~ 이번에는 왼쪽 부분의 구조를 살펴보겠습니다.




6) 프로그램 카운터


프로그램 카운터는 내가 실행시킨 명령어의 주소를 가리키는 역할을 한다.

자 이게 무슨말이냐 하면 이전에 ATmega128은 플래시 프로그램 메모리를 128K 가지고 있다고 하였습니다.

이 메모리는 응용프로그램부 (사용자가 직접 코딩하여 만든 프로그램을 넣는공간)와 부트 프로그램부로 나눠지고

응용프로그램은 그냥 시스템에 전원이 들어오면 막 실행되는 것이 아니라 "프로그램 카운터"를 거쳐서 실행이 됩니다.

즉, 프로그램의 실행은 MCU가 프로그램카운터가 가리키는 주소의 명령어를 차례대로 실행시키는데 그 주소가 

아마 응용프로그램부의 프로그램을 가리키니깐 우리가 코딩한 프로그램이 실행이 되겠지요? ㅎㅎ


따라서, 

프로그램 카운터 = 줄여서 PC 라고 하겠습니다! 


PC의 크기는 16bit 이고~ 그래서 64[Kword](2x64Kbyte) = 128Kbyte)의 FLASH PROGRAM MEMORY 공간을 가리킬수 있습니다.


7) 명령어 레지스터 (Instruction register)


앞에서 PC는 명령어 실행을 위해 플래시 프로그램메모리의 주소를 가리키고있다고 했습니다. 그럼 가리키고만 있으면 무언가 실행이 될까요? 아마 안되겠죠? 그래서 명령어 레지스터는 해당된 주소의 저장된 명령어를 명령어 레지스터로 인출합니다 ^^

(그리고 각 명령어는 "명령코드,오퍼랜드,연산결과가 저장될 내용(항목)"들을 가지고 있습니다.)


(오퍼랜드 : 컴퓨터 프로그래밍에 있어서 연산 대상이 되는 값이나 변수를 지칭하는 말이다. 연산 내용을 나타내는 기호는 [연산자] 또는 [오퍼레이터(operator)]라고 한다. 예를들어 [A + 10]라는 식에서, [A]와 [10]은 오퍼랜드이며, [+]는 오퍼레이터이다. 기계어나 어셈블리 언어에서는 명령 대상이 되는 레지스터나 값을 오퍼랜드라고 부른다.)


8) 명령어 디코더 (Instruction decoder)


명령어 디코더는 명령어 레지스터로 가져온 명령어를 디코딩하여 명령코드에 해당하는 제어신호를 만듭니다.

따라서 위의 일련의 과정을 따라서 우리가 코딩한 프로그램이 PC를 통해 명령어 레지스터로 가져와지고 명령어 디코더로 해석되어져서 제어신호가 나오고 ALU로 전달되거나 그 결과값이 어딘가 저장되는 겁니다. 오해하시면 안되는 부분이 명령어를 해석하고 바로 I/O핀으로 출력신호가 나오는것이 아니라~ 이제 연산과정을 거치러 ALU로 이동한다는것입니다 ^^



**상태레지스터 예제문제**

이런건 시험에서 많이 출제하시더라구요..ㅎㅎ 제가 다니던 학교에서도 이걸 풀었습니다..ㅠㅠㅋㅋ 

아무쪼록 도움이 되었으면 합니다 ^^


I(7) : interrupt enable    1= 전체 interrupt enable, 0 = 전체 인터럽트 disable


T(6) : 비트 복사 저장,

      BST명령으로 레지스터의 한 비트를  T bit에 복사한다.

      BLD명령으로 T bit를  레지스터의 한 비트에 복사한다.


H(5): half carry flag  :   0000 1000 + 0000 1000 <-이와같이 연산결과 비트3에서 비트4로 캐리가 발생하면 1이 된다. half carry 발생

                                 이는 BCD연산에 유용하다.

 

S(4):  sign bit :  V 배타적 OR  N (XOR을 의미합니다)


V(3): overflow bit  :  2의 보수 오버플로 플래그 (그냥 오버플로가 아닙니다!), 비트7과6의 배타적 OR


N(2): negative bit :  연산결과가 MSB가 1이면 이 플래그가 1인된다. 음수라는 의미임


Z(1): zero bit : 연산결과 모든 비트가 0이면 이 플래그가 1이 된다. 0을 나타냄


C(0): carry bit : 연산결과 MSB에서 캐리가 발생하면 1이 된다.


[예제] 아래는 두수의 연산에 대한 결과를 상태레지스터로 나타낸 도표이다. 이를보고 두수의 관계를 설명하라.

 

 

 N

Z 

C 

관계 

설명 

 i = i - k;

1

0 

i < k

연산결과가 음수이며 캐리비트가 1이기 때문에 연산시 캐리를 빌려왔다. 따라서 i가 k보다 작다. 

 i = i + j;

 0

0 

알수없다 

결과가 음수인지 양수인지 알수없다. 단지 캐리비트가 1이라는 사실로는 아무것도 알수없다. 

 i = i - o;

0 

1 

i = 0 

Z비트가 1이면 연산결과가 0이다. 따라서 둘의 관계는 같다




**추가적으로 SREG는 가장 최근에 실행된 산술연산의 결과 정보를 저장합니다. 이 결과에 따라 다음에 실행되는 명령어에 영향을 끼치는 데요..문제는 ATmega128이라는 녀석은 인터럽트가 발생했을때 상태 레지스터를 하드웨어가 자동으로 저장않습니다. 따라서 소프웨어적으로 인터럽트 발생시 상태레지스터를 저장하고 인터럽트수행후 다시 복원을 해야 오류가 발생하지 않습니다.



갑자기 궁금해서 올려봅니다..ㅎㅎ BCH 와 BCD 란 무엇일까요? ---------------------------------


그전에 주의하실점은 같은 철자의 약자를 가진 BCH,BCD가 많다는 것입니다 ^^;

참고로 여기서 설명하는것은 MCU 프로그램을 코딩하실때 사용하시는 코드입니다~!


BCH (binary-coded hexadecimal) 

: 4자리의 2진법으로 표현된 16진법입니다!


16진 

BCH 

10진 

 0

0000

0001 

0010 

0011 


즉, BCH로 표현할수있는 숫자는 총 16가지 (2 X 2 X 2 X 2 = 16) 입니다. 0~15까지. 이는 하나의 BCH 숫자는 1개의 바이너리로 표현되기때문입니다. 또한, 이것은 C언어에서 사용하는 int형(signed)과 동일하겠군요..그럼 활용할수있는 방법이 떠오르시죠?..

그리고 AVR (저는 주로 AVR Studio를 사용합니다 ㅎ) 에서는 RAM주소와 같은것을 표현할 때 주로 사용합니다. 

ex) 0000H ~ FFFFH 따위로 표현.  

그렇지만 실제 코딩에서는 0X00  , 0X01 과 같은 1개의 자리가 16진을 의미하는 16진법형 표현을 가장 많이 사용합니다.

ex) 0x00 = 0000 0000 (2진법) = 0 (10진법) 을 의미합니다.

      0x10 = 0001 0000 (2진법) = 16 (10진법) 을 의미합니다.

      0x23 = 0010 0011 (2진법) = 35 (10진법) 을 의미합니다.


위의 예제를 보시면 이해가 아마 되실거라 생각됩니다. 나중에는 저 숫자들만 봐도 머릿속에서 자동으로 암산이 되실겁니다..^^:

실제적으로 가장많이 사용하는 형태이기때문에 헷갈리시지 않도록 잘 정리하시길 바랍니다.


BCD (binary-coded decimal) ------------------------------------------------------------------

: 2자리의 2진법으로 표현된 10진법입니다.



10진

BCD 

10

0001 0000 

12 

0001 0010 

32 

0011 0010 


+ Recent posts