Hallo Leute,
ich verzweifel gerade mit meinem µC ATtiny84.
Ich habe eine Datenübertragung zwischen dem µC und drei DA-Wandlern
(nacheinander).
(USI Transfer, two-wire-mode, zwei Byte werden übertragen)
Habe zwei Platinen damit aufgebaut --> alles funktioniert
Diese habe ich leider nicht mehr, sodass ich mir nun zwei neue Platinen
gelötet habe. Also Bauteile bestellt, neu gelötet, Programm drauf und
nix geht mehr.
Nach drei tagen intensiver Fehlersuche bin ich nun auf folgendes
gestoßen:
Die Übertragung beginnt und sobald auf der Datenleitung eine 0 auf eine
1 folgt bricht die Datenübertragung ab, und zwar an folgender Stelle:
Ich benutze die App-Note von Atmel (AVR310 - Using the USI module as a
TWI Master) mit dem zugehörigen Code, jedoch modifiziert, weil der Code
für den IAR ist und ich den AVR-GCC nutze.
Hier ein paar Ausschnitte:
(1<<USIWM1)|(0<<USIWM0)|// Set USI in Two-wire mode.
50
(1<<USICS1)|(1<<USICS0)|(1<<USICLK)|// Software clock strobe as source.
51
(1<<USITC);// Toggle Clock Port.
52
do
53
{
54
_delay_us(4);
55
USICR=temp;// Generate negative SCL edge.
56
57
_delay_us(6);
58
USICR=temp;// Generate positve SCL edge.
59
60
while(!(PIN_USI&(1<<PIN_USI_SCL)));// Wait for SCL to go high.
61
62
}while(!(USISR&(1<<USIOIF)));// Check for transfer complete.
63
64
65
returntemp;// Return the data from the USIDR
66
}
67
[...]
Sobald im Datenbyte eine 0 auf eine 1 folgt wird die Clock nicht mehr
released:
SDA: 0000 010-------Abbruch
SDA: 0001 0---------Abbruch
SDA: 0011 110-------Abbruch
Der µC steckt in folgender Schleife fest:
1
// in der USI_TWI_Master_Transfer:
2
do
3
{
4
_delay_us(4);
5
USICR=temp;// Generate negative SCL edge.
6
7
_delay_us(6);
8
USICR=temp;// Generate positve SCL edge.
9
10
while(!(PIN_USI&(1<<PIN_USI_SCL)));// Wait for SCL to go high.
11
//^^^^^^^^ hier steckt er fest, weil die Clock nicht mehr "1" wird
12
// Generate positive SCL edge scheint nicht mehr zu funktionieren
13
14
}while(!(USISR&(1<<USIOIF)));// Check for transfer complete.
Anmerkung:
Der gleiche Code (unverändert) funktionierte in den ersten beiden
Platinen einwandfrei.
Die Platinen sind aus der selben Bestellung. Die Bauteile sind
weitestgehend aus der selben Bestellung.
Der Prozessor ist aus einer anderen Bestellung aber der gleiche Typ!
(ATtiny84)
Habe aber auch schon einen tiny24 probiert, gleicher Fehler.
Ich kann mir das nicht erklären.
Hi
>Ich benutze die App-Note von Atmel (AVR310 - Using the USI module as a>TWI Master) mit dem zugehörigen Code, jedoch modifiziert, weil der Code>für den IAR ist und ich den AVR-GCC nutze.
Vergleiche z.b. mal den Code von
'unsigned char USI_TWI_Master_Transfer( unsigned char temp )'
mit dem Original. Fällt dir da etwas auf?
MfG Spess
while(!(PIN_USI&(1<<PIN_USI_SCL)));// Wait for SCL to go high.
6
__delay_cycles(T4_TWI);
7
USICR=temp;// Generate negative SCL edge.
8
}while(!(USISR&(1<<USIOIF)));// Check for transfer complete.
"Meine Version":
1
do
2
{
3
_delay_us(4);
4
USICR=temp;// Generate negative SCL edge.
5
6
_delay_us(6);
7
USICR=temp;// Generate positve SCL edge.
8
9
while(!(PIN_USI&(1<<PIN_USI_SCL)));// Wait for SCL to go high.
Wie schon gesagt, habe ich den Code modifiziert. U.a. auch deshalb weil
in meinem Fall bei der Kommunikation mit dem DA-Wandler das Datenwort
auf der negativen Flanke ausgelesen wird und auch der Released Pegel bei
"1" liegt.
Vor allem aber, hat genau dieser Code ja schon einwandfrei funktioniert.
Die Frage ist nur: Warum hat er schon mal funktioniert? Warum ist dieser
Fehler auf den vorherigen Platinen (es waren die Gleichen) nicht
aufgetreten?
Hi
>Wie schon gesagt, habe ich den Code modifiziert. U.a. auch deshalb weil>in meinem Fall bei der Kommunikation mit dem DA-Wandler das Datenwort>auf der negativen Flanke ausgelesen wird und auch der Released Pegel bei>"1" liegt.
Für TWI (I2C) gibt es eigentlich eindeutige Festlegungen.
MfG Spess
Hi
>Ja, das schon, aber der DA-Wandler benutzt kein TWI sondern ein eigenes>Protokoll, daher die Abwandlung.
Dann würde ich es komplett in Software machen.
MfG Spess
M.B. schrieb:> So war der Plan
Warum setzt du den denn dann nicht um und ärgerst dich stattdessen
mit dem (völlig unangebrachten) two-wire-mode herum?
Hier mal eine USI, die als SPI master in meinem tiny230-Projekt
werkelt:
Jörg Wunsch schrieb:> Warum setzt du den denn dann nicht um und ärgerst dich stattdessen> mit dem (völlig unangebrachten) two-wire-mode herum?
Weil ich keine Daten zurück bekomme, also nur sende, und daher den
TwoWireMode gewählt habe.
Außerdem gibt es Vorgaben, wie Datenübernahme bei "Falling Edge", Zwei
Byte werden übertragen, zwischen den zwei byte muss die Clock positiv
bleiben. Und nach Datenblattrecherche hielt ich dieses Vorgehen für
angebracht. Zudem lief es ja und auf Nachfrage immer noch einwandfrei
auf den beiden ersten Platinen.
Jetzt wo ich die selber brauche funktioniert es nicht mehr.
Da die Platinen die Selben (zumindest aus der gleichen Fertigung) sind,
der Code der Selbe ist, versuche ich jetzt einen Fehler zu finden, der
scheinbar, aus welchem Grund auch immer, vorher nicht aufgetreten ist.
Ich hoffte vielleicht eine Erklärung im µC zu finden. Vielleicht durch
eine neue Revision, Änderungen an der Schnittstelle, oder so. Aber im
aktuellen Datenblatt kann ich nichts entdecken.
Vielleicht hatte jemand anders ähnliche Erfahrung und kann mir einen
Tipp geben (so war meine Intention). Vielleicht der externe Push-up
Widerstand der zu gering oder zu groß ist oder sowas in der Richtung.
Hi
>Weil ich keine Daten zurück bekomme, also nur sende, und daher den
TwoWireMode gewählt habe.
Das sind aber schon elektrisch zwei völlig verschiede Busse.
Das Three-Wire-Interface funktioniert für 'nur Senden', auch mit 2
Leitungen.
>Jetzt wo ich die selber brauche funktioniert es nicht mehr.
Ich tippe eher darauf, das es beim 1.Mal zufällig funktioniert hat. Hast
du externe Pull-Ups?
MfG Spess
M.B. schrieb:> Weil ich keine Daten zurück bekomme, also nur sende, und daher den> TwoWireMode gewählt habe.
Auch im two-wire-mode kann man Daten zurücklesen. ;-) Selbiger hat
halt nur einen definierten Prozess, bei dem es dem slave möglich
ist, dem master zuzurufen: "halt mal!, ich bin noch nicht so weit!".
Beim SPI (aka. three-wire-mode) gibt es dieses feature jedoch nicht,
da bestimmt immer der master das genaue timing. (Daher ist ein
Controller auch ein miserabler SPI slave. Brauchbare SPI slaves
kann man eigentlich nur in Hardware gießen.)
Ob du auch Daten zurücklesen willst oder nicht, spielt dabei überhaupt
keine Geige.
> Außerdem gibt es Vorgaben, wie Datenübernahme bei "Falling Edge", Zwei> Byte werden übertragen, zwischen den zwei byte muss die Clock positiv> bleiben.
Alles kein Thema, ist halt SPI mode 1 statt des (etwas gebräuchlicheren)
mode 0. Die USCK-Leitung legst du bei der Programmierung der USI ja
ohnehin selbst in Software fest mit dem USICLK-Bit in USICR.
Mein Codebeispiel oben bezog sich in der Tat auf einen SPI mode 0, aber
das solltest du trotzdem einfach abändern können.
Hallo M.B.,
was macht dein USI-Master?
Bin gerade selber dabei, einen MMA7455 über I2C mit einem Tiny84
auszulesen und wäre über einen funktionierenden Code sehr dankbar.
Dein Problem hat vielleicht etwas mit Clock-Stretching zu tun, der Slave
hält wenn er Zeitprobleme hat SCL auf Null, bis er fertig ist. Das mach
er normalerweise aber nicht mitten in der Übertragung.
Gruß
Hallo zusammen,
habe es mittlerweile geschafft, den MMA7455 über den I2C mit dem Tiny84
auszulesen, wer am Code interessiert ist, einfach kurz schreiben.
Gruß