Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 USI und 74HC165


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mathias (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuche einen 74HC165 über USI einzulesen.

Dies habe ich folgendermassen probiert:
1
// Liest versetzt
2
char SPIShiftIn165() {
3
  USISR = 1 << USIOIF;
4
5
  while ((USISR & (1 << USIOIF)) == 0) {
6
    USICR = (1 << USIWM0) | (1 << USICS1) | (1 << USICLK) | (1 << USITC);
7
  }
8
  return USIDR;
9
}

Dabei wird ein Bit versetzt eingelesen, so wie es die shiftIn() Function 
von Arduino macht. Die habe ich fogendermassen abgespeckt:
1
// Liest versetzt
2
char shiftInArduino() {
3
  uint8_t value = 0;
4
  uint8_t i;
5
6
  for (i = 0; i < 8; ++i) {
7
    digitalWrite(Clock, true); // <--- beachten
8
    value |= digitalRead(DataIn) << (7 - i);
9
    digitalWrite(Clock, false);
10
  }
11
  return value;
12
}

Folgende Funktion arbeitet perfekt. Man beachte dabei das Schreiben von 
Clock.
1
// arbeitet korrekt
2
char shiftIn() {
3
  uint8_t value = 0;
4
  uint8_t i;
5
6
  for (i = 0; i < 8; ++i) {
7
    value |= digitalRead(DataIn) << (7 - i);
8
    digitalWrite(Clock, true); // <--- beachten
9
    digitalWrite(Clock, false);
10
  }
11
  return value;
12
}

Geht dies mit USI auch ?

Im Anhang noch die ganze Source.

von Stefan ⛄ F. (stefanus)


Lesenswert?

Mathias schrieb:
> Geht dies mit USI auch ?

Ja schon, aber es wird dir im Vergleich zu deiner Bitbanging Methode 
kaum Vorteile bringen.

Ich würde allerdings digitalWrite() und digitalRead() durch direkte 
Port-Zugriffe ersetzen, das bringt eine ganze Menge:
1
#define CLOCK_HIGH    PORTB |= (1<<7)    // PB7 Arduino Pin 16 HIGH
2
#define CLOCK_LOW     PORTB &= ~(1<<7)   // PB7 Arduino Pin 16 LOW
3
#define READ_IN       (PINB & (1<<5))    // PB5 Arduino Pin 14

Die Bits würde ich so zusammen sammeln:
1
for (i = 0; i < 8; ++i) 
2
{
3
    value = value << 1;
4
    if (READ_IN) // if input is HIGH
5
    {
6
        value |= 1;
7
    }
8
    CLOCK_HIGH;
9
    CLOCK_LOW;
10
}

: Bearbeitet durch User
von Thomas W. (diddl)


Lesenswert?

Stefan ⛄ F. schrieb:
> Die Bits würde ich so zusammen sammeln:
> for (i = 0; i < 8; ++i)
> {
>     value = value << 1;
>     if (READ_IN) // if input is HIGH
>     {
>         value |= 1;
>     }
>     CLOCK_HIGH;
>     CLOCK_LOW;
> }

Sehr schön optimiert.
Der GCC macht daraus einen sehr effizienten Code.

Das erste Shift kann man sich auch noch sparen.
Dann muss man allerdings auf for(;;) verzichten.

von Stefan ⛄ F. (stefanus)


Lesenswert?

Thomas W. schrieb:
> Sehr schön optimiert.
> Der GCC macht daraus einen sehr effizienten Code.

Um das zu wissen, muss man allerdings leider ab und zu mal den 
generierten Assembler-Code lesen.

von Mathias (Gast)


Lesenswert?

Danke erst mal.

>Ich würde allerdings digitalWrite() und digitalRead() durch direkte
>Port-Zugriffe ersetzen, das bringt eine ganze Menge:
Dies ist mir bekannt, diese beiden haben sehr viel Overhead.
In diesem Beispiel ging es nur um einen Muster-Code.


>Mathias schrieb:
>> Geht dies mit USI auch ?
>>
>>Ja schon, aber es wird dir im Vergleich zu deiner Bitbanging Methode
>> kaum Vorteile bringen.

Wie geht dies mit USI ?

von Stefan ⛄ F. (stefanus)


Lesenswert?

Mathias schrieb:
> Wie geht dies mit USI ?

Steht im Datenblatt des Mikrocontrollers. Aber sei gewarnt, die USI 
Schnittstelle ist doof, die benutzt man nur wenn man muss.

von Ingo (Gast)


Lesenswert?

Mathias schrieb:
> Wie geht dies mit USI ?
Ich habe da mal was ausgegraben:
1
uint8_t Usi_Data ( uint8_t Data )
2
{
3
  USIDR = Data;
4
  USISR |= (1<<USIOIF);
5
  while(!(USISR & (1<<USIOIF))){
6
    USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
7
  }
8
  return USIDR;
9
}
Setzt voraus, dass die USI-Pins als Ausgang geschaltet sind.

von Mathias (Gast)


Lesenswert?

Ingo schrieb:
> Mathias schrieb:
>> Wie geht dies mit USI ?
> Ich habe da mal was ausgegraben:
1
uint8_t Usi_Data ( uint8_t Data )
2
 {
3
   USIDR = Data;
4
   USISR |= (1<<USIOIF);
5
   while(!(USISR & (1<<USIOIF))){
6
     USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
7
   }
8
   return USIDR;
9
 }
> Setzt voraus, dass die USI-Pins als Ausgang geschaltet sind.

Dies ist der gleiche Code, wie von mir, aus dem
1
USIDR = Data;

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]
  • [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.