Forum: Mikrocontroller und Digitale Elektronik Attiny2313 USI Schieberegister will nicht


von Matthias (Gast)


Lesenswert?

Hallo,

ich habe es entlich geschafft meinen USI als TWI zu initialisieren,
aber ich bekomme keine Daten raus.

Was muss ich setzten, damit das Schieberegister seinen Inhalt ausgiebt?


mfg
Matthias

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Das USITC-Bit in USICR 8x setzen.

von Matthias (Gast)


Lesenswert?

Ja durch setzten des USITC bits erzeuge ich meinen Takt, aber aus SDA 
kommt nichts.

mfg
Matthias

von Markus (Gast)


Lesenswert?

Das Schieberegister muss nochmal separat getaktet werden.
Funktioniert mit folgender Anweisung:


USICR |= (1<<USICLK);  // Shift USIDR to next Bit

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Markus schrieb:
> Das Schieberegister muss nochmal separat getaktet werden.

Nö, muss es nicht.

Matthias schrieb:
> aber aus SDA
> kommt nichts.

Ist SDA als Ausgang geschaltet? das betreffende Bit in DDRn muss gesetzt 
sein. Und Du musst natürlich vorher Daten ungleich 0`und ungleich 255 in 
USIDR eintragen, damit Du am Ausgang was siehst. Siehst Du die 
Clockpulse an SCL?

von Matthias (Gast)


Lesenswert?

Ich setzt jetzt USICLK gleich mit dem Takt, müsste also ein 
durchgehender Datenstrom sein. Es kommt aber nichts, SDA ist trotz pull 
up immer Low?

Auszug:
1
 
2
    nop
3
    sbi USICR, 1  ;USICLK
4
    nop
5
    sbi USICR, 0  ;USITC für Takt

von Matthias (Gast)


Lesenswert?

Hier mein derzeitiges versuchs asm, Takt kommt ohne Probleme.

Kommentare stimmen oft nicht!
1
include "tn2313def.inc"
2
3
4
5
6
.def temp1 = r16
7
.def temp2 = r17
8
.def temp3 = r18
9
10
.org 0x0000
11
    rjmp main
12
13
.org 0x000D
14
    rjmp timer0compare64
15
16
.org 0x000E
17
    rjmp timer0compare128
18
19
20
21
22
main:
23
24
    ldi temp1, LOW(RAMEND)
25
    out SPL, temp1
26
27
    ldi  temp1, 0b00100000
28
    out DDRD, temp1
29
30
    ldi temp1, 0b10100000
31
    out DDRB, temp1
32
33
    ldi temp1, 0b10000001
34
    out TCCR0B, temp1    ;Timer 0 Voreiler 1
35
    
36
    ldi temp1, 0b01000000
37
    out OCR0A, temp1    ;Timer 0 Compare 128
38
  
39
    ldi temp1, 0b10000000
40
    out OCR0B, temp1    ;Timer 0 Compare 128
41
42
    ldi temp1, 0b00000111
43
    out TIMSK, temp1    ;Timer 0 Interrupt enable
44
45
46
    ldi temp1, 0b00101010
47
    out USICR, temp1
48
    
49
  
50
  ;ldi temp1, 0b10101010
51
  ;  out USIDR, temp1
52
        ; Interrupts aktivieren
53
54
55
ldi r16, 0b10101010
56
out USIDR,r16
57
58
ldi r16,(0<<USISIF)|(1<<USIWM1)|(1<<USICS1)|(0<<USITC)|(1<<USICLK)
59
 out USICR,r16 
60
 
61
 sei
62
63
64
loop:
65
 
66
67
ldi r16, 0b10101010
68
out USIDR,r16
69
70
rjmp loop
71
72
73
74
timer0compare64:
75
76
    cbi PORTD, 5  
77
    nop
78
    sbi USICR, 1  ;USICLK
79
    nop
80
    sbi USICR, 0  ;USITC für Takt
81
        
82
83
84
  
85
    reti
86
87
timer0compare128:
88
89
    sbi PORTD,5 
90
    nop
91
    sbi USICR, 1
92
    nop
93
    sbi USICR, 0
94
95
96
    ldi temp1, 0b00000000
97
    out TCNT0, temp1
98
    reti

von Spess53 (Gast)


Lesenswert?

Hi

Nur mal so: Was stört dich eigentlich an dem Beispielcode aus dem 
Datenblatt?

MfG Spess

von Matthias (Gast)


Lesenswert?

Ich finde nur das für SPI und da tut sich nichts
1
SPITransfer:
2
out USIDR,r16
3
ldi r16,(1<<USIOIF)
4
out USISR,r16
5
ldi r16,(1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC)
6
SPITransfer_loop:
7
out USICR,r16
8
sbis USISR,USIOIF
9
rjmp SPITransfer_loop
10
in r16,USIDR
11
ret

von Markus (Gast)


Lesenswert?

Ich hab mich mit AVR Assembler noch nicht beschäftigt aber ich kann dir 
meine Funktionen in C als Beispiel geben, evtl kannst du sie ja in 
Assembler umschreiben. Habe damit schon ein mittleres Projekt realisiert 
und hat einwandfrei geklappt.
Die erste Funktion ist zur Initialierung.
Die zweite Funktion schickt 8 Bits auf die SDA Leitung.
Start und Stop Bedingung hab ich in einer anderen Funktion realisiert.
Das USIDR befülle ich vor dem Aufruf der zweiten Funktion mit Daten.
1
void TWI_Init()
2
{
3
4
 USICR = (0<<USISIE) | (0<<USIOIE) | (1<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0);  // Enable Two Wire Mode
5
6
 DDRB |= (1<<SDA) | (1<<SCL);      //  Enable Output Driver
7
8
9
 PORTB |= (1<<SDA) | (1<<SCL);      //******************************** 
10
 USISR |= (1<<7);            // Set SDA and SCL to High
11
 USIDR = 0xff;              //********************************
12
13
 
14
15
}
16
17
18
unsigned char USI_TWI_Master_Transfer(int NumOfBits)
19
{
20
21
  
22
23
  USISR = 0x80;     // Init USISR 
24
25
26
27
  for(int i=0; i<NumOfBits; i++)
28
  {
29
30
    if(USISR & 0x80)    
31
    { USISR |= (1<<7);}
32
33
    PORTB |= (1<<SCL);    //**************************************
34
    while(!(PINB & 0x80))  // Release and wait for SCL to go high
35
    { ;}          //**************************************
36
    
37
38
    _delay_us(10);      // Wait a TWI high period
39
  
40
41
    PORTB &= ~(1<<SCL);    //**************************************
42
    while((PINB & 0x80))  // SCL to Low and wait until done
43
    { ;}          //**************************************
44
45
  
46
    USICR |= (1<<USICLK);  // Shift USIDR to next Bit
47
  
48
    
49
    _delay_us(10);      // Wait a TWI low period
50
51
52
    
53
54
55
  }
56
57
  // All Data shifted???
58
    
59
60
61
return 0x00;
62
}

von Markus (Gast)


Lesenswert?

Übrigens, musst du PORTB.5(SDA) und PORTB.7(SCL) auch auf High schalten 
sonst werden die Busleitungen dauerhaft auf Low gezogen.
SCL wird zusätzlich auch immer auf Low gezogen wenn eine Startbedingung 
vorkommt.
Woher weißt du, dass SDA immer auf Low ist? Hast du LEDs dran oder ein 
Oszi?

von Matthias (Gast)


Lesenswert?

Oszi!

von Matthias (Gast)


Lesenswert?

Kann sein das dass Schieberegister erst Daten ausgiebt, wenn die 
Startbedingung korrekt abgewickelt ist?

von Spess53 (Gast)


Lesenswert?

Hi

Der Ausgang ist PB6! Und der Pin ist in deinem Programm Eingang .

MfG Spess

von Markus (Gast)


Lesenswert?

Nein, bin mir sicher.
Die Startbedingung ist nur für deine Slaves von Bedeutung.
Hast es schon versucht mit PORTs auf High setzen?

von Matthias (Gast)


Lesenswert?

Einzeln mit sbi/cbi kann ich alles setzten.
Was ist mit PB6? ist bei TWI nicht Verwendet.

Kann das c prog leider nicht zu 100% umsetzten, da ich es nicht kann

von Matthias (Gast)


Lesenswert?

Ich habe schon zick varianten mit USITC USICLK versucht, aber es kommt 
nichts aus dem Schieberegister.

Hat nich jemand eine Idee? (hab den Attiny auch schon getauscht)

mfg
Matthias

von Spess53 (Gast)


Lesenswert?

HI

>Hat nich jemand eine Idee? (hab den Attiny auch schon getauscht)

Beitrag "Re: Attiny2313 USI Schieberegister will nicht"

MfG Spess

von Markus (Gast)


Lesenswert?

@Spess also ich seh nicht wo er PB6 verwendet hat.

@Matthias Am Controller selbst liegt es nicht. Aber es stimmt schon, den 
TWI beim AVR zu implementiern ist ein bisschen umständlich aber machbar.

von Spess53 (Gast)


Lesenswert?

Hi

>@Spess also ich seh nicht wo er PB6 verwendet hat.

USI und Schieberegister haben bei mir SPI assoziiert.

Was in DDRB steht ist bei TWI egal. Die Einstellung wird vom TWI 
überschrieben. Allerdings geht bei TWI ohne Pull-Up-Widerstände nichts. 
SCL und SDA können die Leitungen nur auf L ziehen, aber kein H ausgeben.

MfG Spess

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.