The python program I linked earlier is actually closer to immediately useful than I thought. Here's a nice table for you. (naturally, you can edit it down to only the registers you're interested in. And for that matter, it wouldn't be hard to set up a partial table without the python code (which is mainly useful for extracting ALL the register names.)
#include <avr/io.h>
#include <stdio.h>
struct { char name[7];
void * address;
} atmega328_regs[] = {
{"UDR0", (void *) &UDR0 },
{"UCSR0A", (void *) &UCSR0A },
{"UCSR0B", (void *) &UCSR0B },
{"UCSR0C", (void *) &UCSR0C },
{"UBRR0", (void *) &UBRR0 },
{"TWAMR", (void *) &TWAMR },
{"TWBR", (void *) &TWBR },
{"TWCR", (void *) &TWCR },
{"TWSR", (void *) &TWSR },
{"TWDR", (void *) &TWDR },
{"TWAR", (void *) &TWAR },
{"TIMSK1", (void *) &TIMSK1 },
{"TIFR1", (void *) &TIFR1 },
{"TCCR1A", (void *) &TCCR1A },
{"TCCR1B", (void *) &TCCR1B },
{"TCCR1C", (void *) &TCCR1C },
{"TCNT1", (void *) &TCNT1 },
{"OCR1A", (void *) &OCR1A },
{"OCR1B", (void *) &OCR1B },
{"ICR1", (void *) &ICR1 },
{"GTCCR", (void *) >CCR },
{"TIMSK2", (void *) &TIMSK2 },
{"TIFR2", (void *) &TIFR2 },
{"TCCR2A", (void *) &TCCR2A },
{"TCCR2B", (void *) &TCCR2B },
{"TCNT2", (void *) &TCNT2 },
{"OCR2B", (void *) &OCR2B },
{"OCR2A", (void *) &OCR2A },
{"ASSR", (void *) &ASSR },
{"GTCCR", (void *) >CCR },
{"ADMUX", (void *) &ADMUX },
{"ADC", (void *) &ADC },
{"ADCSRA", (void *) &ADCSRA },
{"ADCSRB", (void *) &ADCSRB },
{"DIDR0", (void *) &DIDR0 },
{"ACSR", (void *) &ACSR },
{"DIDR1", (void *) &DIDR1 },
{"PORTB", (void *) &PORTB },
{"DDRB", (void *) &DDRB },
{"PINB", (void *) &PINB },
{"PORTC", (void *) &PORTC },
{"DDRC", (void *) &DDRC },
{"PINC", (void *) &PINC },
{"PORTD", (void *) &PORTD },
{"DDRD", (void *) &DDRD },
{"PIND", (void *) &PIND },
{"OCR0B", (void *) &OCR0B },
{"OCR0A", (void *) &OCR0A },
{"TCNT0", (void *) &TCNT0 },
{"TCCR0B", (void *) &TCCR0B },
{"TCCR0A", (void *) &TCCR0A },
{"TIMSK0", (void *) &TIMSK0 },
{"TIFR0", (void *) &TIFR0 },
{"GTCCR", (void *) >CCR },
{"EICRA", (void *) &EICRA },
{"EIMSK", (void *) &EIMSK },
{"EIFR", (void *) &EIFR },
{"PCICR", (void *) &PCICR },
{"PCMSK2", (void *) &PCMSK2 },
{"PCMSK1", (void *) &PCMSK1 },
{"PCMSK0", (void *) &PCMSK0 },
{"PCIFR", (void *) &PCIFR },
{"SPDR", (void *) &SPDR },
{"SPSR", (void *) &SPSR },
{"SPCR", (void *) &SPCR },
{"WDTCSR", (void *) &WDTCSR },
{"PRR", (void *) &PRR },
{"OSCCAL", (void *) &OSCCAL },
{"CLKPR", (void *) &CLKPR },
{"SREG", (void *) &SREG },
{"SP", (void *) &SP },
{"SPMCSR", (void *) &SPMCSR },
{"MCUCR", (void *) &MCUCR },
{"MCUSR", (void *) &MCUSR },
{"SMCR", (void *) &SMCR },
{"GPIOR2", (void *) &GPIOR2 },
{"GPIOR1", (void *) &GPIOR1 },
{"GPIOR0", (void *) &GPIOR0 },
{"EEAR", (void *) &EEAR },
{"EEDR", (void *) &EEDR },
{"EECR", (void *) &EECR },
};
#define NREGS (sizeof(atmega328_regs)/sizeof(atmega328_regs[0]))
void setup() {
Serial.begin(115200);
for (int i=0; i < NREGS; i++) {
Serial.print(atmega328_regs[i].name);
Serial.print(" is at 0x");
Serial.println((int)atmega328_regs[i].address, HEX);
}
}
void loop() {}
Looking up strings in the table, possibly moving it into program memory, and possibly adjusting the address value to a proper pointer, is left as an exercise for the student...