Embedded Programming

Assignment

  • Read a microcontroller data sheet.
  • Program your board to do something, with as many different programming languages and programming environments as possible.
  • Optionally, experiment with other architectures

What should be done

  • Documented what you learned from reading a microcontroller datasheet.
  • What questions do you have? What would you like to learn more about?
  • Programmed your board
  • Described the programming process/es you used
  • Included your code

I programmed boards using Arduino C before but came across a problem about the program filesize before on Attiny MCUs especially when adding libraries such as "SoftwareSerial".

So I decided to try and program in C but found it difficult as I came from background in higher level languages such as PHP and Python.

I read the "Basics" part of "Make: AVR Programming" book and it helped me a lot as both introduction to Micro-controllers and in C.

Digikey's page for Attiny44A had two datasheets "Complete" and "Summary".

The "Summary" contained the very essential information needed as a quick reference.

As I wanted to know about the pins, input and output, I'm focusing on the following sections:

1. Pin Configurations
10. I/O Ports

The basic functionality that the board designed should do is to turn off the LED when the push button is pressed and on when it is released.

The Button is connected to "PB2" pin and is pulled-up by design and it will be pulled-down when pressed so will read "0" and the LED is connected to "PA7" and to "GND" so should be set to "1" to be turned on.

In the "Pin Configurations" section in the datasheet:

Which means that as the "PA7" is pulled-low, when it is activated current will flow from it through the LED to the ground. And that the input pin "PB2" will be hight by default and should be grounded when pressed.

I then opened the "hello.RGB.45.c" from "Output Devices" and "hello.button.45.c" from "Input Devices" to learn more on how to control LEDs and read from push-buttons

Started from the "hello.button.45.c" where I removed all the bits of code related to serial communications and added the pin definitions for the led and the loop logic.

I created a file names "button.led.44.c" and added the following code.

#include <avr/io.h>
#include <util/delay.h>
 
#define output(directions,pin) (directions |= pin) // set port direction for output
#define input(directions,pin) (directions &= (~pin)) // set port direction for input
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
 
#define input_port PORTB
#define input_direction DDRB
#define input_pin (1 << PB2)
#define input_pins PINB
 
#define led_port PORTA
#define led_direction DDRA
#define led (1 << PA7)
 
int main(void) {
  //
  // main
  //
  // set clock divider to /1
  //
  CLKPR = (1 << CLKPCE);
  CLKPR = (0 <<CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
  //
  // initialize pins
  //
  set(input_port, input_pin); // turn on pull-up
  input(input_direction, input_pin);
  //
  // main loop
  //
  while (1) {
     //
     // wait for button down
     //
     while (0 == pin_test(input_pins,input_pin))
        ;
     set(led_port,led);
     //
     // wait for button up
     //
     while (0 != pin_test(input_pins,input_pin))
        ;
      clear(led_port,led);
     }
  }

And then created a make file and named it "Makefile" in the same directory

PROJECT=button.led.44
SOURCES=$(PROJECT).c
MMCU=attiny44
F_CPU = 20000000

CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)

$(PROJECT).hex: $(PROJECT).out
	avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
	avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out
 
$(PROJECT).out: $(SOURCES)
	avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
 
program-bsd: $(PROJECT).hex
	avrdude -p t44 -c bsd -U flash:w:$(PROJECT).c.hex

program-dasa: $(PROJECT).hex
	avrdude -p t44 -P /dev/ttyUSB0 -c dasa -U flash:w:$(PROJECT).c.hex

program-avrisp2: $(PROJECT).hex
	avrdude -p t44 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex

program-avrisp2-fuses: $(PROJECT).hex
	avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x5E:m

program-usbtiny: $(PROJECT).hex
	avrdude -p t44 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex

program-usbtiny-fuses: $(PROJECT).hex
	avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m

program-dragon: $(PROJECT).hex
	avrdude -p t44 -P usb -c dragon_isp -U flash:w:$(PROJECT).c.hex

program-ice: $(PROJECT).hex
	avrdude -p t44 -P usb -c atmelice_isp -U flash:w:$(PROJECT).c.hex

I switched to the directory, and ran the following command to set attiny44 fuses using the FabISP:

$ make program-usbtiny-fuses

Then to load the code:

$ make program-usbtiny

And then powered the board from FTDI cable power.

I found that the illumination of the LED is very low so I measured the voltage of the output pin and it was about 1.7 volts which should be 5 volts. So in a trial to exclude hardware errors, I replaced the LED with a red one but the problem remained.

I then replaced the current-limiting resistor with a 100 ohm but the problem remained.

I then uploaded a basic "Blink" sketch from Arduino IDE and it ran correctly so I figured that the problem was with the code so I returned to my code and found out that I didn't define the led pin as output; So I added this line to the pin initialization block.

output(led_direction, led);

And uploaded the code and it was a success.

Files