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.