(ATtiny internal) registers
What is a register?
The ATtiny85 is an 8 bit microcontroller, meaning it is made up of 8-bit binary registers.
One register can be represented as such:
place: 7 6 5 4 3 2 1 0
value: |0|0|0|0|0|0|0|0|
binary: 0b00000000
hex: 0x00
Bitwise arithmetic: the basics
To do anything with registers, we need to know a bit about bitwise arithmetic.
This is a good place to start. Here are the most useful things to know how to do.
set the fourth bit from the right HIGH(0, 1, 2, 3: count three places over from the right) we do this:
REGISTER |= (1>>3);
means... (f for false, t for true
REGISTER = 0b01010101
||||||||
0b00001000
ftftttft
0b01011101
To set the fourth bit from the right LOW we do this:
REGISTER &= ~(1>>3);
*
~0b00001000=
0b11110111
&&&&&&&&
REGISTER = 0b01011101
ftftftft
0b01010101
To clear the whole register (probably a dumb idea):
REGISTER = 0;
ASIDE: Quick hexadecimal primer:
Decimal goes up to 10:
decimal: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9... and 10 because the 1's place is maxed out.
Hexadecimal goes up to 16:
when we run out of normal decimal numbers, we start counting up with letters.
decimal: 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15... 16.
hex: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f... 10.
Now that we know a little bit how registers work, let's look at some actual registers.
Registers for basic digital I/O
For turning off and on voltages for pins and sensing whether or not switches are pressed, we only need to pay attention to these registers.
- PORTB (Port B Data Register) sets the state of a pin to either low (approximately ground) or high (VCC).
- DDRB (Port B Data Direction Register) sets the state of a pin to either input or output. Pins are defaulted to inputs.
- PINB (Port B Input Pins Address) this register returns the current state of pins designated as inputs.
Later, when we start looking at analog inputs and the ADC (Analog to Digital Converter), these registers will become important:
- ADMUX (ADC Multiplexer Selection Register) determines which pin will be read by the ADC
- ADCSRA (ADC Sontrol and Status Register)controls the starting and stopping of the ADC
- ADCL and ADCH(The data register) where the reading from the last ADC was stored. Can be changed from 10-bit precision to 8-bit precision by toggling ADLAR.
PORTB
; PORTB - Data Register, Port B
.equ PORTB0 = 0 ;
.equ PB0 = 0 ; For compatibility
.equ PORTB1 = 1 ;
.equ PB1 = 1 ; For compatibility
.equ PORTB2 = 2 ;
.equ PB2 = 2 ; For compatibility
.equ PORTB3 = 3 ;
.equ PB3 = 3 ; For compatibility
.equ PORTB4 = 4 ;
.equ PB4 = 4 ; For compatibility
.equ PORTB5 = 5 ;
.equ PB5 = 5 ; For compatibility
DDRB
; DDRB - Data Direction Register, Port B
.equ DDB0 = 0 ;
.equ DDB1 = 1 ;
.equ DDB2 = 2 ;
.equ DDB3 = 3 ;
.equ DDB4 = 4 ;
.equ DDB5 = 5 ;
PINB
; PINB - Input Pins, Port B
.equ PINB0 = 0 ;
.equ PINB1 = 1 ;
.equ PINB2 = 2 ;
.equ PINB3 = 3 ;
.equ PINB4 = 4 ;
.equ PINB5 = 5 ;
And later, when we start working with the ADC, these become important:
Registers for the ADC
ADMUX:
; ADMUX - The ADC multiplexer Selection Register
.equ MUX0 = 0 ; Analog Channel and Gain Selection Bits
.equ MUX1 = 1 ; Analog Channel and Gain Selection Bits
.equ MUX2 = 2 ; Analog Channel and Gain Selection Bits
.equ MUX3 = 3 ; Analog Channel and Gain Selection Bits
.equ REFS2 = 4 ; Reference Selection Bit 2
.equ ADLAR = 5 ; Left Adjust Result
.equ REFS0 = 6 ; Reference Selection Bit 0
.equ REFS1 = 7 ; Reference Selection Bit 1
- REFS[2:0] : Sets the reference voltage for ADCs
- MUX[3:0] : decides which pin is going to be read by the ADC. For our purposes, we only care about the bottom two bits (00**). The top two bits (**00) deal with differential input which isn't useful to me (yet).
- if nothing is set to MUX[3:0] (0000), but ADC is enabled, it will try to use the reset pin (PB5/ADC0) as an input. We don't want that. We will pretend ADC0 doesn't exist.
ADCSRA:
; ADCSRA - The ADC Control and Status register
.equ ADPS0 = 0 ; ADC Prescaler Select Bits
.equ ADPS1 = 1 ; ADC Prescaler Select Bits
.equ ADPS2 = 2 ; ADC Prescaler Select Bits
.equ ADIE = 3 ; ADC Interrupt Enable
.equ ADIF = 4 ; ADC Interrupt Flag
.equ ADATE = 5 ; ADC Auto Trigger Enable
.equ ADSC = 6 ; ADC Start Conversion
.equ ADEN = 7 ; ADC Enable
- ADSC starts an ADC. ADEN must be enabled first before starting an ADC.
- The rest of the bits are not particularly useful yet, Alex may have suggested changing ADPS[2:0] to make the ADC's more accurate.
ADCH and ADCL:
; ADCH - ADC Data Register High Byte
.equ ADCH0 = 0 ; ADC Data Register High Byte Bit 0
.equ ADCH1 = 1 ; ADC Data Register High Byte Bit 1
.equ ADCH2 = 2 ; ADC Data Register High Byte Bit 2
.equ ADCH3 = 3 ; ADC Data Register High Byte Bit 3
.equ ADCH4 = 4 ; ADC Data Register High Byte Bit 4
.equ ADCH5 = 5 ; ADC Data Register High Byte Bit 5
.equ ADCH6 = 6 ; ADC Data Register High Byte Bit 6
.equ ADCH7 = 7 ; ADC Data Register High Byte Bit 7
; ADCL - ADC Data Register Low Byte
.equ ADCL0 = 0 ; ADC Data Register Low Byte Bit 0
.equ ADCL1 = 1 ; ADC Data Register Low Byte Bit 1
.equ ADCL2 = 2 ; ADC Data Register Low Byte Bit 2
.equ ADCL3 = 3 ; ADC Data Register Low Byte Bit 3
.equ ADCL4 = 4 ; ADC Data Register Low Byte Bit 4
.equ ADCL5 = 5 ; ADC Data Register Low Byte Bit 5
.equ ADCL6 = 6 ; ADC Data Register Low Byte Bit 6
.equ ADCL7 = 7 ; ADC Data Register Low Byte Bit 7