Attiny2313 USI Schieberegister will nicht

(Firma: TravelRec.) Persönliche Seite #2037831
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?
Gast #2037837
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
Gast #2037842
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
Gast #2037868
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
Gast #2037874
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
}
Gast #2037887
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?
Gast #2038096
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren