I don’t even have the SOIC-8 test clip so I can program it, but between a couple hours last night and an hour tonight, I’ve already written most of the code for the ATtiny13.
One thing I like about the AVR microcontroller is avr-gcc and avr-libc. It makes for really quick development using tools I’m familiar with. I think I’m 80% done with the code (everything but saving the brightness levels in the EEPROM), and I’ve only used about 1/3 of the 1K program flash.
The basic operation is as follows:
Timer 0 is clocked at the internal 9.6 Mhz RC oscillator divided by 256. It is an 8 bit timer, and OC0A (PB0) is toggled in Fast PWM mode, therefore, this is a PWM output at 9600000/(256*256) = 146.5 Hz with a duty-cycle variable in 256 levels. That is fast enough to avoid flicker, but slow enough to PWM the ZXLD1350 in the ideal manner, varying the LED brightness from off to full power according to whatever value we put in the OCR0A register (with no other software overhead).
The QT100 output goes to PB1, configured as INT0, interrupt-on-rising edge. Thus touching the touch sensor triggers an interrupt which steps the OCR0A level through one of 4 different brightness levels (e.g. OFF, LOW, MEDIUM, HIGH). The QT100 has handled ‘debouncing’ the actual touch sensor.
The two tiny pushbuttons are debounced using a software routine, see this article for some examples. They then increment or decrement the current brightness level in steps of 8, allowing configuration of a particular one of the four brightness levels to one of 32 possible levels.
The Timer 0 overflow (146.5 times per second) triggers an interrupt. Think of this like your generic timer interrupt in a simple OS, usable for running periodic tasks which are not run as a result of external inputs. In this code, it causes two things to happen periodically: Sampling of the two pushbuttons (the debouncing routine considers a valid button value to be 8 consecutive samples) and incrementing a timer value which is zeroed each time a button is pressed. When this timer value exceeds a certain threshold (equivalent to 30 seconds of no buttons pushed), the in-RAM brightness levels are compared with those in EEPROM. If they are different, the RAM values are written to EEPROM. In this way, writes to EEPROM are minimized, but once brightness levels have been reconfigured, they are written out to EEPROM.
At startup, the main() function sets up the I/O lines, the Timer/PWM, loads brightness levels out of EEPROM, sets the current PWM value, enables interrupts and enters a while(1) loop.