Hallo,
Ich brauche 4 Schieberegister (HCT595) hintereinandergeschaltet an
einem ATTiny2313.
Um etwas mehr Geschwindigkeit herauszuholen hab ich die an den USI Port
angeschlossen, somit spare ich mir die Bit-Shifts und lass die vom USI
ausführen.
Das Atmel-Datenblatt (Seite 141) schlägt für eine möglichst schnelle
Übertragung eine ASM-Sequenz vor die mit:
1 | out USIDR,r16
|
2 | ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
|
3 | ldi r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
|
4 | out USICR,r16 ; MSB
|
5 | out USICR,r17
|
6 | out USICR,r16
|
7 | out USICR,r17
|
8 | out USICR,r16
|
9 | ...
|
das Takt-Signal erzeugt und gleichzeitig den internen Counter richtig
mitlaufen lässt.
Den Counter brauche ich nicht, also habe ich das in c (avr-gcc) so
umgesetzt:
1 | /* init: USICR = _BV(USIWM0)|_BV(USICS1)|_BV(USICLK); */
|
2 |
|
3 | void usi_send_byte(uint8_t d) {
|
4 | USIDR=d;
|
5 | USICR |= _BV(USITC);
|
6 | USICR |= _BV(USITC);
|
7 | USICR |= _BV(USITC);
|
8 | USICR |= _BV(USITC);
|
9 | ...(16 Mal)
|
10 | }
|
was auch in brauchbaren ASM-Code übersetzt wird:
1 | out 47-0x20,r24
|
2 | sbi 45-0x20,0
|
3 | sbi 45-0x20,0
|
4 | ...
|
Nun die Frage: geht das evtl. noch schneller? Bei 8MHz Takt messe ich
gerade mal 200KHz auf der Datenleitung für
while(1) usi_send_byte(0x55)
Hab ich mich vielleicht bei der Initialisierung des USI vertan, kann
man den Takt evtl. direkt erzeugen lassen anstatt die Clock-Leitung per
Software zu togglen?
Oder passt das schon und mein billiges Multimeter hat sich bei der
Frequenz vermessen (Soll angeblich bis 5MHz messen können)?
Danke,
/Ernst