14Ja, stadig i C.
Der her er min 28-bytes-code:
// Compile with avr-gcc gcc-vs-asm_28.c -Wa,-alhd=dump.s -Os
// Define some special function registers. Normally this is done
// with #include <avr/io.h>
#define DDRB (*(volatile unsigned char *)((0x17) + 0x20))
#define PORTB (*(volatile unsigned char *)((0x18) + 0x20))
// Define some usefull macros
#define SetBit(x,y) (x |= (1<<y))
#define ClrBit(x,y) (x &= ~(1<<y))
// Delay Makros
#define clockCyclesPer4MilliSecond ((unsigned int)16*(unsigned int)1000*(unsigned int)4)
#define delay4Milliseconds 250
// Some project defines
#define TESTPIN 5
// The Delay Function
void Delay (void) {
unsigned char outer_i;
unsigned int inner_i;
outer_i = delay4Milliseconds;
do {
inner_i = ((clockCyclesPer4MilliSecond-8)/4);
do {
// There must be a ";", if not, the optimizer
// removes the useless loop
__asm(";");
} while (--inner_i);
} while ( --outer_i);
}
// The main
void main (void) {
// Setup
SetBit(DDRB, TESTPIN);
// The main loop
while (1) {
SetBit(PORTB, TESTPIN); // 2 cycles - set pin HIGH
Delay(); // 3 cycles (the call itself)
ClrBit(PORTB, TESTPIN); // 2 cycles - set pin LOW
Delay(); // 3 cycles (the call itself)
} // 2 cycles (the jump itself) - repeat
}
Og det her er resultatet:
00000000 <Delay>:
0: 2a ef ldi r18, 0xFA ; 250
2: 8e e7 ldi r24, 0x7E ; 126
4: 9e e3 ldi r25, 0x3E ; 62
6: 01 97 sbiw r24, 0x01 ; 1
8: f1 f7 brne .-4 ; 0x6 <__zero_reg__+0x5>
a: 21 50 subi r18, 0x01 ; 1
c: d1 f7 brne .-12 ; 0x2 <__zero_reg__+0x1>
e: 08 95 ret
00000010 <main>:
10: bd 9a sbi 0x17, 5 ; 23
12: c5 9a sbi 0x18, 5 ; 24
14: f5 df rcall .-22 ; 0x0 <Delay>
16: c5 98 cbi 0x18, 5 ; 24
18: f3 df rcall .-26 ; 0x0 <Delay>
1a: fb cf rjmp .-10 ; 0x12 <main+0x2>
Jeg har en 4ms loop, i stedet for 1ms, så min "delayMilliseconds" er nu en "delay
4Milliseconds" og værdien er 250. Der er nu en "unsigned char".
og det her er min 14-bytes-code:
// The main
void main (void) {
unsigned char i;
unsigned int loopcnt;
// The main loop
while (1) {
// Increment i.
// Every 128th cycle, bit 7 of i toggles.
// Put i to the PORTB, only Pin7 is an output
i++;
// Because PORTB is initialized with 0, the LED must be
// connected betwenn PORTB7 and Vcc
DDRB = i;
// 16MHz / 128 / 4 = 31250
loopcnt = 31250;
do {
__asm(";");
} while (--loopcnt);
}
}
00000000 <main>:
0: 2f 5f subi r18, 0xFF ; 255
2: 27 bb out 0x17, r18 ; 23
4: 82 e1 ldi r24, 0x12 ; 18
6: 9a e7 ldi r25, 0x7A ; 122
8: 01 97 sbiw r24, 0x01 ; 1
a: f1 f7 brne .-4 ; 0x8 <__zero_reg__+0x7>
c: f9 cf rjmp .-14 ; 0x0 <main>
I stedet for at sætte en bit i PORTB jeg gør det i DDRB. Jeg har kun en "loop". Det er muligt fordi bit 7 af "i" ændrer hver 128. løb. Og jeg har alt i main.c
EDIT: Det var alt teoretisk. Jeg har ikke prøvet det.