Hallo,
Suche schon seit langem ein sbit-Makro für AVR und bin jetzt auf dieser
Seite fündig geworden.
Besser gesagt hab ich zwei sbit.h gefunden.
Meine Frage welche von denen kann ich für meinen AVR ATmega2560
verwenden?
Wie benutze ich dieses Makro jetzt?
Bsp.(1 ausgeben an PortB Pin4):
#include <avr/io.h>
#include <C:pfad zur .h-datei\sbit.h>
int main(void)
{
SBIT(DDRB,4) = 1;
while(1)
{
SBIT(PORTB,4) = 1;
}
}
Christian Gruber schrieb:> Meine Frage welche von denen kann ich für meinen AVR ATmega2560> verwenden?> Wie benutze ich dieses Makro jetzt?
Ich würde das kurze makro verwenden. Es sieht für mich universell
Nutzbar aus. Einziges Manko: Das Makro verwendet immer 8 PINs. Wenn Du
noch einen Port im Controller hast der nur 4,6 oder 7 Pins hat, darfst
Du die darauf folgenden halt nie ansprechen.
Christian Gruber schrieb:> Wie benutze ich dieses Makro jetzt?
Die Frage hast Du dir selbst beantwortet. :-)
Die Variante mit dem Bitfeld ist erst zusammen mit den zusätzlichen
Defines aus sbit_lang.txt interessant. Dann kannst Du nämlich schreiben:
1
DDR_B4=1;
2
PORT_B4=0;
Allerdings musst Du für jedes Bit in jedem Register ein entsprechendes
Define haben. In sbit_lang.txt ist es ja nur für die I/O-Ports und nicht
für die ganzen anderen Register definiert. Imo lohnt es sich nicht, das
selber alles einzupflegen. Das wäre eher Aufgabe des Toolchain-Anbieters
gewesen.
Hallo,
auch wenn der letzte Beitrag zu diesem Thread schon 4 Monate alt ist,
grabe ich ihn hier nochmals aus.
Auch ich verwende schon seit Jahren (besser Jahrzehnten) die Peter'sche
sbit.h include Datei, um gezielt auf IO Ports zuzugreifen. Also speziell
mit:
Ich habe dann aber mal in den daraus resultierenden assembler code
geschaut, der doch sehr kryptisch und lang ist, und dann auch noch mit
movw instructions arbeitet, als zwei Bytes. Hier ein Beispiel:
--> Hier der C Code:
##############################################
1
#define MY_PORT SBIT (PORTC, 6)
2
uint8_ti;
3
i=1;
4
MY_PORT=i;
##############################################
--> Hier der resultierende Assembler Code:
##############################################
1
i=1;
2
242c: 81 e0 ldi r24, 0x01 ; 1
3
242e: 8a 83 std Y+2, r24 ; 0x02
4
MY_PORT = i;
5
2430: 85 e3 ldi r24, 0x35 ; 53
6
2432: 90 e0 ldi r25, 0x00 ; 0
7
2434: 2a 81 ldd r18, Y+2 ; 0x02
8
2436: 21 70 andi r18, 0x01 ; 1
9
2438: 21 70 andi r18, 0x01 ; 1
10
243a: 22 95 swap r18
11
243c: 22 0f add r18, r18
12
243e: 22 0f add r18, r18
13
2440: 20 7c andi r18, 0xC0 ; 192
14
2442: fc 01 movw r30, r24
15
2444: 30 81 ld r19, Z
16
2446: 3f 7b andi r19, 0xBF ; 191
17
2448: 23 2b or r18, r19
18
244a: fc 01 movw r30, r24
19
244c: 20 83 st Z, r18
##############################################
Bei sehr zeitkritischen Anwendungen sieht das nicht sehr optimiert aus,
denn es gibt doch die beiden AVR instructions:
SBI P,b Set Bit in I/O Register
CBI P,b Clear Bit in I/O Register
Gibt es keine elegantere, bzw. einfacherer Methode in C, diesen beiden
instructions in den assembler code einzubauen ?
Vielleicht kann Peter hierzu ein paar Kommentare beisteuern.
Gruß
Manni
Manfred L. schrieb:> SBI P,b Set Bit in I/O Register> CBI P,b Clear Bit in I/O Register
Hallo was du referierst bezieht sich auf und nur auf Konstanten.
Dein Code zeigt aber einen Variablenzugriff, das da passiert ist dann
klar.
Du könntest auch auf inline C Code zurückgreifen.
inline void portc6(uint8_t value)
{
if (value) { // != 0
PORTC &= (1<<6);
} else { // == 0
PORTC |= ~(1<<6);
}
}
Manfred L. schrieb:> auch wenn der letzte Beitrag zu diesem Thread schon 4 Monate alt ist,> grabe ich ihn hier nochmals aus.
4 Monate?
Fast 7 Jahre!
Manfred L. schrieb:> Bei sehr zeitkritischen Anwendungen sieht das nicht sehr optimiert aus
Das kann es auch nicht, wenn du dem Compiler nicht sagst, dass du
optimierten Code wünschst. Mit -Os wird
1
MY_PORT=i;
von GCC 9.2.0 übersetzt in
1
sbrc r24,0
2
sbi 0x15,6
3
sbrs r24,0
4
cbi 0x15,6
Das sind gerade mal 5 Taktzyklen. Besser geht es nicht, wenn der Wert
von i zur Compilezeit nicht bekannt ist.
Eine eigene Frage?
Dieser Thread ist über 13 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.