Common AVR Gotchas

I’m going to list a few gotchas I encountered this weekend while fiddling around with my AVR projects.

The first:

Interrupts don’t happen unless they’re… enabled. I spent too long trying to figure out why the timer overflow in my previous test worked, but the timer compare match in my current test didn’t. The reason it didn’t work? Somewhere in there I had deleted sei from my init code. That’s right, interrupts are so important that they have their own commands: cli and sei.

The second: The commands cbr and sbr for registers are NOT the same as their I/O counterparts cbi and sbi. Let’s take a peek at the instruction set manual.

CBI – Clear Bit in I/O Register
Description:
Clears a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers - addresses 0-31.
Operation:
I/O(A,b) ← 0

This command is straightforward, it takes a bit number as the second operand and sets that bit to 0. Now let’s see cbr.

CBR – Clear Bits in Register
Description:
Clears the specified bits in register Rd. Performs the logical AND between the contents of register Rd and the complement of the constant mask K. The result will be placed in register Rd.
Operation:
Rd ← Rd • ($FF - K)

I hope you read the instruction descriptions before blindly using this. In this command the complement of the second operand is ANDed with the register. So that means, while you can get away with cbi PORTA, 1 to clear the second bit in PORTA, you can’t do cbr R16, 1 to clear the second bit in R16. Instead, you’ll clear the first bit (0b11111111-0b01=0b11111110).

SBI – Set Bit in I/O Register
Description:
Sets a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers - addresses 0-31.
Operation:
I/O(A,b) ← 1

This one is straightforward just like cbi.

SBR – Set Bits in Register
Description:
Sets specified bits in register Rd. Performs the logical ORI between the contents of register Rd and a constant mask K and places the result in the destination register Rd.
Operation:
Rd ← Rd v K

Just like cbi and sbi, sbr is the counterpart to cbr and works similarly. Instead of the second operand being a number from 0-7, it is a bitmask as in cbr.

Undoubtedly, I’ll have more gotchas when I get back to work on my projects next weekend.