napriklad def_io_v01.h:
#define IOB_11 2 // PD2
#define OUT_IOB_11 (DDRD |= (1<<IOB_11))
#define IN_IOB_11 (DDRD &= ~(1<<IOB_11))
#define SET_IOB_11 (PORTD |= (1<<IOB_11))
#define RES_IOB_11 (PORTD &= ~(1<<IOB_11))
#define GET_IOB_11 (PIND & (1<<IOB_11))
#define IOB_12 3 // PD3
#define OUT_IOB_12 (DDRD |= (1<<IOB_12))
#define IN_IOB_12 (DDRD &= ~(1<<IOB_12))
#define SET_IOB_12 (PORTD |= (1<<IOB_12))
#define RES_IOB_12 (PORTD &= ~(1<<IOB_12))
#define GET_IOB_12 (PIND & (1<<IOB_12))
#define RX0 0 // PD0, RX0
#define OUT_RX0 (DDRD |= (1<<RX0))
#define IN_RX0 (DDRD &= ~(1<<RX0))
#define SET_RX0 (PORTD |= (1<<RX0))
#define RES_RX0 (PORTD &= ~(1<<RX0))
#define GET_RX0 (PIND & (1<<RX0))
#define TX0 1 // PD1, TX0
#define OUT_TX0 (DDRD |= (1<<TX0))
#define IN_TX0 (DDRD &= ~(1<<TX0))
#define SET_TX0 (PORTD |= (1<<TX0))
#define RES_TX0 (PORTD &= ~(1<<TX0))
#define GET_TX0 (PIND & (1<<TX0))
#define COM0_SMER 0 // PD0, RX0
#define OUT_COM0_SMER (DDRD |= (1<<COM0_SMER))
#define IN_COM0_SMER (DDRD &= ~(1<<COM0_SMER))
#define SET_COM0_SMER (PORTD |= (1<<COM0_SMER))
#define RES_COM0_SMER (PORTD &= ~(1<<COM0_SMER))
#define GET_COM0_SMER (PIND & (1<<COM0_SMER))
a potom v
program_v01.c
// .... vsetky potrebne include pre ten ktory procesor, rozpisovat nebudem
#include "def_io_v01.h"
// funkcia jednoducheho invertora
int main(void)
{
IN_IOB_21;
OUT_IOB_11
for(;;) {
if (GET_IOB_21) RES_IOB_11; // zatvorky okolo GET_IOB_21 su zbytocne, ale kvoli prehladnosti sa hodia
else SET_IOB_11;
}
}
A kedze uz vidim, ako sa tu odporcovia C-cka na jednocipy jezia (v dobrom, samozrejme ), lebo oni by to urcite v asm napisali efektivnejsie, ako manipulovat s celym portom, akoby sa zdalo z napisanych makier.
Tak uvadzam disasembler, aby bolo jasne, ze ak sa pouzije rozumny prekladac (v mojom pripade GCC cez WinAVR, optimalizacia -Os), tak preklad nemusi byt neefektivny. Prekladac totizto vie, kedy pouzit instrukcie bitovej manipulacie s pinmi portov a kedy treba pouzit manipulaciu s celym bajtom.
126: IN_IOB_21;
+00000716: 9854 CBI 0x0A,4 Clear bit in I/O register
127: OUT_IOB_11;
+00000717: 9A3B SBI 0x07,3 Set bit in I/O register
128: if (GET_IOB_21) {
+00000718: 9B4C SBIS 0x09,4 Skip if bit in I/O register set
+00000719: C002 RJMP PC+0x0003 Relative jump
129: RES_IOB_11;
+0000071A: 9843 CBI 0x08,3 Clear bit in I/O register
+0000071B: C001 RJMP PC+0x0002 Relative jump
132: SET_IOB_11;
+0000071C: 9A43 SBI 0x08,3 Set bit in I/O register
Pri -O0 to tak samozrejme neprelozi, lebo -O0 hovori: “co si si napisal, to dostanes”, ale uz od -O2 je to zoptimalizovane v takomto tvare.
I napriek tomuto prikladu efektivneho prekladu verim, ze rozsiahlejsi program napisany v C moze byt az 2x dlhsi a 2xpomalsi oproti tomu, ako to vie napisat odbornik asemblerista. Vzhladom na nizky vyskyt odbornikov asembleristov a vysoky vyskyt Flash v procesore sa mi to nezda byt ako velmi nevyhodny pomer.
Ak vsak ide o rychlost bez moznosti zmenit procesor, treba to zvazit.
Cislovanie riadkov si nevsimajte, dopisal som si to do mojho aktualneho projektu a hned to aj mazem
[/code]