Dealing with 16-bit extended SFRs

Technical Note 24209

Arkitekturer:

AVR

Komponent:

compiler

Uppdaterad:

2015-11-02 11:57

Introduction

This tecnical note discusses how access the special function registers (SFRs) in an AVR device.

Background

The AVR microcontrollers comes with more and more special function registers (SFRs) to deal with the increasing amount of on-chip peripherals. In the original AVR instruction set, special instructions were set aside for accessing SFRs, but the SFRs were also present in the memory map (at a slightly different address).

16-bit SFRs requires a certain access order for proper access. The compiler knows about this when it deals with the SFRs that are within the original SFR area (using the special I/O instructions) and takes appropriate actions to ensure correct byte access order.

SFRs that are outside the original SFR area are called Extended SFRs and have to be accessed as normal memory mapped variables. Unfortunately, the compiler cannot automatically meet the byte access order requirement for extended 16-bit SFRs as they share the access mechanism with normal variables that does not impose such restrictions.

Suggestions

Here follows some useful macros that shows correct 16-bit access of extended SFRs:

#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);\
}

As an example how they can be used:

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

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

Note that the macros add the 'L' and 'H' to the SFR name automatically, you only need to specify the base name of the 16-bit SFR.

The atomic versions of the macros protect the access by disabling interrupts. If you know that your code section will run with interrupts turned off, you can use the corresponding macros without _atomic to save code space and execution time.

 

All product names are trademarks or registered trademarks of their respective owners.

Det här innehållet finns tyvärr inte på svenska.

Vår webbplats finns främst på vårt koncernspråk engelska, förutom det innehåll för investerare som vi är lagstadgade att kommunicera på svenska. Vi rekommenderar att du besöker vår globala webbplats på engelska för att få en bättre upplevelse.

Vi stöder inte längre Internet Explorer. För att få bästa möjliga upplevelse av iar.com rekommenderar vi att du uppgraderar till en modern webbläsare som Chrome eller Edge.