Dealing with 16-bit extended SFRs

Technical Note 24209

Architectures:

AVR

Component:

compiler

Updated:

11/2/2015 11:57 AM

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.

We do no longer support Internet Explorer. To get the best experience of iar.com, we recommend upgrading to a modern browser such as Chrome or Edge.