Step 2Reading and Writing Registers
Manipulating AVR registers while running
To get a list of all known registers on your Arduino, type:
print registersand you'll get a printout looking like this...
I know about the following registers: TIFR0 PORTC TIFR1 PORTD TIFR2 DDRD PCIFR DDRB EIFR DDRC EIMSK PINB EECR PINC EEDR PIND SREG EEARL GPIOR0 EEARH GPIOR1 GTCCR GPIOR2 TCCR0A TCCR0B TCNT0 OCR0A OCR0B SPCR SPDR ACSR SMCR MCUSR MCUCR SPMCSR WDTCSR CLKPR PRR OSCCAL PCICR EICRA PCMSK0 PCMSK1 TIMSK0 TIMSK1 TIMSK2 ADCL ADCH ADCSRA ADCSRB ADMUX DIDR0 DIDR1 TCCR1A TCCR1B TCCR1C TCNT1L TCNT1H ICR1L ICR1H OCR1AL OCR1AH OCR1BL OCR1BH TCCR2A TCCR2B TCNT2 OCR2A OCR2B ASSR TWBR TWSR TWAR TWDR TWCR TWAMR UCSR0A UCSR0B UCSR0C UBRR0L UBRR0H UDR0 PORTB root@ATmega328p>To see how the individual bits are set in any register, use the cat or echo command:
cat %GPIOR0Here I'm asking the command interpreter to display, or echo, the contents of the General Purpose I/O Register #0. Note the percent sign (%) in front of the register name. You need this to indicate to the shell that this is a reserved keyword identifying a register. The typical output from an echo command looks like this:
GPIOR0(0x0) set to [00000000]The output shows the name of the register, the hexadecimal value found in the register and the binary representation of the register (showing each bit as a 1 or 0). To set a particular bit in any register, use the "index of" operator []. For example, let's say I want the 3rd bit to a 1.
%GPIOR0[3] = 1and the shell will give you a response indicating it's action and the result:
GPIOR0(0x0) set to [00000000] --> (0x8) set to [00001000]Dont' forget the percent sign to tell the shell you're working with a register. Also note that by setting the 3rd bit, that's 4 bits in because our AVR's use a zero-based index. In other words, counting to the 3rd bit you count 0, 1, 2, 3, which is the 4th place, but the 3rd bit. You can clear a bit in the same way by setting a bit to zero.
By setting bits like this you can change the functioning of your AVR on the fly. For instance, by changing the CTC timer match value found in OCR1A. It also lets you peek into particular settings that you would have to programmatically check in your code, such as the UBBR value for your baud rate.
Working with DDRn, PORTn, and PINn
The I/O pins are also assigned to registers and can be set in exactly the same way, but a special syntax has been created to work with these types of registers.
In code, there is a normal process for, say, turning on an LED or other device that requires a digital high or low. It requires setting the Data Direction Register to indicate the pin is for output, and then writing a 1 or 0 to the particular bit in the correct port. Assuming we have an LED connected to digital pin 13 (PB5) and we want to turn it on, here's how to do that while your AVR is running:
set pin pb5 outputwrite pin pb5 highThe output, besides being able to see your LED come on, would look like this:
root@ATmega328p> set pin pb5 outputSet pb5 for outputroot@ATmega328p> write pin pb5 highWrote logic high to pin pb5The "root@ATmega328p>" is the shell's prompt that indicates it is ready to accept commands from you. To turn the LED off, you would simply write a low to the pin. If you want to read the digital input from a pin, use the read command. Using our above example:
root@ATmega328p> read pin pb5Pin: pb5 is HIGHAlternatively, just echo the pin register that controls that pin port. For example, if we have dip switches connected to digital pin 7 and 8 (PD7 and PD8), you could send the command:
echo %PINDand the shell would then display the contents of that register, showing you all of the input/output states of connected devices and whether the state of the switch was on or off.
| « Previous Step | Download PDFView All Steps | Next Step » |
![]() |
Add Comment
|











































