About Week 7

My Embedded Programming Exercise...

This week assignment was about Embedded Programming, in particular starting from my previous hello-world board:

  • 1. Read the microcontroller data sheet.
  • 2. Program it

In few words the essential capability to program a microcontroller is to know its ports & pins, its input/output (I/O) system and related functions. So by means of ATTINY44 datasheet I read its pins' codes, and related alternate functions:

I found this useful image that provides a schematic summary of ATTINY44 pin

I went back on my hello board design and the Led, the button and related resistors were connected to ATTINY44, to pin 6 and 10 respectively,that is ports PA3 and PA7 respectively.

After this study, I started to check if my hello board was OK. To do this for the first try, first of all I studied from Fab Academy 2015 Tutorials the structure of Makefile:

PROJECT=hello.ftdi.44.echo
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)

Where the first four lines are configuration declaration of the Makefile:

  1. Name of the file to compile
  2. Extension of the file to compile
  3. Microcontroller to program
  4. Frequency of the board to program

After this I downloaded and used a led blink C program from Massimo Menichinelli's by using my FabISP:

The two board were recognized by my PC so I used Win-GCC for the following commands:

D:\FabAcademy_Files\Embedded_Programming\steadyled>make
avr-objcopy -O ihex steadyled.out steadyled.c.hex;\
        avr-size --mcu=attiny44 --format=avr steadyled.out
AVR Memory Usage
----------------
Device: attiny44

Program:     172 bytes (4.2% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)



D:\FabAcademy_Files\Embedded_Programming\steadyled>make program-usbtiny-fuses
avr-objcopy -O ihex steadyled.out steadyled.c.hex;\
        avr-size --mcu=attiny44 --format=avr steadyled.out
AVR Memory Usage
----------------
Device: attiny44

Program:     172 bytes (4.2% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)


avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9207
avrdude: reading input file "0x5E"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0x5E:
avrdude: load data lfuse data from input file 0x5E:
avrdude: input file 0x5E contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.


D:\FabAcademy_Files\Embedded_Programming\steadyled>make program-usbtiny
avr-objcopy -O ihex steadyled.out steadyled.c.hex;\
        avr-size --mcu=attiny44 --format=avr steadyled.out
AVR Memory Usage
----------------
Device: attiny44

Program:     172 bytes (4.2% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)


avrdude -p t44 -P usb -c usbtiny -U flash:w:steadyled.c.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9207
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "steadyled.c.hex"
avrdude: input file steadyled.c.hex auto detected as Intel Hex
avrdude: writing flash (172 bytes):

Writing | ################################################## | 100% 0.23s



avrdude: 172 bytes of flash written
avrdude: verifying flash memory against steadyled.c.hex:
avrdude: load data flash data from input file steadyled.c.hex:
avrdude: input file steadyled.c.hex auto detected as Intel Hex
avrdude: input file steadyled.c.hex contains 172 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.16s



avrdude: verifying ...
avrdude: 172 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.


D:\FabAcademy_Files\Embedded_Programming\steadyled>					
 

All went well and my hello board started to blink.

Then I removed FabISP-hello board connection and I checked the program loaded that is a led switch on-off once button pressed:OK!

Once verified my board I started to create a new program to load. My first idea was to create a Morse Code translator that translates a string into Morse code by means of led blinking. To do this I started from the previous led blink, removed the unused functions and inserted two functions for the elaboration of a String by calling for each character morse_char decode function. My first try was to put in memory a string ('FAB ACADEMY'-> ..-. .- -... / .- -.-. .- -.. . -- -.--) and in while(1){} block in the main the instruction to start the blink Morse Code once the button is pressed:

#include 
#include 
#include 
#include 

void delay_ms(uint16_t ms);
void init_io();
int button_is_pressed();


void morse_character(char c);
void morse_P(const char *s);
const unsigned char morse_code_table[];

#define F_CPU 20000000UL        /* 20MHz crystal oscillator */

#define BUTTON_PORT PORTA       /* PORTx - register for button output */
#define BUTTON_PIN PINA         /* PINx - register for button input */
#define BUTTON_BIT PA3          /* bit for button input/output */

#define LED_PORT PORTA          /* PORTx - register for LED output */
#define LED_BIT PA7             /* bit for button input/output */
#define LED_DDR DDRA            /* LED data direction register */

#define DEBOUNCE_TIME 25        /* time to wait while "de-bouncing" button */
#define LOCK_INPUT_TIME 250     /* time to wait after a button press */

#define DIT 25		            /* unit time for morse code */

int 
main (void)
{
	init_io();

	while (1)                       
	{
		if (button_is_pressed())
		{
			morse_P(PSTR("FAB ACADEMY"));
						   
		}
	}
}

void delay_ms(uint16_t ms) {
	while ( ms )
		{
			_delay_ms(1);
			ms--;
		}
}

void 
init_io() 
{
        /* set LED pin as digital output */
        LED_DDR = _BV (LED_BIT); 

        /* led is OFF initially (set pin high) */         
        LED_PORT |= _BV(LED_BIT);

        /* turn on internal pull-up resistor for the switch */
        BUTTON_PORT |= _BV(BUTTON_BIT);
}

int 
button_is_pressed()
{
        /* the button is pressed when BUTTON_BIT is clear */
        if (bit_is_clear(BUTTON_PIN, BUTTON_BIT))
        {
			delay_ms(DEBOUNCE_TIME);
			if (bit_is_clear(BUTTON_PIN, BUTTON_BIT)) return 1;
        }

        return 0;
}



// blink a single character in Morse code
void morse_character(char c)
{
	unsigned char code, count;

	if (c == ' ') {
		
		delay_ms(DIT * 7);
		return;
	}
	
		
	
	
	if(c >= 'A' && c <= 'Z') {
	
		code = pgm_read_byte(morse_code_table + (c - 'A'));
	
	}
	
	else {
		
		return;
	}
	
	for (count = code & 0x07; count > 0; count--) {
		LED_PORT=0b00000001;
		if (code & 0x80) {
			
			delay_ms(DIT * 3);
		} else {
			
			delay_ms(DIT);
		}
		LED_PORT=0b10000000;
		delay_ms(DIT);
		code = code << 1;
	}
	
	delay_ms(DIT * 2);
}

// blink an entire message in Morse code
// the string must be in flash memory (using PSTR macro)
void morse_P(const char *s)
{
	char c;
	
	while (1) {
		c = pgm_read_byte(s++);
		if (!c) break;
		morse_character(c);
	}
	
}

const unsigned char PROGMEM morse_code_table[] = {
	0x40 + 2,	// A: .-
	0x80 + 4,	// B: -...
	0xA0 + 4,	// C: -.-.
	0x80 + 3,	// D: -..
	0x00 + 1,	// E: .
	0x20 + 4,	// F: ..-.
	0xC0 + 3,	// G: --.
	0x00 + 4,	// H: ....
	0x00 + 2,	// I: ..
	0x70 + 4,	// J: .---
	0xA0 + 3,	// K: -.-
	0x40 + 4,	// L: .-..
	0xC0 + 2,	// M: --
	0x80 + 2,	// N: -.
	0xE0 + 3,	// O: ---
	0x60 + 4,	// P: .--.
	0xD0 + 4,	// Q: --.-
	0x40 + 3,	// R: .-.
	0x00 + 3,	// S: ...
	0x80 + 1,	// T: -
	0x20 + 3,	// U: ..-
	0x10 + 4,	// V: ...-
	0x60 + 3,	// W: .--
	0x90 + 4,	// X: -..-
	0xB0 + 4,	// Y: -.--
	0xC0 + 4    // Z: --..
	
};

Download the code

 

Fab Academy - Class schedule 2015

Week 1

Principles and Practices

Week 2

Computer-Aided Design

Week 3

Computer-Controlled Cutting

Week 4

Electronics Production

Week 5

3D Scanning and Printing

Week 8

Computer-controlled machining

Week 13

Networking and Communications

Week 14

Interface and application programming

Week 15

Mechanical Design, Machine Design

Week 16

Applications and Implications

Week 17

Invention, Intellectual Property, and Income

More information and suggestions

please Keep in Touch!