Arduino µC Status Register (SREG)

bling

Like all microcontrollers the arduino’s AVR µC has a flag register to indicate various conditions. The Status Register is referred to in short as the “SREG”, and can be directly referenced inline using __SREG__. It is an 8-bit wide register, containing 6 condition flags, a control register and a special bit instruction register.

sreg

The status register bits are:
C – Carry flag
Z – Zero flag
N – Negative flag
V – Overflow flag
S – Sign flag
H – Half carry
T – Bit Copy storage
I – Global Interrupt Enable flag

The following is a brief explanation of each bit of the Status Register.

C – Carry Flag

This flag is set whenever there is a carry out of the 7th-bit position (MSB). This bit is affected after an 8-bit addition or subtraction operation.

Z – Zero Flag

The zero flag reflects the result of an arithmetic or logic operation. If the result is zero, then this bit = 1, conversely, if this bit = 0, the result was not zero. This flag is very useful for controlling program loops.

N – Negative Flag

The negative flag reflects the result of an arithmetic operation. Signed numbers use the 7th-bit (MSB) as a sign bit. If the 7th-bit of the result is zero, then this flag = 0, meaning the result is positive. Conversely, if the 7th-bit of the result is set, then this flag =1, and the result is negative. The Negative (N) and Overflow (V) flags are used for signed number arithmetic operations.

V – Overflow Flag

This flag is set whenever the result of a signed number operation is too large, causing the high-order bit to overflow into the sign bit. In general, the Carry flag (C) is used to detect errors in unsigned arithmetic and the Overflow flag (V) is used to detect errors in signed arithmetic operations. Both the Overflow (V) and Negative (N) flags are used for signed arithmetic operations.

S – Sign Flag

This flag is the result of an Exclusive-OR of the Overflow (V) and Negative (N) flags.

H – Half Carry Flag

If there is a carry from bit 3 to 4 during an ADD or SUB operation, this bit is set, otherwise it is cleared. This flag is used for Binary Coded Decimal arithmetic.

T – Bit copy Storage Bit

The T bit is used as a temporary storage location for bit operations involving the BLD and BST instructions. BLD, or Bit LoaD copies the T flag in the Status Register to a particular bit in a register.

BST, is Bit STore from a bit in a register to T flag in the Status Register. Here is how we can use these instructions:

asm (
  //Copy bit
  "clr r0 \n"
  "ldi r16, 0b00000100 \n"
  "bst r16, 2 \n" //Store bit 2 of r1 in T flag
  "bld r0, 4 \n" //Load T into bit 4 of r0
  : : : "r0", "r16"
);

There are several additional instructions that specific manipulate or reference the T-flag. SET (Set T Flag), CLT (Clear T Flag), BRTS (Branch if the T Flag is Set), and BRTC (Branch if the T Flag is Cleared).

I – Global Interrupt Enable

This bit must be set for interrupts to be enabled. It is cleared by the microcontroller after an interrupt has occurred, but may be set again manually with the sie() instruction to allow nested interrupts. It is also set by the RETI instruction upon completion of the interrupt. This enables subsequent interrupts. In addition to this Global Interrupt Enable flag, each individual interrupt enable bit(s) must be set in the appropriate control register.

For example, for timer counter 1, both the timer 1 overflow interrupt enable bit (TOIE1) and global interrupts need to be enabled, to allow the TCNT1 over flow to cause an interrupt.

To set the Global Interrupt Flag, use the SEI, or SEt global Interrupt Flag instruction. The instruction following SEI will be executed before any pending interrupts.

To clear the Global Interrupt Flag, use the CLI, or CLear global Interrupt Flag instruction. Interrupts will be immediately disabled. No interrupt will be executed after the CLI instruction, even if it occurs simultaneously with the CLI instruction.

asm (“sei \n”);
asm (“cli \n”);

Instructions That Affect Flag Bits

Inst.   Z  C  N  V  S  H  T  I
------------------------------
ADD     Z  C  N  V  S  H  -  -
ADC     Z  C  N  V  S  H  -  -
ADIW    Z  C  N  V  S  -  -  -
AND     Z  -  N  V  S  -  -  -
ANDI    Z  -  N  V  S  -  -  -
ASR     Z  C  N  V  -  -  -  -
BST     -  -  -  -  -  -  T  -
CBR     Z  -  N  V  S  -  -  -
CLC     -  C  -  -  -  -  -  - 
CLH     -  -  -  -  -  H  -  -
CLI     -  -  -  -  -  -  -  I
CLN     -  -  N  -  -  -  -  -
CLR     Z  -  N  V  S  -  -  -
CLS     -  -  -  -  S  -  -  -
CLT     -  -  -  -  -  -  T  -
CLV     -  -  -  V  -  -  -  - 
CLZ     Z  -  -  -  -  -  -  - 
COM     Z  C  N  V  S  -  -  -
CP      Z  C  N  V  -  H  -  -
CPC     Z  C  N  V  -  H  -  -
CPI     Z  C  N  V  -  H  -  -
DEC     Z  -  N  V  S  -  -  -
EOR     Z  -  N  V  S  -  -  -
INC     Z  -  N  V  S  -  -  -
LSL     Z  C  N  V  -  H  -  -
LSR     Z  C  N  V  -  -  -  -
NEG     Z  C  N  V  -  H  -  -
OR      Z  -  N  V  S  -  -  - 
ORI     Z  -  N  V  S  -  -  -
ROL     Z  C  N  V  -  H  -  -
ROR     Z  C  N  V  -  -  -  -
SBR     Z     N  V  -  -  -  -
SBCI    Z  C  N  V  -  H  -  -
SBIW    Z  C  N  V  -  -  -  -
SBC     Z  C  N  V  -  H  -  -
SEC     -  C  -  -  -  -  -  - 
SEH     -  -  -  -  -  H  -  -
SEI     -  -  -  -  -  -  -  I
SEN     -  -  N  -  -  -  -  -
SES     -  -  -  -  S  -  -  -
SET     -  -  -  -  -  -  T  -
SEV     -  -  -  V  -  -  -  -
SEZ     Z  -  -  -  -  -  -  - 
SUB     Z  C  N  V  S  H  -  -
SUBI    Z  C  N  V  S  H  -  -
TST     Z  -  N  V  S  -  -  -

Stupid Sreg Tricks

This arduino program will iterate through the flags in the Status Register, turning them on individually:

//SREG demo
#define SREG_IBIT 0b10000000

char s[6], f[8] = { 'C', 'Z', 'N', 'V', 'S', 'H', 'T', 'I' };

void PrintSreg(uint8_t sreg) {
  for (uint8_t i=0; i<8; i++) {
    sprintf(s, " %c: %d", f[i], (sreg & (1 << i) ? 1 : 0));
    Serial.print(s);
  }
  Serial.println();
}

void setup() {
  Serial.begin(9600);
  
  //Carry Flag
  asm (
    "out __SREG__, %0 \n"
    "sec              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //Zero Flag
  asm (
    "out __SREG__, %0 \n"
    "sez              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //Negative Flag
  asm (
    "out __SREG__, %0 \n"
    "sen              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //Overflow Flag
  asm (
    "out __SREG__, %0 \n"
    "sev              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //Sign Flag
  asm (
    "out __SREG__, %0 \n"
    "ses              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //Half Carry Flag
  asm (
    "out __SREG__, %0 \n"
    "seh              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
  //T bit
  asm (
    "out __SREG__, %0 \n"
    "set              \n"
    : : "r" (SREG_IBIT) 
  );
  PrintSreg(SREG);
}

void loop() { }

Also available as a book, with greatly expanded coverage!

BookCover
[click on the image]

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

Leave a comment