16비트 확장SFR 다루기

기술노트 24209

아키텍처:

AVR

컴포넌트:

compiler

업데이트:

2021-05-06 오후 3:54

소개

본 기술 노트는 AVR 장비의 특수기능 레지스터(SFRs; Special Function Registers)에 어떻게 접근하는지 설명합니다.

배경지식

AVR 마이크로컨트롤러는 점점 더 많은 특수기능 레지스터(SFRs)를 갖추어 점점 증가하는 칩상의(on-chip) 주변장치들을 처리할 수 있습니다. 본래 AVR 명령어집합에는, SFR에 접근하기 위한 특별한 명령어들이 따로 마련되어 있었으나, SFR은 메모리 맵에도 존재했습니다. (약간 다른 주소).

16비트 SFR에 접근하기 위해 특정한 접근 순서가 필요합니다. 컴파일러는 기본SFR영역 내에 있는 SFR을 다룰때 (특수한 I/O 명령을 사용할때) 특정한 접근 순서에 대해 알고 올바른 바이트 접근 순서를 보장하기 위해 적절한 작업을 수행합니다.

기본SFR영역 밖의 SFR을 확장 SFR이라고 하며 일반 메모리 맵 변수로 접근해야 합니다. 안타깝게도, 컴파일러는 16비트 확장SFR을 위해 바이트 접근 순서요건을 충족할 수 없습니다. 일반 변수에 접근하는 방식을 공유하기에 이러한 제한을 적용하지 않습니다.

제안

여기 유용한 매크로를 참고하여, 16비트 확장SFR에 접근하는 올바른 방식을 살펴보세요:

#define __out_word(BaseName, value)\ 
{\
unsigned char _tH=(value) >> 8;\
unsigned char _tL=(value) & 0xFF;\
BaseName ## H = _tH;\
BaseName ## L = _tL;\
}
#define __out_word_atomic(BaseName, value)\ 
{\
unsigned char _t=__save_interrupt();\
__disable_interrupt();\
__out_word(BaseName,value);\
__restore_interrupt(_t);\
}
#define __in_word(BaseName, value)\ 
{ (value) = (BaseName ## L);\
(value) |= (unsigned short)BaseName ## H << 8;\
}
#define __in_word_atomic(BaseName, value)\ 
{\
unsigned char _t=__save_interrupt();\
__disable_interrupt();\
__in_word(BaseName, value);\
__restore_interrupt(_t);\
}

사용 방법에 대한 예제입니다:

#include <inavr.h>
#include <iom128.h>

void main ()
{
int value;
__in_word_atomic(TCNT3, value);
__out_word_atomic(OCR1C, value);
}

보시는 바와 같이, 매크로에서 SFR의 이름에 자동으로 'L'과 'H'를 추가합니다. 16비트 SFR의 기본 이름만 지정하면 됩니다.

매크로의 원형엔 인터럽트를 비활성화함으로써 접근을 보호합니다. 인터럽트가 꺼진 상태에서 코드 섹션이 실행된 다는 것을 알고 있는 경우 _atomic 없이 해당 매크로를 사용하여 코드 공간과 실행 시간을 절약할 수 있습니다.

 

모든 제품 이름은 해당 소유자의 상표 또는 등록 상표입니다.

죄송하지만, 당사 사이트에서는 Internet Explorer를 지원하지 않습니다.보다 편안한 사이트를 위해 Chrome, Edge, Firefox 등과 같은 최신 브라우저를 사용해 주시길 부탁드립니다.