Week 09 - Mar 14th 2012 - Embedded Programming
Weekly Assignment - Program the hello board in a variety of ways
The first thing to set up was the toolchain to upload .hex files to the hello board. On my mac I used gavrasm to compile assembly files to hex files, and avrdude (via crosspack) to upload the hex files. Alternatively, I also used the Arduino 1.0 IDE to directly program the board according to the instruction here.
Next I was keen to assess the efficiency of assembly language over a higher level language such as Arduino, which is especially important when working with a microcontroller such as the attiny44 with only 4096 bytes of program storage memory. Therefore I wrote very simple programs in both languages and compared the sizes of the resulting hex files.
- Program 1 - switch on the LED, and switch it off when the button is pressed:
- Assembly:
.device attiny44 .def pinsetup = R16 ; where to store initial pin setup (0=input, 1=input) .def testbyte = R17 ; byte to test whether button is pushed ldi pinsetup, 0b11110111 ; prepare PORTA pins (all output except PA3) out DDRA, pinsetup ; set PORTA pin directions loop: in testbyte, PINA ; read PINA register subi testbyte, 0b00001000 ; if PA3 is high (switch not pressed) then this equals zero so Z=1 brne switchoff ; if PA3 is low Z=0 so jump to switchoff sbi PORTA, 7 ; switch on led rjmp loop ; back to beginning of loop switchoff: cbi PORTA, 7 ; switch off led rjmp loop ; back to beginning of loop
- Arduino:
/* Button and LED Turns on an LED attached to pin 7 when pushbutton attached to pin 3 is pressed. Circuit setup: * LED attached from pin 7 to GND * pushbutton attached to pin 3 from GND * 10K resistor attached to pin 3 from +5V modified from http://www.arduino.cc/en/Tutorial/Button */ const int buttonPin = 3; // the number of the pushbutton pin const int ledPin = 7; // the number of the LED pin int buttonState = 0; // variable for reading the pushbutton status void setup() { // pinMode(ledPin, OUTPUT); // define pin 7 as output pinMode(buttonPin, INPUT); // define pin 3 as input } void loop(){ buttonState = digitalRead(buttonPin); // read state of pushbutton if (buttonState == HIGH) { // if button is not pressed pin 7 reads +5V digitalWrite(ledPin, HIGH); // so switch on LED } else { // else button is pressed digitalWrite(ledPin, LOW); // so switch off LED } }
- Hex file sizes Assembly 18 bytes, Arduino 752 bytes
- Program 2 - switch the LED on brightly, and when the button is pressed dim the LED using PMW:
- Assembly:
.device attiny44 .def pinsetup = R16 ; where to store initial pin setup (0=input, 1=input) .def testbyte = R17 ; byte to test whether button is pushed .def temp = R18 ; temp register for setup .def highpmw = R19; .def lowpmw = R20; ldi pinsetup, 0b11110111 ; prepare PORTA pins (all output except PA3) out DDRA, pinsetup ; set PORTA pin directions ldi temp, 0b00100011 out TCCR0A, temp ; set PMW mode 3, OC0B non-inverting ldi temp, 0b00000001 out TCCR0B, temp ; set prescaler /1 ldi temp, 0 out TCNT0, temp ldi temp, 250 out OCR0B, temp ldi highpmw, 250 ldi lowpmw, 5 loop: in testbyte, PINA ; read PINA register subi testbyte, 0b00001000 ; if PA3 is high (switch not pressed) then this equals zero so Z=1 brne switchoff ; if PA3 is low Z=0 so jump to switchoff out OCR0B, highpmw ; bright led rjmp loop ; back to beginning of loop switchoff: out OCR0B, lowpmw ; dim led rjmp loop ; back to beginning of loop
- Arduino:
/* Button and LED Dims an LED when a button is pressed Circuit setup: * LED attached from pin 7 to GND * pushbutton attached to pin 3 from GND * 10K resistor attached to pin 3 from +5V modified from http://www.arduino.cc/en/Tutorial/Button */ const int buttonPin = 3; // the number of the pushbutton pin const int ledPin = 7; // the number of the LED pin int buttonState = 0; // variable for reading the pushbutton status void setup() { // pinMode(ledPin, OUTPUT); // define pin 7 as output pinMode(buttonPin, INPUT); // define pin 3 as input } void loop(){ buttonState = digitalRead(buttonPin); // read state of pushbutton if (buttonState == HIGH) { // if button is not pressed so pin 7 reads +5V analogWrite(ledPin, 250); // make LED almost full brightness } else { // else button is pressed analogWrite(ledPin, 5); // dim LED } }
- Hex file sizes Assembly 38 bytes, Arduino 884 bytes
So while in both cases the programs are doing the same things in the same ways, the hex file produced by the Arduino IDE is massively inflated.>
The next thing I wanted to do was to modify Neil's original hello.ftdi.44.echo.asm program to parse the key that had been pressed and, if it was a number key, set the LED brightness according (0 low, 9 high) using PMW. The modified code is shown below: