Embedded programming
I found this tutorial exteremely helpful in understanding the basics of C-based embedded programming.
The ATtiny44 microcontroller has port A with 8 pins (PA0-PA7) configurable as outputs or inputs. You can control those pins by setting three pre-defined (8-bit long; each bit corresponds to a particular pin) variables (see pages 66-67 of the data sheet).
- DDRA - Data Direction Register A - defines whether a given pin is an input or an output, e.g. DDRA witha value of 00000010 will treat all port A pins as inputs apart from pin 2 which would be an output.
- PORTA - Port A Data Register - this is part of the memory of the microcotroler that can be accessed through a given pin when that pin is defined as an output (through DDRA). In the above example the internal process can change the value of PORTA2 which could then be accessed on the PA2. On the other hand if the pin is defined as an input and PORTAx for that pin is set to 1 - it just activates a pull up resistor.
- PINA - Port A Input Pins - when a pin is defined as an input, the microcontroller will be able to read a physical status of the pin itself.
Now, the way to set these different variables in C we can't just write
DDRA=00000010
(or DDRA=2
for that matter) because C by default assumes that the numbers are provided in decimal form. To provide a variable in binary (or hex) - prefix it with 0b
(0x
):
DDRA=0b00000010
(DDRA=0x00000010
).
To change one bit in an 8-bit register REG (it could be DDRA, PORTA or PINA) that already has other values stored on other pins/bits you can use an OR bitwise operation. Say you want to change bit 5 to high value:
REG=REG|0b00100000
or as a shorthand you can write:
REG|=0b00100000
In practice the C libraries for a specific device actually have names of specific pins. A human readible way of setting pin 5 of PORTA to 1 would be:
PORTA|=(1<<PA5)
In here PA5 is defined as having a value 0b00100000. << is a left-shift operator and it moves the LHS by the number of points on RHS. In this case 00000001 was simply shifted by 6 positions to 00100000. Or we can simply set it as:
PORTA|=PA5
To clear a register we use a different set of operators:
PORTA&=(~PA5)
The code activates an LED connected to PA2 pin when the button (on pin PA7) is depressed. To upload it I first needed to make sure that the ISP cable was in the correct orientation between FabISP and the PCB:

Then I used a modified make file and used the following command to set the fuses:
make -f embprog.c.make program-usbtiny-fuses
which produced the following output:

and then I uploaded the short c programme:
make -f embprog.c.make program-usbtiny
which resulted in:

The entire process was succesful:
