Datum:
Angehängte Dateien:Manchmal will man mehrere MC verbinden, ohne großen Aufwand. Das hier ist ein sehr einfacher Bus, sogar ein ATtiny13 kann ihn implementieren. Der CPU-Takt muß auch nicht quarzstabil sein, ein Fehler von +-15% ist zulässig. Ich nenne ihn 124Bus, weil die Pulse 1, 2 oder 4 Zeiten lang sind. Die Pulse haben folgende Bedeutung: 1 * T: 0-Bit 2 * T: 1-Bit 4 * T: Synchronisationsbit Es wird nur ein Pin benötigt. Man kann aber auch 2 Pins nehmen, wenn man z.B. die MCs über Optokoppler galvanisch trennen will. Es ist ein Single-Master Bus. Nimmt man das erste Byte als Adresse, können 256 Slaves angeschlossen werden. Empfang und Senden erfolgen bequem im Hintergrund über Interrupts. Das Main muß also nur die Empfangspakete auswerten und die Sendepakete in den Puffer stellen. Die Bitrate hängt davon ab, wieviel Zeit andere Interrupts benötigen. Das Beispiel benutzt 10kHz bei 8MHz CPU-Takt. 50kHz habe ich auch erfolgreich getestet, aber für andere Interrupts ist dann kaum Zeit übrig. Die Beispiele sind für den AVR geschrieben, es gehen aber auch beliebig andere MCs. Zum Test wurde ein STK500 mit 3 AVRs verwendet. Für den ATmega48 gibt es noch ein 2.Beispiel, wo der Timer für den 124Bus noch gleichzeitig eine PWM macht. Beim ATtiny261 habe ich auch eine Fallgrube entdeckt. Peter Dannegger
Datum:
Hallo Peter, danke für das Teilen Deines Codes. Ich finde Deine Idee, das mit dem PWM Modus zu "modulieren" sehr interessant. Vielleicht sollte ich meinen Bus (Autopilot, siehe suart) auch mal darauf umstellen. Das spart die Hälfte aller Interrupts ;-) weil man nicht auschalten braucht... Schöne Grüße, Clemens
Datum:
Hallo Peter, mit der Kommunikation über einen Pin habe ich mich auch schon beschäftigt: Beitrag "Re: Unidirektionale Datenübertragung, 1 Leitung, kein Quarz" Gruß, chris
Datum:
Peter Dannegger schrieb: > Ich nenne ihn 124Bus, weil die Pulse 1, 2 oder 4 Zeiten lang sind. > Die Pulse haben folgende Bedeutung: > 1 * T: 0-Bit > 2 * T: 1-Bit > 4 * T: Synchronisationsbit Habe so etwas Ähnliches auch als Debugschnittstelle laufen, ist aber eher ein 123-Bus, da das Sync-Bit 3 0-Bit-Längen entspricht ;-)
Datum:
Knut Ballhause schrieb: > Habe so etwas Ähnliches auch als Debugschnittstelle laufen, ist aber > eher ein 123-Bus, da das Sync-Bit 3 0-Bit-Längen entspricht ;-) Das verringert aber die erlaubte Toleranz der Taktfrequenz. Ich habe deshalb auch die Schwelle auf die relative Mitte (1,4) gelegt und nicht auf die arithmetische Mitte. Peter
Datum:
Bei meinem BUS-Protokoll war das Entwicklungsziel eine möglichst schnelle Datenübertragung zu realisieren. Ursprünglich wollte ich 1Mbit/s erreichen. Ich habe ein Ping-Pong-Verfahren zwischen den zwei Prozessoren implementiert: Es wird ein Byte vom Master zum Slave gesendet und als Antwort sendet der Slave ein Byte zum Master. Damit hat man automatisch eine bidirektionale Kommunikation realisert. Die Geschwindigkeit für ein PING-PONG lag schließlich bei 10-20KHz ( bei 16 effektiv übertragenen Bits also max ca. 360KBit/s). Welche Datenrate wird bei euren Verfahren erreicht?
Datum:
So ähnlich ist der Sony Control A1 Bus (oder (S-Link) aufgebaut: 600µs, 1200µs und 2400µs Pasuse auf einer 1-Draht-Leitung. Wer also Sony-Audio-Geräte mit Control- A1-Bus hat, kann damit einen Konverter zum PC bauen und seine Geräte per PC/Notebook steuern, abfragen, usw. Blackbird
Datum:
Hallo Peter! Ich verwende deinen 124BUS und habe eine Frage. wenn ich rx_init() ausführe, wird doch der nächste Timerinterrupt auf 4*T gesetzt ( Also auf Startbit ) Wenn man nun in dem Timerinterrupt nachschaut, kann man erkennen, dass er in die Abfrage " if( rx_idx != DATA_SIZE * 8 ) // receive successful " hineingeht, und er somit meint, die Übertragung ist schon fertig. Gehe ich recht in der Annahme, oder habe ich einen kleinen Kniff übersehen? Aufgrund dessen dass der Ruhepegel bei dir immer + ist, wird ja nur das Stopbit ausgeführt, und das Startbit existiert ja eigentlich nicht, deshalb könnte ich das nicht auswirken, stimmt das? Danke Lg Manuel
Datum:
Manuel schrieb: > Wenn man nun in dem Timerinterrupt nachschaut, kann man erkennen, dass > er in die Abfrage " if( rx_idx != DATA_SIZE * 8 ) // receive successful > " hineingeht, und er somit meint, die Übertragung ist schon fertig. Nur wenn vorher genau die richtige Anzahl an Datenbits gelesen wurde, bedeutet das Sync-Bit auch das Ende des Empfangs. Ansonsten ist es eben nur ein Sync-Bit und setzt den Bitzähler zurück. Peter
Datum:
Hallo! Ok das heißt also, egal ob ein Startbit kommt oder ein Stopbit, das ist erstmal egal. Es würde rein theoretisch auch ohne gehen richtig? Ich brauche nämlich zwecks der Datenübertragung per Optokoppler ein low als Ruhezustand, dabei habe ich im Timer Interrupt einfach eine Abfrage auf Low gemacht, passt oder? Lg Manuel
Datum:
Oder wäre es besser einfach den Optokoppler gegen + als gegen Masse zu schalten? Ansonsten ist ja einiges am Programm zu ändern, dass der Ruhepegel 0 ist. Was meinst du ist besser ? Danke Lg Manuel
Datum:
Manuel schrieb: > Oder wäre es besser einfach den Optokoppler gegen + als gegen Masse zu > schalten? Ja, dem Optokopller dürfte es egal sein. Allerdings solltest Du bei einem Optokoppler 2 Leitungen benutzen, da der ja nicht bidirektional ist. Und dann ist der Ruhepegel egal, man muß nicht mehr zwischen Senden und Empfang umschalten. Peter
Datum:
Hallo! Ja ich verwende natürlich zwei! Naja der Ruhepegel ist insofern nicht egal, als dass ich mehrere Optokoppler parallel betreibe, und die somit im Ruhezustand immer Strom verbrauchen würden, würde bei einigen Parallel schon einiges ergeben, und das muss ja nicht sein. Ich habe jetzt folgendes geändert: Statt Set on Compare hab ich überall Clear on Compare. Danach die Abfrage, dass er solange ein High ist noch nicht die Interrupt deaktiviert. Zusätzlich da ich ja jetzt 2 Pins verwende, habe ich die Abfrage bei tx_init auf das warten des Pins bis es high ist weggelassen. Und ich habe eine neue variable eingeführt, um zu erkennen, ob der Timer Interrupt fürs Senden oder fürs Empfangen ist ( War ja vorher direkt per DATA_DDR abgefragt) Hab ich das einigermaßen richtig gemacht? Danke dir! Lg Manuel
Datum:
Hallo nochmal! Kann es sein, dass die Slaves es nicht mögen, wenn der Master zu schnell hintereinander sendet? Es kommen immer viele Timeouts zustande, wenn ich den Master direkt nach dem empfangen & abarbeiten senden lasse, wenn ich allerdings 100ms Abstand lasse, geht es besser. Trotz dessen gibt es noch häufig Time Outs, wie ist das zu erklären? Danke! Lg Manuel
Datum:
Hallo nochmal! Ich habe mittlerweile herausgefunden, dass die Slaves immer senden ( also antworten ) Der Master aber auf einmal ein Timeout einleitet. Woran das liegt ist mir schleierhaft, das Programm ist genau deines! Hast du eine Idee wie das sein kann ? Lg Manuel
Datum:
Vielleicht braucht eine andere Routine sehr viel Zeit oder blockiert die Interrupts. Geh mal mit der Datenrate runter. Oder ist vielleicht bei einem das Cal-Byte zerstört und der liegt total daneben. Laß mal auf beiden eine 1s Blink-LED laufen und prüfe mit ner Stoppuhr. Oder setze beim Master die CLK-OUT Fuse und takte damit den Slave. Wenn nichts hilft, poste mal den kompletten Code von Master/Slave (als ZIP). Peter
Datum:
Hallo! also nachdem ich in den PCINT1 Interrupt Aufruf ein "ISR_NOBLOCK" geschrieben habe, funktioniert alles einwandfrei! Woran kann das liegen, ein Interrupt kann nur durch ein 4T ausgeführt werden, kommt aber nie vor? Komisch ist auch, wenn ich den Code lasse wie bei dir, aAntworten die Slaves schneller als wenn ich den Code invertiere ( mit Clear on Compare und so ) aber ich seh da keinen logischen Grund außer, dass das Synchronisationsbit am Schluss statt am Anfang eines Frames kommt. Lg Manuel
Datum:
Manuel schrieb: > Woran kann das liegen Was erwartest Du, ohne den kompletten Code zu zeigen? Im Hellseherlehrgang habe ich ne 6 gekriegt. Peter
Datum:
Angehängte Dateien:Hallo! Tut mir Leid. Habs angehängt, die Änderungen sollten für dich eh gut sichtbar sein! Lg Manuel
Datum:
Manuel schrieb: > also nachdem ich in den PCINT1 Interrupt Aufruf ein "ISR_NOBLOCK" > geschrieben habe, funktioniert alles einwandfrei! Ich habs ja auch so in mein Beispiel geschrieben. Die Datenrate ist recht hoch, da können andere Interrupts zu lang sein. Brauchst Du wirlich diese hohe Datenrate? Peter
Datum:
Manuel schrieb: > Habs angehängt, die Änderungen sollten für dich eh gut sichtbar sein! Man postet immer ein compilierbares File und keine Schnipselchen! Welches Target überhaupt?
TCCR0A = 1<<COM0B1;// | 1<<COM0B0; // set on compare
///////////////////////////////////////////////////////////////////////////////////////////
if( DATA_PIN == 1 )
return;
|
Dann hast Du nur eine Sache geändert, kann also nicht gehen. Nimm besser erstmal das Beispiel mit 2 Timern, die sind etwas einfacher zu verstehen. Und setze die Datenrate runter. Peter
Datum:
Hallo! Ja ich weiß. Es ist für einen AtMega644 Ja die hohe Datenrate brauche ich. auch wenn ich
if( DATA_PIN == 0 ) |
mache, funktioniert es kein Stück besser. Das meintest du doch hoffentlich oder ? Aber könntest du mir noch bitte sagen, wieso ein anderer Interrupt dazwischenfunken sollte ? Es sind doch keine anderen aktiv, lediglich der PCINT und der für 2.8*T, selbiger kann nicht auslösen. Und den PCINT wollen wir doch. Danke für deine Hilfe! Lg Manuel
Datum:
Manuel schrieb: > Ja ich weiß. Es ist für einen AtMega644 Na dann kannst Du doch 2 getrennte Compare eines Timers benutzen und mußt nicht zwischendurch umschalten (Slave1.c). Manuel schrieb: > Ja die hohe Datenrate brauche ich. Welche und bei welcher Frequenz? Peter
Datum:
Du mußt aufhören, Programme als großen monolithischen Block zu betrachten. Wenn etwas nicht funktioniert, mußt Du debuggen. Dazu muß man das Programm in einzelne Teile zerlegen und diese testen. Z.B. beide Datenrichtungen getrennt testen. Auch kann man erstmal kritische Timings runter setzen. Die Routine (slave1a.c) mit nur einem Compareregister ist durch die Umschaltung komplexer und benötigt auch mehr CPU-Zeit. Sie sollte man wirklich nur auf dem ATtiny13 einsetzen, wenn der Timer noch anderes machen soll. Beim ATmega644 ist dieser Geiz mit Timern aber nicht nötig. Peter
Datum:
Hallo nochmal Peter! Also auf dem Master, dem AtMega644 verwende ich ja auch deine Master Software mit den getrennten Timer Compare. Trotzdem funktioniert es ausschließlich einwandfrei ( Ohne oft einen TimeOut zu bekommen ) Wenn ich "ISR_NOBLOCK" einfüge. ISR_NOBLOCK heißt ja, dass der Interrupt durch einen anderen Interrupt unterbrochen werden darf, da direkt am start ein "sei()" eingefügt wird. Das heißt also entweder COMPA oder COMPB wird ausgeführt. Da beim empfangen der COMPA nicht verwendet wird, existieren also nur der PCINT und COMPB, COMPB wird allerdings nur beim Synchronisationsbit ausgeführt. Deshalb sollte der COMPB den PCINT ja überhaupt nicht stören und es sollte keinen Unterschied machen, ob ich "ISR_NOBLOCK" beim PCINT Interrupt hinzufüge oder nicht. Bin ich auf dem Holzweg? Liebe Grüße Manuel
Datum:
Hallo Peter ! Ich habe den Fehler herausgefunden, wie ich es lösen kann zwar noch nicht, aber ich möchte dir mal den Fehler erklären. Undzwar ist es die zeit zwischen PCINT aufruf und dem TCNT0=0. Wenn dazwischen hier ein Interrupt aufgerufen wird, der eigentlich das Synchronisationsbit detektieren soll, stimmt die Zählung nichtmehr. Nachdem im PCINT Interrupt rx_idx auf 0 gesetzt wurde, also als start, geht gleich darauf der COMPB Interrupt an, und setzt rx_idx wieder auf 255, womit beim nächsten Aufruf von PCINT wieder bei 0 angefangen wird, und somit alles falsch ist. Kannst du verstehen was ich meine? Hast du eventuell eine Idee selbiges zu umgehen? Lg Manuel
Datum:
Manuel schrieb: > Kannst du verstehen was ich meine? Nein. Nochmal, ich weiß nicht, welchen Code auf welchen AVRs Du benutzt. Ich kann nicht hellsehen. Und hör auf, Deine Codeänderungen beschreiben zu wollen, damit kann keiner was anfangen. Wenn eine Änderung eine Wirkung hat, die Dir unklar ist, dann mach 2 komplette Projekte, einmal mit und einmal ohne die Änderung. Oder ein Projekt, wo die Änderung mit einem Define umgeschaltet wird. Und dann kannst Du auch darauf Bezug nehmen (folgende Änderung in File x.c, Zeile y habe ich gemacht ...). Peter P.S.: Target, Taktfrequenz, Compilerversion, Compileroptionen, Anschlußbelegung usw. gehören selbstverständlich zu den Angaben, die im Projekt enthalten sein müssen.
Datum:
Hallo nochmal! Ich habe mich echt bemüht dir zu erklären wo der Fehler liegt. Ich kann dir auch sagen, wieso der Fehler bei dir nie aufgetreten ist, aber bei mir schon, dennoch hilft es nichts wenn ich den kompletten Code einfüge. Aber ich werde es einmal Versuchen. Original:
ISR( TIMER0_COMPB_vect ) // sync received { if( rx_idx == DATA_SIZE * 8) // receive successful { PCMSK1 = 0; // disable further receive } rx_idx = 255; // detect sync transition if( rx_timeout ){ // timeout answer from slave rx_timeout--; TCNT0 = 0; } } |
Testcode:
ISR( TIMER0_COMPB_vect )
{ if( rx_idx == DATA_SIZE * 8 || rx_idx == DATA_SIZE * 8 - 1)
{ PCMSK1 = 0;
}
rx_idx = 255;
if( rx_timeout ){
rx_timeout--;
TCNT0 = 0;
}
}
|
So beim Testcode schaltet er ebenfalls ab, wenn einmal eine Flanke gefehlt hat ( Eben wenn besagter Fehler auftritt ), dann tritt nie ein Timeout auf! Ich habe es mit dem Oszilloskop überprüft ob es tatsächlich daran liegt, und es liegt daran. In der Zeit zwichhen dem
ISR( PCINT1_vect ) |
Aufruf und
TCNT0 = 0; |
kommmt ein Timer0 Compare B Interrupt und setzt rx_idx NACH BEDINGUNG des Pin Change Interrupts fälschlicherweiße auf 255. Erklärung warum bei dir der Fehler nicht auftritt: Bei deinen Slaves kommt das Synchronisationsbit am Anfang, das heißt zuerst 4T und danach die Daten, bei mir ist es Programmtechnisch umgekehrt, zuerst die Daten dann das Synchronisationsbit, aus diesem Grund kann der Fehler bei dir nicht auftreten, bei mir aber schon. Erklärung warum es bei hinzufügen von
ISR_NOBLOCK |
bei der
ISR ( PCINT1_vect ) |
Routine zu keinem Fehler kommt: Nachdem der Compiler ja als bald als möglich den Interrupt mit
sei() |
wieder frei gibt, hat der
ISR( TIMER0_COMPB_vect ) |
Interrupt in der kritischen Phase eine Eingriffsmöglichkeit, und somit kann fast kein Fehler mehr auftreten, der Aufgrund der Wartezeit vom Compare B Interupt auftritt. Peter, ich hoffe, dass ich es ausführlich, verständlich und genau erklärt habe. Ich weiß, dass ich hier nichts von Compilerversion, Target etc. geschrieben habe, da es in diesem Fall keine Auswirkung hat. Ich hoffe, dass du damit einverstanden bist, wenn nicht, bitte sag es mir nochmal ich werde versuchen die Erklärung zu verbessern, auch wenn ich momentan keine Ahnung habe wie ich es noch verbessern sollte. Dankesehr Peter! Lg Manuel
Datum:
Manuel schrieb: > Bei deinen Slaves kommt das Synchronisationsbit am Anfang, das heißt > zuerst 4T und danach die Daten, bei mir ist es Programmtechnisch > umgekehrt, zuerst die Daten dann das Synchronisationsbit, Warum sagst Du denn nicht gleich, daß Du am Master-Code rumgefriemelt hast? Das kann ja nicht funktionieren! Du brauchst zu Anfang eine Flanke und die ist eben das Ende des Sync-Bits und der Start des 1.Datenbits. Ich kann Dir versichern, ich habe mir dabei was gedacht, es so zu machen und nicht anders. Du kannst Dir natürlich ein anderes Protokoll ausdenken, aber dann kannst Du meinen Code nicht mehr verwenden. Peter
Datum:
Angehängte Dateien:Hallo Peter! Tut mir Leid, ich habe es so verstanden, dass es egal ist, ob das Synchronisationsbit am Anfang oder am Ende kommt. Danke dass du mir das jetzt erklärt hast. Im Anhang befindet sich meine Testdatei. Ziel ist ein Attiny13, selbiger soll nur Aussenden. Ich verwende AVR Studio mit AVR-GCC die neueste Version. Da ich Sendeleitung und Empfangsleitung getrennt habe, gibt es ein kleines Problem und zwar hier:
void tx_data( uint8_t addr, uint8_t data ) { PCMSK = 0; // disable receive DATA_DDR = 0; // input DATA = 1; // pullup on while( DATA_PIN == 0 ); // wait until pin high ... |
Du setzt hier den Data Pin auf Eingang, legst einen Pull Up auf High und wartest bis er auf 0 gezogen wird. Die Frage ist nun, wie wird er jetzt auf 0 gezogen? Ich brauche ja nicht auf Eingang schalten und warten, da ich diesen PIN ja sowieso nur als Ausgang verwende, aber ein einfaches umschreiben auf:
void tx_data( uint8_t addr, uint8_t data ) { PCMSK = 0; DATA_DDR =1; DATA = 1; ... |
funktioniert ja nicht. Kannst du mir eventuell erklären wieso es auf 0 gezogen werden soll, bzw. wie ich es in meinem Fall umschreiben kann, dass es auch funktioniert wenn ich einen Optokoppler am Ausgang gegen Masse habe? Ich sitze wirklich nun schon seit ca. 12 Uhr da und versuche es. Es tut mir Leid, dass ich nicht der Profi Programmierer bin, und ein wenig Hilfe brauche, ich hoffe du kannst es verstehen, und siehst auch, dass ich mich wirklich bemühe es selbst zu schaffen. Großen Dank Peter! Lg Manuel
Datum:
Wenn der ATtiny13 von sich aus sendet, ist er natürlich der Master und der andere der Slave, er muß ständig empfangsbereit sein. Du kannst den Sendeausgang dann ständig eingeschaltet lassen. Ein Timeout muß dann länger sein, als der Master zwischen dem Senden maximal Pause macht. Wenn Du Modifikationen vornimmst, ist es ratsam, mit einem Oszi das Signal anzusehen. Peter
Datum:
Peter Dannegger schrieb: > Wenn der ATtiny13 von sich aus sendet, ist er natürlich der Master und > der andere der Slave, er muß ständig empfangsbereit sein. > Du kannst den Sendeausgang dann ständig eingeschaltet lassen. > Ein Timeout muß dann länger sein, als der Master zwischen dem Senden > maximal Pause macht. > > Wenn Du Modifikationen vornimmst, ist es ratsam, mit einem Oszi das > Signal anzusehen. > > > Peter Hallo! Ja das ist klar, ich habe das Programm geschrieben, da mir lediglich der Sendevorgang Sorge bereitet! Momentan sende ich nur mit dem Attiny13 und schaue mir den Ausgang am Oszilloskop an. Wenn ich auf das warten bis der Pin "0" wird verzichte, dann funktioniert es nur jedes zweite mal. Also 1. Sekunde richtig, 2. Sekunde falsch. Falsch äußert sich dahingehend, dass das Synchronisationsbit nicht gesendet wird, und auch das letzte Bit nicht gesendet wird. Beim dritten mal passt es wieder, beim 4. nicht,... Ich kann es mir nicht so recht erklären, wieso es jedes zweite Mal funktioniert, da hier ja nirgends etwas umgeschalten wird, nach jedem mal senden, zumindest sehe ich das so. So leid es mir tut, dich nochmals Fragen zu müssen, ob du eventuell einen Tipp hast, wieso selbiges Phänomen auftritt. Danke Lg Manuel
Datum:
Ein Sync-Bit ist per meiner Definition >=4*T, nach oben hin gibt es keine Grenze. Also wenn eine Sekunde lang nichts gesendet wird, ist das ein astreines Sync. Ein zusätzliches Sync schadet aber nicht, für die Anzahl gibt es auch keine obere Grenze. Peter
Datum:
Angehängte Dateien:Folgende Änderung:
void tx_data( uint8_t addr, uint8_t data ) { PCMSK = 0; // disable receive DATA_DDR = 1; // input DATA = 1; // pullup on //while( DATA_PIN == 0 ); // wait until pin high OCR0B = TCNT0 + (uint16_t)(BIT_TIME * 4 + 0.5); // sync: 4T TCCR0A = 1<<COM0B0; // toggle on compare //DATA_DDR = 1; // tx output on TIFR0 = 1<<OCF0B; // clear earlier interrupts DATA_INT = 1; // enable tx interrupt volatil(tx_idx) = 0; // point to first bit volatil(tx_buff[0]) = addr; volatil(tx_buff[1]) = data; while( DATA_INT ); // until tx done } |
führt zum "Erfolg" im Anhang. Ausgesendet soll zweimal eine "1" werden. Beim 1. Bild passt alles einwandfrei beim 2. Bild fehlt Synchronisationsbit und letztes Bit. Lg Manuel
Datum:
Angehängte Dateien:Hallo Peter! ICh sollte mich schämen, hab ich doch glatt etwas vergessen zu ändern:
ISR( TIM0_COMPB_vect, ISR_NOBLOCK ) // Transmit/Sync interrupt { uint8_t *dp; // locals for faster access if( DATA_DDR ) { if( tx_idx < DATA_SIZE * 8 ) { OCR0B += (uint16_t)(BIT_TIME + 0.5); // 0-bit: 1T dp = &tx_buff[tx_idx++ / 8]; // get byte address if( *dp & 0x80 ) // msb first OCR0B += (uint16_t)(BIT_TIME + 0.5); // 1-bit: 2T *dp <<= 1; // shift bits return; } OCR0B += (uint16_t)(BIT_TIME * 4 + 0.5); // Sync: 4T TCCR0A = 1<<COM0B1 | 1<<COM0B0; // set on compare if( DATA_PIN == 1 ) return; } |
Das:
TCCR0A = 1<<COM0B1 | 1<<COM0B0; // set on compare |
war zuvor:
TCCR0A = 1<<COM0A1 | 1<<COM0A0; // set on compare |
Dummer dummer Fehler :( Tut mir leid. hab jetzt ein Oszi Bild in den Anhang gestellt. Das passt nun so richtig, wie du den 124Bus Designed hast richtig? Lg Manuel
Datum:
Hat schon mal einer einen slave auf dem Tiny25 gebastelt?
Datum:
Mit Timer0 (OC0A, PB0 und PCINT0) klappt es wunderbar. Nur mit dem Timer1 bekomme ich es nicht hin. Platinen schon fertig, der Bus müsste auf PB4/OC1B/PCINT4. Nach wie vor läuft der Timer1 in der Simualtion AVR-Studio 4.19 nicht :-( Naja, werde jetzt erstmal die Platinen umverdrahten, 2 Tage mit dem Mist zugebracht...
Datum:
Also mit dem Mist meine ich den Timer1 vom Tiny25, nicht die Software von PeDa, nicht dass hier Missverständnisse aufkommen.... Klappt wunderbar, und so kompakt hätte ich es selbst sicher nicht hinbekommen. Eine Anmerkung trotzdem: TIMSK = 1<<OCIE1A; // sync interrupt o.ä. kann natürlich leicht zur Falle werden. Löscht andere Timer Int-Freigaben und man sieht schlecht, dass es auch darauf ankommt, dass OCIE1B gelöscht wird. Besser wäre: TIMSK = (TIMSK | 1<<OCIE1A) & ~ (1<<OCIE1B); //OCIE1A on, OCIE1B off löscht sichtbar OCIE1B und lässt die andern Bits in Ruhe.


