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
Ja durch setzten des USITC bits erzeuge ich meinen Takt, aber aus SDA kommt nichts. mfg Matthias
Das Schieberegister muss nochmal separat getaktet werden. Funktioniert mit folgender Anweisung: USICR |= (1<<USICLK); // Shift USIDR to next Bit
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?
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 |
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 |
Hi Nur mal so: Was stört dich eigentlich an dem Beispielcode aus dem Datenblatt? MfG Spess
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 |
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 | } |
Ü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?
Kann sein das dass Schieberegister erst Daten ausgiebt, wenn die Startbedingung korrekt abgewickelt ist?
Hi Der Ausgang ist PB6! Und der Pin ist in deinem Programm Eingang . MfG Spess
Nein, bin mir sicher. Die Startbedingung ist nur für deine Slaves von Bedeutung. Hast es schon versucht mit PORTs auf High setzen?
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
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
HI >Hat nich jemand eine Idee? (hab den Attiny auch schon getauscht) Beitrag "Re: Attiny2313 USI Schieberegister will nicht" MfG Spess
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.