www.mikrocontroller.net

Forum: Compiler & IDEs Senden einer Infrarotsequenz


Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich baue gerade eine Art Fernbedienung, dafür müssen natürlich 
Bitsequenzen an eine IR-LED ausgegeben werden. Hier erstmal eine 
(erläuterte) Beispielsbitsequenz:

  Herstellercode   Parity   Genre       Data     ID   Parity
00101010  01001100  0000  1110 0110  0100000000  00  01101000

Es wird von links angefangen zu übertragen. Der Herstellercode, die 
erste Parity, das Genre und die ID sind bei jeder Übertragung gleich. 
Die 10 Datenbits sollen an die Sendefunktion übergeben werden. Die 
Parity soll von der Funktion selbstständig berechnet werden, um Speicher 
zu sparen. Sie wird aus dem 3., 4. und 5. Byte per XOR errechnet.

Meine Überlegung war jetzt die folgende: In einer Sendefunktion (ihr 
Name sei JAPAN) wird eine 64 Bit-Variable mit den Fixwerten 
initialisiert, dann wird der übergebene Datenwert darangeschoben und die 
Parity ausgerechnet. Ich weiß jedoch nicht, wie ich das realisieren 
kann. Würde jemand so freundlich sein, mir mit einem Codeschnipsel 
weiterzuhelfen?
Ich brauche nur die fertige 64 Bit-Variable, die Data und Parity 
beinhaltet. Wie ich die durchlaufen kann, ist nicht das Problem.

Vielen Dank im Vorraus, Sven

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles was du brauchst sind die bitweisen Operatoren:
| bitweises ODER.
& bitweises UND.
~ bitweises negieren.
>>n rechtsshift um n Bits
<<n linksshift um n Bits

Falls du nicht genau weißt, was die machen: 
http://de.wikipedia.org/wiki/Bitweiser_Operator


Das zweite Byte von rechts aus einer Variable x bekommst du dann z.B. 
mit
uint8_t second_byte = (x & 0xFF00) >> 8.

Alternativ, nicht portabel aber evtl. schneller (Assembler-Code 
kontrollieren!) geht das gleiche auch so:
uint8_t second_byte = ((uint8_t*)&x)[1].
Vielleicht muss der Index auch anders sein, aber das Prinzip sollte klar 
werden.

Mit dem bitweisen ODER kannst du die übergebenen Werte in den 
64-Bit-Wert "einfügen" (wenn du nicht weißt wie, würde ich dir raten 
eine Skizze zu machen; so viele Möglichkeiten gibt es da nicht).

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke erstmal für die Tipps. Ich habe jetzt mal einen Entwurf für die 
Funktion angefertigt:
void JAPAN(uint16_t data){
  uint64_t sequenz = 108016212 | (data << 28); //Zeile 48
  uint8_t parity = ((sequenz & 0xFF0000) >> 16) ^ ((sequenz & 0xFF000000) >> 24) ^ ((sequenz & 0xFF00000000) >> 32);
  sequenz |= (parity << 40); //Zeile 50
  
  //Start
  IR_LED_ON(); _delay_us(3454); IR_LED_OFF(); _delay_us(1654);
  
  //Datensequenz
  for(uint8_t i=0; i<48; i++){
    IR_LED_ON();
    _delay_us(465);
    
    IR_LED_OFF();
    _delay_us(394);      
    
    if(sequenz & (1<<i))
      _delay_us(789);
  }

  //STOP
  IR_LED_ON(); _delay_us(474); IR_LED_OFF(); _delay_us(74755);
}

Beim Kompilieren kommen die folgenden Warnings:
ir.c:48: warning: left shift count >= width of type
ir.c:50: warning: left shift count >= width of type

Natürlich könnte ich jetzt data und parity auch als 64 Bit-Variable 
ausführen, aber dann kann ich mir das ja auch alles sparen und direkt 
eine 64 Bit-Variable übergeben. Das will ich mir ja aber sparen. Wer 
weiß Abhilfe?

Autor: let (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei solchen Warnungen staune ich immer wieder über die
'Intelligenz' des GCC.
Das Problem sind in der Tat die Shifts:

Hier:
for(uint8_t i=0; i<48; i++){

und dann hier:
if(sequenz & (1<<i))

Die '1' ist vom Typ 'int', hat also beim AVR 16 Bits. Zu wenig
für die for-Schleife.

Ich würde es mit
if(sequenz & (1ULL <<i))
 versuchen.

Hinter IR_LED_ON() steckt vermutlich ein PWM o. ä. der den Träger
erzeugt? Sowas wird nicht bei jedem Empfänger funktionieren, da
die tatsächliche Dauer eines Pulses so nur abgeschätzt wird.
Einige Geräte erwarten ziemlich genaue Zeiten und wenn man da
einen Puls mit einer Toleranz von +/-1 Periode sendet kann das
schnell mal schief gehen.
Also: Versuchen die Trägerfrequenz so genau wie möglich zu treffen
(davon hängt letztlich die Pulsdauer ab) und damit die erwartete
Anzahl Perioden senden.
Bedenke auch das das hantieren mit Datentypen > 8Bits auf einem
AVR mitunter recht lange dauern kann. Zumindest dann wenn es um
Mikrosekunden geht.

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
die Warnings liegen nicht in der Zeile, die du angesprochen hast, 
sondern in den Zeilen 48 und 50, die ich mit entsprechenden 
Zeilennummern versehen habe.

Die Modulationsfrequenz wird mit Timer2 im CTC Mode erzeugt. So erziele 
ich eine Genauigkeit von 0,05kHz, was vollkommen ausreichend ist.

Ich möchte einfach erstmal gucken, ob mein Problem mit meinem Ansatz 
lösbar ist. Anschließend denke ich nochmal über das mit dem Timer 
nach...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  uint64_t sequenz = 108016212 | (data << 28); //Zeile 48
  sequenz |= (parity << 40); //Zeile 50

 |
 v
  uint64_t sequenz = 108016212ULL | ((uint64_t) data << 28); //Zeile 48
  sequenz |= ((uint64_t) parity << 40); //Zeile 50

Du hast übrigens noch mehr "ULL" Fehler in deinem Quellcode. Alle 
Konstanten, die größer als int (0x7FFF bzw. 32767 beim AVR-GCC 
normalerweise) sind, müssen mit U (für bis zu 0xFFFF, 65535), UL (für 
bis zu 0xFFFFFFFF 32bit) oder ULL für 64bit postfixiert werden!

Damit die Shifts in 64Bit Breite ausgeführt werden, sollte die Variable 
data bzw. parity vorher gecastet werden.

Du kannst übrigens auch data vorher in eine 64bit Temporär-Variable 
kopieren und dann den Shift ausführen. Ich gehe mal stark davon aus, 
dass der Compiler den gleichen Code oder einen ähnlichen Code generieren 
wird.

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, die Warnings sind weg! Hier jetzt der Code:
void JAPAN(uint16_t data){
  uint64_t sequenz = 108016212ULL | ((uint64_t) data << 28);
  uint8_t parity = ((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz & 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32);
  sequenz |= ((uint64_t) parity << 40);
  
  //Start
  IR_LED_ON(); _delay_us(3454); IR_LED_OFF(); _delay_us(1654);
  
  //Datensequenz
  for(uint8_t i=0; i<48; i++){
    IR_LED_ON();
    _delay_us(465);
    
    IR_LED_OFF();
    _delay_us(394);      
    
    if(sequenz & ((uint64_t) (1<<i))) //Ist das so richtig???
      _delay_us(789);
  }

  //STOP
  IR_LED_ON(); _delay_us(474); IR_LED_OFF(); _delay_us(74755UL);
}

Kannst du nochmal erläutern, was du mit dem folgenden meintest?
> Damit die Shifts in 64Bit Breite ausgeführt werden, sollte die Variable
> data bzw. parity vorher gecastet werden.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven S. wrote:
> Super, die Warnings sind weg! Hier jetzt der Code:
void JAPAN(uint16_t data){
   uint64_t sequenz = 108016212ULL | ((uint64_t) data << 28);
   uint8_t parity = ((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz &
 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32);
   sequenz |= ((uint64_t) parity << 40);
 
   //Start
   IR_LED_ON(); _delay_us(3454); IR_LED_OFF(); _delay_us(1654);
 
   //Datensequenz
   for(uint8_t i=0; i<48; i++){
     IR_LED_ON();
     _delay_us(465);
 
     IR_LED_OFF();
     _delay_us(394);
 
     if(sequenz & ((uint64_t) (1<<i))) //Ist das so richtig???
       _delay_us(789);
   }
 
   //STOP
   IR_LED_ON(); _delay_us(474); IR_LED_OFF(); _delay_us(74755UL);
 }

> Kannst du nochmal erläutern, was du mit dem folgenden meintest?
>> Damit die Shifts in 64Bit Breite ausgeführt werden, sollte die Variable
>> data bzw. parity vorher gecastet werden.

Klar: Durch das (uint64_t) in den Klammern vor der Variable data bzw. 
parity wird diese (16 Bit Variable) wie eine 64 bit Variable behandelt. 
Der Compiler führt also den auf diesen Cast folgenden Shift in 64 Bit 
Breite durch. Somit ist alles in Butter.

Folgende Zeilen wird vermutlich noch eine Warnung erzeugen:
   uint8_t parity = ((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz &
 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32);
Da das letzte Klammerpaar (durch das ULL Prefix) ein uint64_t Typ ist, 
wird der gesamte Rechte Ausdruck auf uint64_t angehoben, bevor er durch 
das XOR verknüpft und schlussendlich dem "parity" zugewiesen wird. Am 
besten sollte man hier auch wieder einen Cast benutzen, wenn ich mich 
jetzt nicht irre:
   uint8_t parity = (uint8_t) (((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz &
 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32));
     if(sequenz & ((uint64_t) (1<<i))) //Ist das so richtig???
Die Zeile funktioniert so nicht wie gewünscht, da auch beim Casten immer 
noch die Klammerregeln gelten. Sprich: Hier wird erst nach dem Shiften 
gecastet.
Entweder:
     if(sequenz & (1ULL<<i))
oder
     if(sequenz & ((uint64_t) 1<<i))

Hoffe jetzt keinen Fehler gemacht zu haben. Ich verlass mich bei solchen 
Geschossen immer auf die Warnungen vom Compiler ;)

Übrigens sind Shifts um ein i-faches auf dem AVR relativ langsam (Da der 
Shift mithilfe eine Schleife durchgeführt wird). Am besten ist es, die 
sequenz Variable durchzushiften und immer das niedrigste Bit zu prüfen. 
und den Ausgang entsprechend zu setzen. Die Variable "sequenz" ist zwar 
danach nicht mehr zu gebrauchen, aber man kann diese ja vorher sichern.

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, vielen Dank für die äußerst ausführlichen Ausführungen. Das mit den 
Shifts um ein i-faches hab ich nach deinen Vorschlägen optimiert. Das 
Ganze funktioniert jetzt wie gewünscht. Bei dem zu fernbedienenden Gerät 
handelt es sich übrigens um einen DRA-700AE Stereoreceiver der Marke 
Denon.
void JAPAN(uint16_t data, uint8_t wiederholungen){
  uint64_t sequenz = 108016212ULL | ((uint64_t) data << 28);
  uint8_t parity = (uint8_t) (((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz & 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32));
  sequenz |= ((uint64_t) parity << 40);
  
  for(uint8_t i=0; i<wiederholungen; i++){
    uint64_t temp_sequenz = sequenz;
    
    //Start
    IR_LED_ON(); _delay_us(3454); IR_LED_OFF(); _delay_us(1654);
    
    //Datensequenz
    for(uint8_t j=0; j<48; j++){
      IR_LED_ON();
      _delay_us(465);
      
      IR_LED_OFF();
      _delay_us(394);      
      
      if(temp_sequenz & 1)
        _delay_us(789);
      
      temp_sequenz >>= 1;
    }
    
    //Stop
    IR_LED_ON(); _delay_us(474); IR_LED_OFF(); _delay_us(74755UL);
  }
}

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven S. wrote:
> Wow, vielen Dank für die äußerst ausführlichen Ausführungen. Das mit den
> Shifts um ein i-faches hab ich nach deinen Vorschlägen optimiert. Das
> Ganze funktioniert jetzt wie gewünscht. Bei dem zu fernbedienenden Gerät
> handelt es sich übrigens um einen DRA-700AE Stereoreceiver der Marke
> Denon.

Super! Auch wenn das Ganze nicht so wirklich schön aussieht ;) 
Normalerweise (tm) macht man sowas mit einem Timer, aber wenn sonst 
nichts nebenbei gemacht werden soll, was das Timing der Warteschleifen 
zerreißt, ist es doch in Ordnung. :D

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast natürlich Recht. Eventuell muss ich bei der Implementierung das 
Ganze nochmal umstricken, deswegen kann ich mir ja schonmal laut 
Gedanken darüber machen:

1. Ich nehme zwei Timer; einer erzeugt die Modulation per Hardware 
(CTC), der andere misst die Zeit. Das ganze würde dann per Interrupt 
vonstatten gehen. Nachteil: Es werden zwei Timer benötigt.

2. Ich nehme einen Timer; er löst im Takt der Modulationsfrequenz aus 
und zählt dabei die Zeit. Nachteil: Bei 40kHz Modulationsfrequenz wäre 
die Zeit zwischen zwei Interrupts 25µs, das würde aber kaum für die 
Befehle ausreichen, oder?

Was meint ihr?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sven S. (schwerminator)

>Du hast natürlich Recht. Eventuell muss ich bei der Implementierung das
>Ganze nochmal umstricken,

Vor allem ist es besonders auf einem 8 Bitter nicht sinnvoll, die 
Datenpakete als 64 Bit Zahlen zu handhaben. Besser als Array von Bytes, 
das ist viel schneller und übersichtlicher.

MFg
Falk

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk,
darüber werde ich mal nachdenken. Ich finde es eigedlich mit der langen 
Variablen übersichtlicher, aber schneller ist das Array natürlich - 
obwohl es nicht so sehr auf Geschwindigkeit ankommt...

Hat jemand Rat auf die oben angesprochene Timerproblematik?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:
> @  Sven S. (schwerminator)
>
>>Du hast natürlich Recht. Eventuell muss ich bei der Implementierung das
>>Ganze nochmal umstricken,
>
> Vor allem ist es besonders auf einem 8 Bitter nicht sinnvoll, die
> Datenpakete als 64 Bit Zahlen zu handhaben. Besser als Array von Bytes,
> das ist viel schneller und übersichtlicher.

Würde ich nicht unbedingt sagen. Wie kommst du darauf? Sind ja keine 
Rechenoperationen, die hier durchgeführt werden.
Einzig beim Shiften wird der Compiler wohl immer alle 8 Bytes Shiften.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Simon K. (simon) Benutzerseite

>Würde ich nicht unbedingt sagen. Wie kommst du darauf?

Weil man ein Datenpakt per UART auch nicht als 1024 Bit Zahl behandelt, 
wenn man 128 Bytes senden will ;-)

Daten in grosse Zahlen zu packen ist eigentlich nur dann notwendig, wenn 
man direkt und ohne "von Hand" Überlaufrechung was berechnen will.

> Sind ja keine
>Rechenoperationen, die hier durchgeführt werden.

EBEN!

>Einzig beim Shiften wird der Compiler wohl immer alle 8 Bytes Shiften.

Unter anderem. Auch wenn die Compiler schon bisweilen gut optimieren, 
Brain 2.0 können sie nicht ansatzweise ersetzen.

>void JAPAN(uint16_t data){
>   uint64_t sequenz = 108016212ULL | ((uint64_t) data << 28);

Ok, das wird nen normale Initialisierung.

>   uint8_t parity = ((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz &
> 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32);
>   sequenz |= ((uint64_t) parity << 40);

Ist der Compiler so clever, die Shifts rauszuschmeissen und einfachen 
XOR der Bytes draus zu machen?

>      if(temp_sequenz & 1)

Ist er hier so clever zu erkennen, dass er nur das untere Byte prüfen 
muss?

>      temp_sequenz >>= 1;

Der 64 Bit Shift, im aktuellen AVR-GCC eine Katastrophe. Siehe

Beitrag "Re: Frage zur C Syntax"

void JAPAN(uint16_t data, uint8_t wiederholungen){
  uint8_t sequenz[6];
  uint8_t tmp, i, j, k;

  sequenz[0] = 0xaa;
  sequenz[1] = 0xaa;
  sequenz[2] = 0xaa;
  sequenz[3] = 0xaa;
  sequenz[4] = data;
  sequenz[5] = sequenz[0] ^ sequenz[1] ^ sequenz[2] ^ sequenz[3]; // parity
  
  for(i=0; i<wiederholungen; i++){
    
    //Start
    IR_LED_ON(); _delay_us(3454); IR_LED_OFF(); _delay_us(1654);
    
    //Datensequenz
    for (k=0; k<6; k++) { 
      tmp = sequenz[i];
      for(j=0; j<8; j++){
        IR_LED_ON();
        _delay_us(465);
      
        IR_LED_OFF();
        _delay_us(394);      
      
        if(tmp & 1) _delay_us(789);
      
        tmp >>= 1;
      }
    }
    //Stop
    IR_LED_ON(); _delay_us(474); IR_LED_OFF(); _delay_us(74755UL);
  }
}

Sinngemäss, ist jetzt nicht voll syntaktisch OK. Sieht für mich 
wesenlich einfacher aus und ist garantiert kleiner und schneller.

MfG
Falk

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs mal ausprobiert.

Falk Brunner wrote:
>>Einzig beim Shiften wird der Compiler wohl immer alle 8 Bytes Shiften.
Bei 64 Bit Arithmetik ruft er sogar Funktionen dafür auf

> Unter anderem. Auch wenn die Compiler schon bisweilen gut optimieren,
> Brain 2.0 können sie nicht ansatzweise ersetzen.
Natürlich nicht.

>>   uint8_t parity = ((sequenz & 0xFF0000UL) >> 16) ^ ((sequenz &
>> 0xFF000000UL) >> 24) ^ ((sequenz & 0xFF00000000ULL) >> 32);
>>   sequenz |= ((uint64_t) parity << 40);
>
> Ist der Compiler so clever, die Shifts rauszuschmeissen und einfachen
> XOR der Bytes draus zu machen?
Normalerweie macht der Compiler das. Da aber (wie schon erwähnt) die 
Shifts sofort durch einen Funktionsaufruf ersetzt werden, geht das 
natürlich nicht mehr.. Hm, damit habe ich nicht gerechnet. Bei 32 Bit 
Arithmetik versteht er das sehr gut.

>>      if(temp_sequenz & 1)
>
> Ist er hier so clever zu erkennen, dass er nur das untere Byte prüfen
> muss?
Ja.

>>      temp_sequenz >>= 1;
>
> Der 64 Bit Shift, im aktuellen AVR-GCC eine Katastrophe. Siehe
Ja, das stimmt leider.

> ... code ...

> Sinngemäss, ist jetzt nicht voll syntaktisch OK. Sieht für mich
> wesenlich einfacher aus und ist garantiert kleiner und schneller.
Jep, diese Darstellung ist für das Datenpaket eher geeignet das stimmt. 
Ich würde rein gefühlsmäßig bei sowas auch die Array-Variante vorziehen. 
Dachte nur nicht, dass der GCC die 64 Bit Sachen so vermasselt. Wie 
gesagt, bei 32 Bit sieht es definitiv besser aus.

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieder was gelernt! Danke, die 8 Bit-Variante mit Array ist ja auch nur 
unwesensentlich komplizierter, allerdings ist in dem obigen Code nicht 
berücksichtigt, dass es 10 Datenbits gibt, naja ist auch nicht 
wesentlich komplizierter. Ein bisschen shiften mit ner 16 Bit-Variable 
sollte doch gehen...

Bleibt noch die Timerfrage (nein, ich lasse nicht locker ;) )...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Sven S. (schwerminator)

>Wieder was gelernt! Danke, die 8 Bit-Variante mit Array ist ja auch nur
>unwesensentlich komplizierter,

Komplizierter?

>Bleibt noch die Timerfrage (nein, ich lasse nicht locker ;) )...

Du brauchst einen Soft-UART. Unter dem Stichwort wirst du viel finden. 
Auch Application Notes von Atmel.

MFG
Falk

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WOW!!! Der Code ist jetzt nur noch ein Drittel so groß wie vorher. 
Wahnsinn. Ich habe noch eine andere Funktion, in der nur 12 Bit 
übertragen werden müssen (SIRC). Bis jetzt habe ich die in einer 16 
Bit-Variable gepackt, macht es da auch noch Sinn ein 8 Bit-Array zu 
verwenden?

Zum Timerproblem:
Aber UART wird doch nicht moduliert oder seh ich das falsch? Wenn nein 
wäre das doch nicht vergleichbar mit meiner Problemstellung.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. wrote:
> Falk Brunner wrote:

>> Vor allem ist es besonders auf einem 8 Bitter nicht sinnvoll, die
>> Datenpakete als 64 Bit Zahlen zu handhaben. Besser als Array von Bytes,
>> das ist viel schneller und übersichtlicher.
>
> Würde ich nicht unbedingt sagen. Wie kommst du darauf? Sind ja keine
> Rechenoperationen, die hier durchgeführt werden.

Das 64Bit-Paket wurde beim AVR-GCC mit der heißen Nadel dazugestrickt, 
d.h. völlig ohne jegliche Optimierung.

Jeder 64Bit-Operator ruft ganze Orgien von MOV/PUSH/POP und sehr lange 
Funktionscalls auf.

Ich hab mal testweise ein Programm von float auf long long umgestrickt.
Der Code wurde sogar noch größer statt kleiner.

Beim Umstellen auf Byte-Arrays sollte ein Eindampfen um mindesten 75% 
möglich sein.


Ich könnte mir auch vorstellen, daß es zu Zeitproblemen bei den elend 
langsamen 64Bit-Operationen kommt, so ein IR-Signal muß ja in Echtzeit 
ausgegeben werden.


Peter

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sven S. (schwerminator)

>WOW!!! Der Code ist jetzt nur noch ein Drittel so groß wie vorher.
>Wahnsinn.

Strike! ;-)

>übertragen werden müssen (SIRC). Bis jetzt habe ich die in einer 16
>Bit-Variable gepackt, macht es da auch noch Sinn ein 8 Bit-Array zu
>verwenden?

Bei 16 Bit kann man ein einzelne Variable nutzen, da ist der AVR-GCC 
schon gut.

>Aber UART wird doch nicht moduliert oder seh ich das falsch?

Das siehst du rictig.

> Wenn nein wäre das doch nicht vergleichbar mit meiner Problemstellung.

Doch. Du must ja in einem festen Zeitraster Daten ausgeben. Der 
Timer ist dein Freund.

MFG
Falk

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja meine Frage war ja, ob ich einen oder doch zwei Timer benutzen 
sollte...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sven S. (schwerminator)

>Naja meine Frage war ja, ob ich einen oder doch zwei Timer benutzen
>sollte...

Einer reicht.

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.