Making a battery last a long time in a microcontroller circuit

Just a random list, if you post your schematic it would probably be easier:

1.8V lithium Coin cells are very easy to find, but more likely your serial interface needs 3.3v? Unless your receiving end will deal with 1.8V.

Leakage current does generally go up as your voltage increases, so lower is better usually. Also consider the brown-out point for the system vs the battery characteristics. The 'death' characteristics of the battery will be determines by the battery chemistry you use. For instance if your uC browns out at 1.7V you may actually want to use a higher voltage battery as with some batteries the output voltage will lower slowly as the battery dies. You'd get more life out of a 3.3V battery as when it begins to die its output will slowly drop and you can operate all the way down to 1.8V. If you use a 1.8V battery your going to shut down fairly quickly as the battery dies. This all assumes your serial interface or other components can deal with a wide voltage range (I know the AVR can).

LED's use a lot of power, unless you use a very low power LED and are controlling its current draw it's probably drawing a lot more current than the AVR is. If its just there for debug, don't populate it for production or only have it blink once in a while or something to minimize its on time, and definitely control its current draw.

If you can, pick the polarity / rest state of your serial interface to draw as little power as possible, it's rest state should not be drawing power. If pull ups are required use the largest resistor possible to maintain signal integrity but minimize current usage. If power is a huge concern use a signally scheme that favor's bits that don't draw power. For instance if you have pull ups, using a protocol that results in lots of 1's in the signal will leave the serial interface in a state that isn't drawing as much power most of the time. Such optimizations are only worthwhile if your making heavy use of the serial bus. If its very lightly used just make sure its rest state isn't drawing power.

Generally speaking you can assume all instructions (reading GPIO, etc) require the same amount of power. Its not really true but the power difference is minimal.

Power usage is much more dependent on the number/type of peripherals you have powered on, and the amount of time the micro spends active vs sleeping. So the ADC uses more power, EEPROM writes use a fair amount of power. Specifically something like the EEPROM writes are usually done in fairly large 'chunks' so you should accumulate as much information as you can before doing the write to the EEPROM (if your even using it of course). For the ADC that micro supports doing the ADC read during 2 of its sleep states, as ADC conversion takes a relatively long time this is a good time to sleep.

You should probably just read the sections on power management, sleep states and minimizing power using in the microcontroller's data sheet: linky page 35 on. Keep the AVR in the deepest sleep state possible as long as possible. The only exception to this is that you have to consider the start up and shutdown time. Its not worth it to sleep for 10 cycles if waking back up takes 25, etc.

Do resistors use up battery life? Do capacitors? Do diodes?

They all do to some extent. Resistors dissipate the most in most applications:

P = V*I

P = V^2 / R or P = I^2 * R (where V is the voltage drop across the resistor)

Diode's have a (relatively) fixed voltage drop, so power dissipation is almost exclusively tied to current passing through the diode. For instance a diode with a 0.7V forward voltage drop, P = 0.7 * I if current is moving forward through the diode. This is a simplification of course and you should check out the operating mode based on the diode's I-V characteristics.

Capacitors theoretically shouldn't dissipate any power, but in reality they have a finite series resistance and non-zero leakage current which means they do dissipate some power, generally not something you should worry about with such low voltages though. That being said choosing capacitors with minimal leakage current and ESR is a power win.

As far as using them to smooth out battery draw, this doesn't really help for power usage, its more for filtering. Also battery chemistry comes into play here, some chemistries will be happier with a constant draw, some deal better with spiky current draws.

Mark gave a most excellent answer and hit on many of the points I was going to make. There are a few that I'd like to contribute as well.

Use an oscilloscope with a low-ohm resistor in series with the return to battery common to make current measurements. Current draw with a microcontroller is not straightforward and as a general rule, meters are FAR too slow to give you a good idea of what's going on. What "low-ohm" means depends on the expected current draw. a 1 ohm resistor will develop 100mV for every 100mA drawn, and that is probably too much for you. I'd try a 10 ohm 1% or 0.5% resistor; you'll see 100mV for every 10mA of current draw. 18 ohms would give you 100mV for every 5.5mA. If you're REALLY going for low power you might be able to get away with 1k; I=V/R: you'll see 100mV for every 100uA of current drawn. Careful though; if you draw enough current you'll end up dropping too much across the shunt and your measurements will be off, not to mention the circuit probably won't work. :-)

With the 'scope connected, try a few different operating frequencies for the microcontroller. You may be surprised to learn that you consume less power with a higher clock speed because you spend much less time "awake."

Eliminate pull-ups/downs as much as possible. You shouldn't have any on any output, since you can drive them to an idle state in most cases. Inputs should be tied to what makes sense, using as high a value as possible, as Mark said.

Make sure that your microcontroller has as much shut off as possible. Turn unused pins into outputs and drive them to a state (high or low, doesn't matter). Don't leave LEDs on. If you can power down other components or stop their clocks, do it. SPI Flash memories, for example, often have a 'power down' command that will take the already low power draw and drive it even lower.

Others have touched on the voltage aspect, and I'd like to comment on it as well. You will likely end up with MUCH better battery use if you use a high-efficiency buck/boost regulator between the battery and your circuit. The regulator will be in buck mode (voltage reduction) when the battery level is higher than the 1.8V you need, and switch to boost mode (voltage increasing) when the battery level drops below 1.8V. This will allow you to run the circuit until the battery is well and truly dead, which is well worth the few percent efficiency loss you'll get when using them. Make sure to select the regulator based on its efficiency over the entire range you want to use, and size the regulator appropriately; a regulator that can deliver 1A at 98% efficiency is probably at 60% efficiency delivering 50mA. Read the datasheets carefully.

With your circuit, I'd recommend using a multimeter on the microamps range to measure current consumption. Then, given the battery characteristics you can calculate the longevity. It's not necessarily amp-hours / current, as the battery will have different discharge characteristics for different loads. But, it can be useful as an approximation.

At 1 MHz I think you will be sucking a bit of power - at least 100µA, if PIC micros are anything to compare with. But this is going to be overwhelmed by the 5mA to 20mA going through your LED, so you should get rid of that first.