カウントダウン・コルクボード
2017
年2
月19
日 皆無軟体
24
時間、1
時間、1
分、1
秒間隔でカウントダウンしていくボード。 コルクボードになっているため、紙などを貼り付けて飾れる。使用部品と回路図
内部は、
CPU
基板、7
セグメントLED
駆動回路基板、7
セグメントLED
ピン変換基板に分割され ている。筐体には
100
均ショップのコルクボードを使用した。この製品はコルクが薄いため、ピンを刺すと<
CPU
基板>
回路図
部品名 規格等
AVR
マイコンATmega168P (ATmega328P
でも動作するが、ファームウェア のMakefile
を書き換える必要がある)IC
ソケット28PIN
水晶振動子
10MHz
電池ボックス及びバッテリスナップ
押しボタンスイッチ オルタネート動作
AC
アダプタ用コネクタセラミックコンデンサ
33pF 2
個、0.1uF 7
個カーボン抵抗器
10kΩ
タクトスイッチ
5
個圧電スピーカ
ユニバーサル基板 ブレッドボード互換
<
7
セグメント
LED
駆動回路基板>
&
<ピン変換基板>
回路図
部品表
部品名 規格等
トランジスタアレイ
8ch-
ダーリントンシンクドライバTD62084APG
IC
ソケット18PIN
PNP
トランジスタ2SA1015 4
個7
セグメントLED
青色、4桁、OSL-40562-IB
カーボン抵抗器
2.2kΩ 4
個 、150Ω 7
個ユニバーサル基板 ブレッドボード互換
別の
7
セグメントLED
に交換する場合は、7
セグ メントLED
ピン変換基板を交換すればよい。明る いLED
に交換するには、より多くの電流を制御す るため、7
セグメントLED
駆動回路基板のトラン ジスタ類の交換が必要になる場合がある。今回の製品で使用した
7
セグメントLED
はOSL-40562-IB
で、4桁の7セグメントLED
がカ スケード接続されている。ピン配置は図のとおり。裏面の操作パネルには、5個のタクトスイッチ、電源スイッチ、
ISP
用コネクタ、AC
アダプタ ジャックがある。ファームウェア・ソースコード(AVR-GCC 用)
/* *
* 7-segment LED x 4 digit Display Count Down Timer ( EEPROM Backup) * Programmed By Kaimunantai 2016/05/05
* clock 10MHz , div8 *
*/
/*
* PD0, 1, 2, 3, 5 : Push Button Switch : OFF=1, ON=0 * PD2/INT0 : interrupt
*/
#include <avr/io.h>
#include <avr/interrupt.h> #include <avr/eeprom.h>
#define INITIAL_NUMBER 9999 //#define INITIAL_NUMBER 365 //#define INITIAL_NUMBER 30
/*
* clock int.8MHz, div8 : Timer0 1 count = 0.100352 sec. * clock crystal 10MHz, div 8: Timer0 1 count = 0.0999424 sec. * clock crystal 10MHz : Timer0 1 count = 0.019968 sec.
* ( OCR0A / clock frequency * 1024 ) */
//#define TIMER0_LIMIT_1DAY 4326923L // 24 hour. NG. may be 86634 sec. about 7.4min over.
//#define TIMER0_LIMIT_1DAY 4282316L // 24 hour. NG. may be 85741 sec. about 7.5min short.
//#define TIMER0_LIMIT_1DAY 4294244L // 24 hour. NG. may be 86190 sec. about 3.5min short.
//#define TIMER0_LIMIT_1DAY 4304707L // 24 hour. clock 10MHz, 1sec = 49.82299571 ? Timer0, 17sec / 12 day over
//#define TIMER0_LIMIT_1DAY 4304636L // 24 hour. clock 10MHz, 1sec early / 4 day (Timer0)
//#define TIMER0_LIMIT_1DAY 4304648L // 24 hour. clock 10MHz, 2sec late / 14days (Timer0)
#define TIMER0_LIMIT_1DAY 4304640L // 24 hour. clock 10MHz Timer0 //#define TIMER0_LIMIT 180288L // 3600 sec. but 1 hour -> 3618.6 sec.) #define TIMER0_LIMIT_1HOUR 179361L // 3600 sec. tuned parameter
// #define TIMER0_LIMIT_1MINUTE 3005L // 60 sec. but 60'00" -> 60'22"
#define TIMER0_LIMIT_1MINUTE 2989L // 60 sec. tuned parameter. clock crystal 10MHz, Timer0 1 count = 0.0200728
//#define TIMER0_LIMIT_10SEC 501 // 10 sec. #define TIMER0_LIMIT_1SECOND 50 // 1 sec.
enum {
MODE_DAY, MODE_HOUR, MODE_MINUTE, MODE_SECOND };
static uint16_t TIMEMODE = MODE_SECOND;
static uint32_t TIMER0_LIMIT = TIMER0_LIMIT_1SECOND;
enum {
static uint8_t STAGE = STAGE_READY;
static uint16_t EEMEM EEPROM_NUMBER, EEPROM_MODE; // Previous number storage in EEPROM static uint16_t EEMEM EEPROM_MODE; // Previous time mode storage in EEPROM
static inline void wait(volatile uint32_t i) // wait for a while
// Arguments :
// i : waiting length {
while ( i-- > 0 ); }
static inline void buzOn(void) // Buzzer ON / OFF
{
PORTD ^= (1<<PD4); }
void beepOn(unsigned int tone, unsigned long length) // beep by Buzzer
// Arguments :
// tone : tone height , tone 2 (high) ~ 1000 (low) // length : beep sound time
{
length /= tone;
while (length-- > 0) { buzOn();
wait(tone); }
}
static inline uint8_t isSwitchOn(void) {
return !( PIND & ( 1<<PD2 ) ); }
static inline uint8_t isSwitchOn0(void) {
return !( PIND & ( 1<<PD0 ) ); }
static inline uint8_t isSwitchOn1(void) {
return !( PIND & ( 1<<PD1 ) ); }
static inline uint8_t isSwitchOn2(void) {
return !( PIND & ( 1<<PD2 ) ); }
static inline uint8_t isSwitchOn3(void) {
return !( PIND & ( 1<<PD3 ) ); }
static inline uint8_t isSwitchOn5(void) {
return !( PIND & ( 1<<PD5 ) ); }
uint8_t getSwitch(void) {
uint8_t sw;
return sw; }
/*
* initialize */
static inline void initIo(void) // initialize I/O ports.
{
PORTD = (1<<PD5) | (1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0); // weak pull up resistor enable on PD53210
DDRD = 0b11010000; // PD53210 as Input, others Output DDRC = 0b11111111; // PORTC All Output
DDRB = 0b11111111; // PORTB All Output }
static inline void initInt0(void) {
EICRA |= (1<<ISC01) | (1<<ISC11); // INT0 Falling Edge, INT1 Falling edge // EIMSK |= (1<<INT0) | (1<<INT1); // Enable Interrupt 0, 1
EIMSK |= (1<<INT0); // Enable Interrupt 0 }
static inline void initTimer0(void) // Initialize TIMER0
{
// CTC mode , TOP is OCR0A
TCCR0A = (1 << WGM01) | (0 << WGM00) ; // I/O clock prescaler N = 8
// TCCR0B = (0 << WGM02) | (0 << CS02) | (1 << CS01) | (0 << CS00); // I/O clock prescaler N = 1024
TCCR0B = (0 << WGM02) | (1 << CS02) | (0 << CS01) | (1 << CS00); // Timer0 on OCR0A compare match interrupt enable
TIMSK0 |= ( 1<< OCIE0A );
// set TOP value . Interrupt every 1 ms
//OCR0A = 125; // OCR0A = interrupt period [s] * f_clkio [Hz] / I/O clock prescaler N // set TOP value. Interrupt every 0.1s at Internal clock 8MHz / 8 = 1MHz
//OCR0A = 98;
// set TOP value. Interrupt every 0.1s at Full Swing clock 10MHz / 8 // OCR0A = 122;
// set TOP value. Interrupt every 0.02s at Full Swing clock 10MHz OCR0A = 195;
}
/*
* Interrupt */
volatile uint32_t TIMER0_COUNTER; // Timer0 interrupt counter
ISR(TIMER0_COMPA_vect)
// Timer0 Timer counter Compair match Interrupt {
TIMER0_COUNTER++; }
ISR(INT0_vect) // INT0 Interrupt {
beepOn(40,10000); switch ( STAGE ) { case STAGE_READY :
STAGE = STAGE_COUNTDOWN; break;
STAGE = STAGE_READY; break;
case STAGE_ALARM : STAGE = STAGE_READY; }
while( isSwitchOn() ); }
void choose_7seg_digit(uint8_t digit) /*
* PORTC-5432 : 7seg anode ( digit ) 0123 : 1-OFF, 0-ON * digit 0123
* PORTC 0bxx0000xx */
{
// choose digit switch (digit) { case 0 :
PORTC |= (0b00011100); PORTC &= ~(0b00100000); break;
case 1 :
PORTC |= (0b00101100); PORTC &= ~(0b00010000); break;
case 2 :
PORTC |= (0b00110100); PORTC &= ~(0b00001000); break;
case 3 :
PORTC |= (0b00111000); PORTC &= ~(0b00000100); break;
default :
PORTC |= (0b00111100); }
}
void off_7seg(void) {
PORTB = ~(0b00000000); PORTC |= (0b00000000); }
void show_7seg_1digit(uint16_t number) /*
* arguments : * digit : 3210 * number : 0 ~ 9 *
* PORT *
* digit:
* 3 2 1 0 * * | | | | | | | | * f b f b f b f b * | | | | | | | | * * | | | | | | | | * e c e c e c e c * | | | | | | | | * *
*
* PORTC-1 : 7seg -a- : 0-OFF, 1-ON * PORTC 0bxxxxxx0x
* PORTB-543210 : 7seg -b-c-d-e-f-g- : 0-OFF, 1-ON * PORTB : 0bxx 0 0 0 0 0 0
*
* xxbcdefg * PORTB 0bxx000000 * PORTC 0bxx0000xx *
*/ {
switch (number) { case 0 :
// a-b-c-d-e-f
PORTB = ~(0b00000001); PORTC |= (0b00000010); break;
case 1 : // b-c
PORTB = ~(0b00001111); PORTC &= ~(0b00000010); break;
case 2 :
// a-b-d-e-g
PORTB = ~(0b00010010); PORTC |= (0b00000010); break;
case 3 :
// a-b-c-d-g
PORTB = ~(0b00000110); PORTC |= (0b00000010); break;
case 4 : // b-c-f-g
PORTB = ~(0b00001100); PORTC &= ~(0b00000010); break;
case 5 :
// a-c-d-f-g
PORTB = ~(0b00100100); PORTC |= (0b00000010); break;
case 6 :
// a-c-d-e-f-g
PORTB = ~(0b00100000); PORTC |= (0b00000010); break;
case 7 : // a-b-c
PORTB = ~(0b00001111); PORTC |= (0b00000010); break;
case 8 :
// a-b-c-d-e-f-g
PORTB = ~(0b00000000); PORTC |= (0b00000010); break;
case 9 :
// a-b-c-d-f-g
PORTB = ~(0b00000100); PORTC |= (0b00000010); break;
default :
// All segments OFF PORTB = ~(0b00111111); PORTC &= ~(0b00000010); }
}
uint8_t i;
for ( i = 0; i < 4 ; i++) {
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( number % 10 );
choose_7seg_digit( i );
wait(1);
number /= 10; }
}
void show_7seg_4digit_timer( uint16_t number, uint32_t timer) {
TIMER0_COUNTER = 0;
while( TIMER0_COUNTER < timer ) { show_7seg_4digit(number); }
}
void getDigitNum(uint16_t num, uint16_t *num1000, uint16_t *num100, uint16_t *num10, uint16_t *num1)
{
*num1000 = num / 1000;
*num100 = ( num % 1000 ) / 100; *num10 = (num % 100 ) / 10; *num1 = (num % 10 ); }
void show_7seg_char(char ch) /*
* arguments :
* character 'c', 'd', 'e' , 'H', 'S', '-' *
* PORT *
* digit:
* 3 2 1 0 * * | | | | | | | | * f b f b f b f b * | | | | | | | | * * | | | | | | | | * e c e c e c e c * | | | | | | | | * *
*
* PORTC-1 : 7seg -a- : 0-OFF, 1-ON * PORTC 0bxxxxxx0x
*
* PORTB-543210 : 7seg -b-c-d-e-f-g- : 0-OFF, 1-ON * PORTB : 0bxx 0 0 0 0 0 0
*
* xxbcdefg * PORTB 0bxx000000 * PORTC 0bxx0000xx *
*/ {
case 'C' : // a-d-e-f
PORTB = ~(0b00110001); PORTC |= (0b00000010); break;
case 'd' : case 'D' : // b-c-d-e-g
PORTB = ~(0b00000010); PORTC &= ~(0b00000010); break;
case 'e' : case 'E' : // a-d-e-f-g
PORTB = ~(0b00110000); PORTC |= (0b00000010); break;
case 'H' : case 'h':
// b-c-e-f-g
PORTB = ~(0b00001000); PORTC &= ~(0b00000010); break;
case 'S' : case 's' : // a-c-d-f-g
PORTB = ~(0b00100100); PORTC |= (0b00000010); break;
case '-' : // g
PORTB = ~(0b00111110); PORTC &= ~(0b00000010); break;
default :
// All segments OFF PORTB = ~(0b00111111); PORTC &= ~(0b00000010); }
}
void show_7seg_mode( uint16_t time_mode ) {
switch (time_mode) { case MODE_DAY :
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 2 );
choose_7seg_digit( 3 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 4 );
choose_7seg_digit( 2 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'H' );
choose_7seg_digit( 1 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( '-' );
choose_7seg_digit( 0 ); wait(1);
break; case MODE_HOUR :
choose_7seg_digit( 3 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 1 );
choose_7seg_digit( 2 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'H' );
choose_7seg_digit( 1 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( '-' );
choose_7seg_digit( 0 ); wait(1);
break;
case MODE_MINUTE :
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 6 );
choose_7seg_digit( 3 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 0 );
choose_7seg_digit( 2 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'S' );
choose_7seg_digit( 1 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'E' );
choose_7seg_digit( 0 ); wait(1);
break;
case MODE_SECOND :
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_1digit( 1 );
choose_7seg_digit( 3 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'S' );
choose_7seg_digit( 2 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'E' );
choose_7seg_digit( 1 ); wait(1);
choose_7seg_digit( -1 ); // 7SEG ALL DIGIT OFF show_7seg_char( 'C' );
choose_7seg_digit( 0 ); wait(1);
break; default :
show_7seg_4digit( 0 ); }
/* * main */
int main(void) {
volatile uint16_t num = INITIAL_NUMBER; uint16_t num1000, num100, num10, num1;
initIo(); initInt0(); initTimer0();
//while (isSwitchOn0() || isSwitchOn1() || isSwitchOn2() || isSwitchOn3() || isSwitchOn5());
//while (isSwitchOn()); show_7seg_4digit(0); wait(10000);
if ( isSwitchOn0() ) {
// when Boot system, if switch #0 ON -> reset number, Day mode num = INITIAL_NUMBER;
while (isSwitchOn0());
TIMEMODE = MODE_DAY;
TIMER0_LIMIT = TIMER0_LIMIT_1DAY;
// write current value to EEPROM eeprom_busy_wait();
eeprom_update_word(&EEPROM_MODE, TIMEMODE);
STAGE = STAGE_READY;
} else if ( isSwitchOn1()) {
// when Boot system, if switch #1 ON -> reset number, Hour mode num = INITIAL_NUMBER;
while (isSwitchOn1());
TIMEMODE = MODE_HOUR;
TIMER0_LIMIT = TIMER0_LIMIT_1HOUR;
// write current value to EEPROM eeprom_busy_wait();
eeprom_update_word(&EEPROM_MODE, TIMEMODE);
STAGE = STAGE_READY;
} else if ( isSwitchOn3()) {
// when Boot system, if switch #2 ON -> reset number, Minute mode num = INITIAL_NUMBER;
while (isSwitchOn3());
TIMEMODE = MODE_MINUTE;
TIMER0_LIMIT = TIMER0_LIMIT_1MINUTE;
// write current value to EEPROM eeprom_busy_wait();
eeprom_update_word(&EEPROM_MODE, TIMEMODE);
STAGE = STAGE_READY;
// when Boot system, if switch #5 ON -> reset number, Second mode num = INITIAL_NUMBER;
while (isSwitchOn5());
TIMEMODE = MODE_SECOND;
TIMER0_LIMIT = TIMER0_LIMIT_1SECOND;
// write current value to EEPROM eeprom_busy_wait();
eeprom_update_word(&EEPROM_MODE, TIMEMODE);
STAGE = STAGE_READY;
} else {
// when Boot system, if switch OFF -> recover previous number beepOn( 100 , 1000 );
// get previous number from EEPROM eeprom_busy_wait();
num = eeprom_read_word(&EEPROM_NUMBER);
if ( num > INITIAL_NUMBER ) { num = INITIAL_NUMBER; }
TIMEMODE = eeprom_read_word(&EEPROM_MODE); switch (TIMEMODE) {
case MODE_SECOND:
TIMER0_LIMIT = TIMER0_LIMIT_1SECOND; break;
case MODE_MINUTE:
TIMER0_LIMIT = TIMER0_LIMIT_1MINUTE; break;
case MODE_HOUR:
TIMER0_LIMIT = TIMER0_LIMIT_1HOUR; break;
case MODE_DAY:
TIMER0_LIMIT = TIMER0_LIMIT_1DAY; break;
default:
TIMEMODE = MODE_SECOND;
TIMER0_LIMIT = TIMER0_LIMIT_1SECOND; }
// show_7seg_4digit( num ); STAGE = STAGE_COUNTDOWN; }
beepOn( 20 , 10000 );
sei(); // Enable Interrupt
// TIME mode display 3 sec.
for ( TIMER0_COUNTER = 0; TIMER0_COUNTER < TIMER0_LIMIT_1SECOND * 3; ) { show_7seg_mode( TIMEMODE );
}
while (1) {
switch(STAGE) { case STAGE_READY:
show_7seg_4digit( num ); if (TIMER0_COUNTER > 100) { choose_7seg_digit(-1); wait(50000);
TIMER0_COUNTER = 0; }
getDigitNum(num, &num1000, &num100, &num10, &num1);
if (isSwitchOn0()) { beepOn(5,1000); num1000++;
if (num1000 > 9) { num1000 = 0; }
while(isSwitchOn0()); }
if (isSwitchOn1()) { beepOn(5,1000); num100++;
if (num100 > 9) { num100 = 0; }
while(isSwitchOn1()); }
if (isSwitchOn3()) { beepOn(5,1000); num10++;
if (num10 > 9) { num10 = 0; }
while(isSwitchOn3()); }
if (isSwitchOn5()) { beepOn(5,1000); num1++;
if (num1 > 9) { num1 = 0; }
while(isSwitchOn5()); }
num = num1000 * 1000 + num100 * 100 + num10 * 10 + num1;
break;
case STAGE_RESET:
num = INITIAL_NUMBER; show_7seg_4digit( num ); STAGE = STAGE_COUNTDOWN; break;
case STAGE_COUNTDOWN:
// write current value to EEPROM eeprom_busy_wait();
eeprom_update_word(&EEPROM_NUMBER, num);
TIMER0_COUNTER = 0;
while (TIMER0_COUNTER < TIMER0_LIMIT) { show_7seg_4digit( num );
/* blink
if (TIMER0_COUNTER % 2 == 1) { choose_7seg_digit(-1); //OFF } else {
show_7seg_4digit( num ); }
*/
if ( isSwitchOn0() ) { beepOn(5,1000);
while ( isSwitchOn0() ); num++;
TIMER0_COUNTER = 0; }
if ( isSwitchOn1() ) { beepOn(10,1000);
while ( isSwitchOn1() ); if (num <= 0) {
num = 0; } else { num--; }
TIMER0_COUNTER = 0; }
if (STAGE != STAGE_COUNTDOWN) { break;
} } num--;
if (num <= 0) { num = 0;
STAGE = STAGE_ALARM; TIMER0_COUNTER = 0; }
break;
case STAGE_ALARM:
show_7seg_4digit(0);
if (TIMER0_COUNTER > 100) { choose_7seg_digit(-1); wait(500000L);
TIMER0_COUNTER = 0; }
break; }
}
Makefile
(
AVR-GCC, Xcode
用)
# Name: Makefile
# Author: <insert your name here>
# Copyright: <insert your copyright message here> # License: <insert your license reference here>
# This is a prototype Makefile. Modify it according to your needs. # You should at least check the settings for
# DEVICE ... The AVR device you compile for # CLOCK ... Target AVR clock rate in Hertz
# OBJECTS ... The object files created from your source files. This list is # usually the same as the list of source files with suffix ".o". # PROGRAMMER ... Options to avrdude which define the hardware you use for # uploading to the AVR and the interface where this hardware # is connected. We recommend that you leave it undefined and # add settings like this to your ~/.avrduderc file:
# default_programmer = "stk500v2" # default_serial = "avrdoper"
# FUSES ... Parameters for avrdude to flash the fuses appropriately.
DEVICE = atmega168 AVRDUDE_DEVICE = m168p CLOCK = 1000000
PROGRAMMER = -c avrispmkII -P usb OBJECTS = main.o
#FUSES = -U hfuse:w:0xdf:m -U lfuse:w:0x62:m #Full Swing Crystal, Divide clock by 8
#FUSES = -U hfuse:w:0xdf:m -U lfuse:w:0x56:m #Full Swing Crystal
FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0xd6:m
# ATMega8 fuse bits used above (fuse bits for other devices are different!): # Example for 8 MHz internal oscillator
# Fuse high byte:
# 0xd9 = 1 1 0 1 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) # ^ ^ ^ ^ ^ ^ ^--- BOOTSZ0
# | | | | | +--- BOOTSZ1
# | | | | +--- EESAVE (set to 0 to preserve EEPROM over chip erase) # | | | +--- CKOPT (clock option, depends on oscillator type) # | | +--- SPIEN (if set to 1, serial programming is disabled) # | +--- WDTON (if set to 0, watchdog is always on)
# +--- RSTDISBL (if set to 0, RESET pin is disabled) # Fuse low byte:
# 0x24 = 0 0 1 0 0 1 0 0 # ^ ^ \ / \--+--/
# | | | +--- CKSEL 3..0 (8M internal RC) # | | +--- SUT 1..0 (slowly rising power)
# | +--- BODEN (if 0, brown-out detector is enabled) # +--- BODLEVEL (if 0: 4V, if 1: 2.7V)
#
# For computing fuse byte values for other devices and options see # the fuse bit calculator at http://www.engbedded.com/fusecalc/
# Tune the lines below only if you know what you are doing:
AVRDUDE = avrdude $(PROGRAMMER) -p $(AVRDUDE_DEVICE)
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
# symbolic targets: all: main.hex
.c.o:
$(COMPILE) -c $< -o $@
$(COMPILE) -x assembler-with-cpp -c $< -o $@
# "-x assembler-with-cpp" should not be necessary since this is the default # file type for the .S (with capital S) extension. However, upper case # characters are not always preserved on Windows. To ensure WinAVR # compatibility define the file type manually.
.c.s:
$(COMPILE) -S $< -o $@
flash: all
$(AVRDUDE) -U flash:w:main.hex:i
fuse:
$(AVRDUDE) $(FUSES)
# Xcode uses the Makefile targets "", "clean" and "install" install: flash fuse
# if you use a bootloader, change the command below appropriately: load: all
bootloadHID main.hex
clean:
rm -f main.hex main.elf $(OBJECTS)
# file targets: main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS)
main.hex: main.elf rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size --format=avr --mcu=$(DEVICE) main.elf
# If you have an EEPROM section, you must also create a hex file for the # EEPROM and add it to the "flash" target.
# Targets for code debugging and analysis: disasm: main.elf
avr-objdump -d main.elf
cpp: