Forum: Mikrocontroller und Digitale Elektronik 74HC595 an USI (Attiny2313)


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 Adrian E. (ahsd)


Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich habe mir jetzt den gesamten Tag die Zähne an USI auf dem Attiny2313 
ausgebissen und muss jetzt wohl doch wieder das Forum Fragen.
Ich habe mich schon durch sämtliche englischsprachigen Foren gewühlt und 
das Kapitel im Datenblatt mehrfach durchgelesen.

Zum Beispiel ist mir unklar, warum in vielen Beispielen in der "Clock 
Schleife" immer wieder USICS1 und USICLK gesetzt werden, bleiben die 
nicht an?

Ich habe einen 74HC595 an einem Attiny2313. An den Ausgängen des 74HC595 
sind LEDs gegen GND. Die Verbindungen sind:

t2313    -   74HC595
SCK --------- SRCLK (Shiftregister Clock)
DO  --------- SER   (Serieller Input)
PB4 --------- RCLK  (Ausgangsregister Clock)

Außer, dass die LEDs beim Einschalten manchmal kurz aufleuchten, 
passiert gar nichts.

#include <avr/io.h>
#include <util/delay.h>

// 74HC595 am USI Port, LEDs an den parallel Ausgängen

#define SCK  PB7      // USI
#define DO  PB6      //
#define DI  PB5      //
#define RCLK PB4    // 74HC595 Storage Register Clock

#define TEST 0xAA    // Testmuster

int main( void )
{
  PORTB &= (1 << SCK) | (1 << DO) | (1 << DI) | (1 << RCLK);    // Outputs auf low
  DDRB |= (1 << SCK) | (1 << DO) | (1 << DI) | (1 << RCLK);    // SCK, DO, DI und PB4 (RCLK) auf Ausgang
  
  _delay_ms(200);
  
  USIDR = TEST;
  USISR |= (1 << USIOIF);      // Counter Overflow Zurücksetzen
  USICR = (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
  
  while(!(USISR & (1 << USIOIF)))  // Takten bis zum Counter Overflow
    {
      USICR |= (1 << USITC);    // Diese Schleife taktet die USI Clock
    }
    
  PORTB |= (1 << RCLK);        // Byte ins Ausgangsregister des 74HC595 schieben
  PORTB &= ~(1 << RCLK);        //
  
  
  return 0;
}

von Takao K. (takao_k) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Datenblatt des 74HC595 lesen.

/OE - auf 0 wenn die Ausgaenge an sein sollen
D - serial data
SCLK - shifting clock
RCLK - register clock
/RESET - immer auf 1 ausser das Register soll zurueckgesetzt werden


Der 74HC164 hat kein extra Register.

Beim 74HC595 ist die Idee dass sich die Ausgaenge zunaechst nicht 
aendern sollen. Die Daten werden eingetaktet, und dann wird mit einem 
Impuls an RCLK das gesamte Register geladen.

von Adrian E. (ahsd)


Bewertung
0 lesenswert
nicht lesenswert
DANKE! Nachdem ich ein paar Stunden gebraucht hatte um die primitive USI 
Schnittstelle zu kapieren, hatte ich ein Brett vorm Kopf, was den 
74HC595 anging. OE war zwar schon auf GND, aber der /RESET Pin wars! :)

von Adrian E. (ahsd)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der obige Code enthielt noch einen Fehler (Es kamen nur 7 Takte statt 
8.) Deswegen fürs Archiv noch den korrekten Code:

THE ABOVE CODE HAD AN ERROR. THIS ONE WORKS:

// USING 74HC595 with USI Port on Attiny

#include <avr/io.h>
#include <util/delay.h>

// Mikrocontroller: Attiny2313
// 74HC595 on USI Port, 8 LEDs on Shiftregister Outputs, /RESET (SRCLR) on +

#define SCK   PB7      // USI Clock
#define DO    PB6      // USI Serial Out
#define RCLK  PB5      // 74HC595 Storage Register Clock
#define OE    PB4      // 74HC595 Output Enable


// parameters for testing purposes:
#define TEST  0b11110001  // test byte to be sent


void USI_init(void);
void USI_send(uint8_t);

int main( void )
{
  _delay_ms(200);      // This delay was only for my measuring purpose
  
  USI_init();  
  USI_send(TEST);
  
  return 0;
}

void USI_init(void)
{
  PORTB &= ~(1 << SCK) | (1 << DO) | (1 << RCLK);              // Outputs low
  PORTB |= (1 << OE);                                          // Output Enable OFF
  DDRB |= (1 << SCK) | (1 << DO) | (1 << RCLK) | (1 << OE);    // SCK, DO, DI, RCLK und OE as Output
  USICR = (1 << USIWM0) | (1 << USICS1) | (1 << USICLK);       // Three-Wire-Mode / Software Clock / Clocksource => USITC
  
  return;
}

void USI_send(uint8_t Byte)
{
  USIDR = Byte;
  USISR |= (1 << USIOIF);                      // reset Counter-Overflow
  
  
  while(!(USISR & (1 << USIOIF)))              // clocking until Counter-Overflow = true
    {
      USICR |= (1 << USITC);
    }
  
  PORTB |= (1 << RCLK);                        // sending byte to Outputregister of 74HC595
  PORTB &= ~(1 << RCLK);                       //
  
  PORTB &= ~(1 << OE);                         // Output Enable low (= ON)
  
  return;
}

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.