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


von Adrian E. (ahsd)


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.

1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
// 74HC595 am USI Port, LEDs an den parallel Ausgängen
5
6
#define SCK  PB7      // USI
7
#define DO  PB6      //
8
#define DI  PB5      //
9
#define RCLK PB4    // 74HC595 Storage Register Clock
10
11
#define TEST 0xAA    // Testmuster
12
13
int main( void )
14
{
15
  PORTB &= (1 << SCK) | (1 << DO) | (1 << DI) | (1 << RCLK);    // Outputs auf low
16
  DDRB |= (1 << SCK) | (1 << DO) | (1 << DI) | (1 << RCLK);    // SCK, DO, DI und PB4 (RCLK) auf Ausgang
17
  
18
  _delay_ms(200);
19
  
20
  USIDR = TEST;
21
  USISR |= (1 << USIOIF);      // Counter Overflow Zurücksetzen
22
  USICR = (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);
23
  
24
  while(!(USISR & (1 << USIOIF)))  // Takten bis zum Counter Overflow
25
    {
26
      USICR |= (1 << USITC);    // Diese Schleife taktet die USI Clock
27
    }
28
    
29
  PORTB |= (1 << RCLK);        // Byte ins Ausgangsregister des 74HC595 schieben
30
  PORTB &= ~(1 << RCLK);        //
31
  
32
  
33
  return 0;
34
}

von Takao K. (takao_k) Benutzerseite


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)


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)


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:

1
// USING 74HC595 with USI Port on Attiny
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
// Mikrocontroller: Attiny2313
7
// 74HC595 on USI Port, 8 LEDs on Shiftregister Outputs, /RESET (SRCLR) on +
8
9
#define SCK   PB7      // USI Clock
10
#define DO    PB6      // USI Serial Out
11
#define RCLK  PB5      // 74HC595 Storage Register Clock
12
#define OE    PB4      // 74HC595 Output Enable
13
14
15
// parameters for testing purposes:
16
#define TEST  0b11110001  // test byte to be sent
17
18
19
void USI_init(void);
20
void USI_send(uint8_t);
21
22
int main( void )
23
{
24
  _delay_ms(200);      // This delay was only for my measuring purpose
25
  
26
  USI_init();  
27
  USI_send(TEST);
28
  
29
  return 0;
30
}
31
32
void USI_init(void)
33
{
34
  PORTB &= ~(1 << SCK) | (1 << DO) | (1 << RCLK);              // Outputs low
35
  PORTB |= (1 << OE);                                          // Output Enable OFF
36
  DDRB |= (1 << SCK) | (1 << DO) | (1 << RCLK) | (1 << OE);    // SCK, DO, DI, RCLK und OE as Output
37
  USICR = (1 << USIWM0) | (1 << USICS1) | (1 << USICLK);       // Three-Wire-Mode / Software Clock / Clocksource => USITC
38
  
39
  return;
40
}
41
42
void USI_send(uint8_t Byte)
43
{
44
  USIDR = Byte;
45
  USISR |= (1 << USIOIF);                      // reset Counter-Overflow
46
  
47
  
48
  while(!(USISR & (1 << USIOIF)))              // clocking until Counter-Overflow = true
49
    {
50
      USICR |= (1 << USITC);
51
    }
52
  
53
  PORTB |= (1 << RCLK);                        // sending byte to Outputregister of 74HC595
54
  PORTB &= ~(1 << RCLK);                       //
55
  
56
  PORTB &= ~(1 << OE);                         // Output Enable low (= ON)
57
  
58
  return;
59
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.