Guten Tag, ich beschäftige mich aktuell mit 1-Wire auf STM32 (C, CubeIDE) und habe mir auch schon einige Beiträge hier im Forum durchgelesen. Mir wäre jedoch wichtig, dass der Code nicht blockierend aufgebaut ist und damit scheint die Angelegenheit dann etwas komplizierter zu werden. Bevor ich da jetzt mit Tests sinnlos Zeit verschwende... Lässt sich das 1-Wire Protokoll gut mit einer state machine abbilden oder würdet ihr diese Aufgabe rein vom Konzept her anders angehen? Vielen Dank und schöne Grüße, Martin
Martin schrieb: > Mir wäre > jedoch wichtig, dass der Code nicht blockierend aufgebaut ist und damit > scheint die Angelegenheit dann etwas komplizierter zu werden. Das liegt in der Natur der Sache. Asynchroner Code ist immer komplizierter strukturiert. > Lässt sich das 1-Wire Protokoll gut mit einer state machine abbilden Natürlich.
Ja lässt sich. Ist halt die Frage welche HW Elemente du zu beschleunigen nehmen kannst. Und wie schnell dein Kontroller ist. Nen Reset Pulse mit 480ns möchtest du ja nicht blockierend abwarten. Da kann man mit Interrupt etwas machen. Rest könnte kann man ja blockierend abwarten. Bei so langsameren Kontrollers wird das vielleicht so gemacht. Wenn du aber schnellere Kontrollers hast, mit 100MHz oder mehr, da willst du ja auch die kleineren Zeiten nicht blockierend abwarten. Da kommt ein UART ins spiel, und das ganze könnte man dann Interruptgetrieben machen. Oder wenn du DMA hast, kannst versuchen mit DMA die Musters zu generieren. Je nach Kontrollertype kann das funktionieren oder nicht. Also ja, lässt sich. Man muss nur erstmal wissen wie schnell dein Kontroller ist, welche HW Bausteine du dafür opfern möchstest. Wie lange darf man blockierend laufen.
Ich hatte einen 16 MHz AVR mit einem globalen 10 kHz Timer Tick betrieben, und auch die Bits von 1-Wire darüber abgewickelt. Nur das Timing innerhalb der Bits lief per Delayloop. Dieser Tick produzierte natürlich spürbar Grundlast, aber das war egal. Obendrein war das keine State Machine, sondern ein schneller RTOS Kernel, weshalb der Code kaum anders aussah als sonst.
:
Bearbeitet durch User
Martin schrieb: > ich beschäftige mich aktuell mit 1-Wire auf STM32 (C, CubeIDE) und habe > mir auch schon einige Beiträge hier im Forum durchgelesen. Mir wäre > jedoch wichtig, dass der Code nicht blockierend aufgebaut ist Was heißt das GENAU? Jeder Code "blockiert", fragt sich nur, wie lange. Bei meiner Implementierung sind die Interrupts für jedes Bit ca. 100us gesperrt, zwischen den Bits werden sie wieder freigegeben. Die Funktionsaufrufe "blockieren" halt für die jeweilige Byte-Sequenz. Beitrag "Re: Onewire + DS18x20 Library"
(prx) A. K. schrieb: > Obendrein war das keine State Machine, sondern ein schneller RTOS > Kernel, weshalb der Code kaum anders aussah als sonst. Ja, für solche Leute sind RTOSe wohl gedacht... Bis das böse Erwachen kommt, weil halt der ineffiziente Code aus der Echtzeit fällt...
> Lässt sich das 1-Wire Protokoll gut mit einer state machine abbilden
Auf einem Tiny10 tat ich genau dies. Fährt automatisch
SkipRom-ConvertT-SkipRom-ReadScratchpad bitbangend durch. Granuliert als
Nibble (4 bit-slots) konnte ich die Interrupts aus lassen und das
Timerbit ohne Verlust pollen. Dient nur als Interface OW2UART.
Martin schrieb: > Mir wäre > jedoch wichtig, dass der Code nicht blockierend aufgebaut ist und damit > scheint die Angelegenheit dann etwas komplizierter zu werden. Ja! Selbst wenn es "nicht blockierend" geschrieben ist, können einem irgendwelche ISRs derbe ins Timing spucken. Drum: Mit einem 2 Kerne µC mag das günstiger sein. Auch ein 2ter µC(Tiny?), welcher als Koppler zwischen z.B. I2C und OnWire dient, bekommt man das hin. Provokation Was ist mehr Wert, die Arbeit(Lebenswerk?) eines verbissenen ASMlers, dessen Karre bei der nächsten asynchronen Anforderung umfällt, oder ein mini Häuflein Euronen.
c-hater schrieb: > Das liegt in der Natur der Sache. Asynchroner Code ist immer > komplizierter strukturiert. Gut zu wissen. Ich nehme mal an, man darf die streng asynchrone Struktur an geeigneten Stellen auch etwas entschärfen bzw. man muss es nicht mit der Verschachtelungs-Tiefe übertreiben, wenn es aufgrund zu vieler Bedingungen und Verzweigungen zu unübersichtlich wird und das Timing es erlaubt? Andras H. schrieb: > Also ja, lässt sich. Man muss nur erstmal wissen wie schnell dein > Kontroller ist, welche HW Bausteine du dafür opfern möchstest. Wie lange > darf man blockierend laufen. Der µC läuft aktuell mit 25 MHz (incl. APB1 Timer Clock). Einen UART könnte ich aber sicherlich für 1-Wire spendieren, das scheint das Timing ja zu entschärfen. Uwe Bonnes schrieb: > Generiere die Pulse via UART -> Maxim AN126 Ich werde das mit dem UART in Erwägung ziehen. Wie würde man denn bei 1-Wire über UART den 1-Wire-Slave anschließen? In einem Schema von Maxim sieht es so aus, als würde man den UART-TX via PullUp gleichzeitig mit UART-RX + DQ verbinden. Ist das der Trick, damit man das Gesendete entweder 1:1 empfängt (weil der Slave den Bus nicht auf Low zieht) oder eben etwas anderes, was durch die Bitzeiten in der jeweiligen Baudrate erzeugt wird? Falk B. schrieb: > Was heißt das GENAU? Jeder Code "blockiert", fragt sich nur, wie lange. Hmm, das ist eine gute Frage. Es geht mir wohl auch darum, das jetzt nicht völlig falsch anzugehen. Vermutlich wird bei mir aber auch Deine Lösung mit dem vertretbaren Blockieren funktionieren. Ich reize den µC nicht bis zum letzen Takt aus und habe auch (noch) keine superkritischen Timing-Sachen, daher sehe ich mir das nochmal an. neuer PIC Freund schrieb im Beitrag #7234626: > Auf einem Tiny10 tat ich genau dies. Fährt automatisch > SkipRom-ConvertT-SkipRom-ReadScratchpad bitbangend durch. Auch nicht schlecht. :) Ich vermute aber, dass eine state machine bei vollständiger 1-Wire-Protokoll-Implementierung etwas unübersichtlich wird. EAF schrieb: > Was ist mehr Wert, die Arbeit(Lebenswerk?) eines verbissenen ASMlers, > dessen Karre bei der nächsten asynchronen Anforderung umfällt, oder ein > mini Häuflein Euronen. Hast schon recht. Ich verstehe nur nicht, warum Maxim das Timing so kritisch designt hat? Bei den vergleichsweise gigantischen Wartezeiten, die man für eine Temperatur-Messung ertragen muss, wäre ein entschärftes Timing doch nicht so schlimm gewesen?!? Vielen Dank euch allen!
EAF schrieb: > Selbst wenn es "nicht blockierend" geschrieben ist, können einem > irgendwelche ISRs derbe ins Timing spucken. Natürlich nur dann, wenn diese inkompetent und ohne deterministisches Timing geschrieben sind. Also gerade nicht in Asm, sondern in irgendeiner verschissenen Hochsprache. Denn genau das können Hochsprachen nicht: ein deterministisches Timing garantieren. Alles was die garantieren, ist: "so schnell wie möglich". Wobei das eigentlich in Wahrheit bedeutet: "so schnell mir (also dem Compiler) möglich", was auch nochmal ein durchaus signifikanten Unterschied bedeuten kann... Selbst in Asm fällt es auf vielen Architekturen schwer, ein determistisches Timing zu garantieren. Aber nicht auf AVR8. Da geht das recht einfach. Und weil das da geht, kann man ganz hervorragend alles ausrechnen, insbesondere natürlich auch den worst case. Man muss es einfach nur können und tun...
Martin schrieb: > wäre ein entschärftes > Timing doch nicht so schlimm gewesen?!? Wenn man sich kein Kabel für einen Takt leisten kann/will, kann man es nur über das Timing regeln. Und das muss dann eben recht exakt sein.
EAF schrieb: > c-hater schrieb: >> Man muss es einfach nur können und tun... > > Du kannst gar nichts! Nun, das sagst du. Allerdings kann ich kein Werk von dir sehen, was deine Kompetenz in irgendeiner Form belegen könnte. Ich hingegen habe wenigstens ein paar Sachen öffentlich zur Verfügung gestellt, die definitiv funktionieren und insbesondere auch den Vorteil der Asm-Programmierung für AVR8-Targets zeigen. Weil sie halt Sachen umsetzen, die mit dem üblichen Compilern nicht gehen, weil der Code halt schlicht zu beschissen ist, den diese produzieren. Also steht hier leeres Blafasel eines Blinden Wichsers ohne jeden Beleg gegen öffentlich verfügbare und nachweislich funktionierende Lösungen. Nicht schwer, hier die Wahl zu treffen, wem man glaubt...
EAF schrieb: > c-hater schrieb: >> Man muss es einfach nur können und tun... > > Du kannst gar nichts! Nun, das sagst du. Allerdings kann ich kein Werk von dir sehen, was deine Kompetenz in irgendeiner Form belegen könnte... Ich hingegen habe wenigstens ein paar Sachen öffentlich zur Verfügung gestellt, die definitiv funktionieren und insbesondere auch den Vorteil der Asm-Programmierung für AVR8-Targets zeigen. Weil sie halt Sachen umsetzen, die mit dem üblichen Compilern nicht gehen, weil der Code halt schlicht zu beschissen ist, den diese produzieren. Also steht hier leeres Blafasel eines Blinden Wichsers ohne jeden Beleg gegen öffentlich verfügbare und nachweislich funktionierende Lösungen. Nicht schwer, hier die Wahl zu treffen, wem man glaubt...
c-hater schrieb: > (prx) A. K. schrieb: > Bis das böse Erwachen kommt, weil halt der ineffiziente Code aus der > Echtzeit fällt... Bin ich du? ;-) Die Steuerung lief 2 Jahrzehnte und flog erst nach dem Verkauf des Hauses raus. Das war aber nicht als Empfehlung gemeint. Was dir bestimmt gefallen wird: Der Kernel "AvrX" war in Assembler implementiert. Weniger: mein Programm jedoch in C/C++.
:
Bearbeitet durch User
(prx) A. K. schrieb: > Bin ich du? ;-) Sicher nicht. Du kannst halt nicht alles haben. > Die Steuerung lief 2 Jahrzehnte und flog erst nach dem Verkauf des > Hauses raus. Naja, wenn die Zeit reicht für den Task (und alle konkurrierenden), dann ändert natürlich auch eine Laufzeit der unveränderten Anwendung von 20 Jahren nichts an diesem Sachverhalt. Ist doch logisch. Wenn allerdings Tasks hinzukommen oder bestehende Task nach Änderungen mehr Rechenzeit benötigen, ist irgendwann Schluss. Sollte auch logisch sein. Der Punkt ist halt: Ineffiziente Tasks (und auch das RTOS selber) sorgen dafür, dass diese Situation eintritt, lange bevor sie tatsächlich eintreten müsste, wenn die Fähigkeiten der Hardware des Targets optimal genutzt würden...
Martin schrieb: > Ich werde das mit dem UART in Erwägung ziehen. Wie würde man denn bei > 1-Wire über UART den 1-Wire-Slave anschließen? In einem Schema von Maxim > sieht es so aus, als würde man den UART-TX via PullUp gleichzeitig mit > UART-RX + DQ verbinden. Ist das der Trick, damit man das Gesendete > entweder 1:1 empfängt (weil der Slave den Bus nicht auf Low zieht) Ja. > oder > eben etwas anderes, was durch die Bitzeiten in der jeweiligen Baudrate > erzeugt wird? Das auch. > Falk B. schrieb: >> Was heißt das GENAU? Jeder Code "blockiert", fragt sich nur, wie lange. > > Hmm, das ist eine gute Frage. Es geht mir wohl auch darum, das jetzt > nicht völlig falsch anzugehen. Vermutlich wird bei mir aber auch Deine > Lösung mit dem vertretbaren Blockieren funktionieren. Ich reize den µC > nicht bis zum letzen Takt aus und habe auch (noch) keine superkritischen > Timing-Sachen, daher sehe ich mir das nochmal an. Gute Idee. Man kann alles übertreiben. Ein Code muss nur so "nicht blockierend" sein, wie es für die Anwendung ausreichend ist. > neuer PIC Freund schrieb im Beitrag #7234626: >> Auf einem Tiny10 tat ich genau dies. Fährt automatisch >> SkipRom-ConvertT-SkipRom-ReadScratchpad bitbangend durch. > > Auch nicht schlecht. :) Ich vermute aber, dass eine state machine bei > vollständiger 1-Wire-Protokoll-Implementierung etwas unübersichtlich > wird. Nö. ALles eine Frage der Umsetzung. Außerdem, wenn es einmal läuft, ist der inhalt egal, man muss es nur noch nutzen. > EAF schrieb: >> Was ist mehr Wert, die Arbeit(Lebenswerk?) eines verbissenen ASMlers, >> dessen Karre bei der nächsten asynchronen Anforderung umfällt, oder ein >> mini Häuflein Euronen. > > Hast schon recht. Ich verstehe nur nicht, warum Maxim das Timing so > kritisch designt hat? Was heißt denn kritisch? Die haben schon ziemlich großzügige Toleranzen drin. > Bei den vergleichsweise gigantischen Wartezeiten, > die man für eine Temperatur-Messung ertragen muss, wäre ein entschärftes > Timing doch nicht so schlimm gewesen?!? Unsinn. Das sind zwei vollkommen verschiedene Schuhe! Das eine ist die unterste Bitübertragungsschicht, OSI Layer 1. Das Andere die Anwerdschicht, OSI-Layer 4 oder höher.
c-hater schrieb: > Natürlich nur dann, wenn diese inkompetent und ohne deterministisches > Timing geschrieben sind. Also gerade nicht in Asm, sondern in > irgendeiner verschissenen Hochsprache. Denn genau das können > Hochsprachen nicht: ein deterministisches Timing garantieren. Abwer sicher, mein Hochverehrter. Auch ein C-Programm ist deterministisch, wenn gleich nicht auf den Takt genau wie ein ASM-Progamm. > Selbst in Asm fällt es auf vielen Architekturen schwer, ein > determistisches Timing zu garantieren. Unfug. Deterministisch != taktgenau. > Aber nicht auf AVR8. Da geht das > recht einfach. Und weil das da geht, kann man ganz hervorragend alles > ausrechnen, insbesondere natürlich auch den worst case. Jo, und darauf hat auch jeder Bock und das ist auch voll nötig, in jeder Lebenslage . . . > Man muss es einfach nur können und tun... Man muss es vor allem nur dann tun, wenn es WIRKLICH nötig ist. Parkst du dein Auto auch auf dem Millimeter genau? Du vermutlich schon . . .
c-hater schrieb: > EAF schrieb: > >> Selbst wenn es "nicht blockierend" geschrieben ist, können einem >> irgendwelche ISRs derbe ins Timing spucken. > > Natürlich nur dann, wenn diese inkompetent und ohne deterministisches > Timing geschrieben sind. Also gerade nicht in Asm, sondern in > irgendeiner verschissenen Hochsprache. Das ist doch Unsinn. Eine ISR spuckt einem auch in Assembler in die Timing-Suppe wenn man sie lässt. LG, Sebastian
Ach komm! Jetzt lass doch bitte mal den C Hasser in Ruhe. Ihm ist doch gar nicht in der Lage einen Irrtum einzusehen/einzugestehen. bzw. ist seine Lösungsmenge begrenzt, beleidigen, oder den Schwanz einkneifen.
Martin schrieb: > Der µC läuft aktuell mit 25 MHz (incl. APB1 Timer Clock). Einen UART > könnte ich aber sicherlich für 1-Wire spendieren, das scheint das Timing > ja zu entschärfen. Der AVR schafft es bequem bei 8MHz, da sollten 25MHz überhaupt kein Problem sein. Und wenn man dann noch einen MC mit Interruptlevel hat, dann brauchen andere Tasks auch keinerlei Rücksicht zu nehmen. Der 1-Wire Timerinterrupt läuft einfach still und leise im Hintergrund. Auch irgendwelche Assembler-Hacks sind vollkommen unnötig. Hier nochmal der Link: Beitrag "DS18B20 mit Interrupt, AVR-GCC" Und nochmal die Statemaschine:
1 | ISR(TIMER0_OVF_vect) |
2 | {
|
3 | if (ONWI_oe && !ONWI_out) // if low |
4 | {
|
5 | ONWI_oe = 0; // pin = tristate |
6 | _delay_us(5); // min high time |
7 | }
|
8 | uint8_t* pbuf = onwi.pbuf; // for faster access |
9 | switch (++onwi.state) |
10 | {
|
11 | case OW_RES_LO: // 480us low |
12 | if (onwi.delay--) // n * 100ms |
13 | onwi.state = OW_DELAY; |
14 | else
|
15 | {
|
16 | ONWI_out = 0; |
17 | ONWI_oe = 1; // pin = low |
18 | }
|
19 | case OW_RES_HI: // 480us high |
20 | default: // n * 480µs |
21 | TCNT0 = 256 - OW_RESET_SLOT; |
22 | return; |
23 | case OW_WR_DONE: // 1. command byte finished |
24 | pbuf++; |
25 | onwi.state = OW_WR_BIT0; |
26 | case OW_WR_BIT0: // write bit 0 |
27 | if (onwi.wr_cnt--) |
28 | {
|
29 | case OW_WR_BIT1: // write bit 1 |
30 | case OW_WR_BIT2: |
31 | case OW_WR_BIT3: |
32 | case OW_WR_BIT4: |
33 | case OW_WR_BIT5: |
34 | case OW_WR_BIT6: |
35 | case OW_WR_BIT7: // write bit 7 |
36 | ONWI_oe = 1; // pin = low |
37 | _delay_us(1); |
38 | if (*pbuf & 1) |
39 | ONWI_oe = 0; // pin = tristate |
40 | *pbuf >>= 1; |
41 | break; |
42 | }
|
43 | ONWI_out = 1; // parasite power on |
44 | ONWI_oe = 1; |
45 | pbuf = onwi.buf - 1; |
46 | case OW_RD_DONE: |
47 | pbuf++; |
48 | onwi.state = OW_RD_BIT0; |
49 | if (onwi.rd_cnt--) |
50 | {
|
51 | ONWI_oe = 0; // parasite power off |
52 | ONWI_out = 0; |
53 | case OW_RD_BIT1: // read bit 1 |
54 | case OW_RD_BIT2: |
55 | case OW_RD_BIT3: |
56 | case OW_RD_BIT4: |
57 | case OW_RD_BIT5: |
58 | case OW_RD_BIT6: |
59 | case OW_RD_BIT7: // read bit 7 |
60 | ONWI_oe = 1; // pin = low |
61 | _delay_us(1); |
62 | ONWI_oe = 0; // pin = tristate |
63 | _delay_us(5); |
64 | *pbuf >>= 1; |
65 | if (ONWI_in) |
66 | *pbuf |= 0x80; |
67 | break; |
68 | }
|
69 | TCCR0B = 0; // stop T0 |
70 | return; |
71 | }
|
72 | onwi.pbuf = pbuf; |
73 | TCNT0 = 256 - OW_BIT_SLOT; |
74 | }
|
Peter D. schrieb: > Und nochmal die Statemaschine: Also die Einrückungen gefallen mir gar nicht, das hätte ich von einem (Profi-?) PeDa anders erwartet .....
augenkrebs schrieb: > Also die Einrückungen gefallen mir gar nicht, das hätte ich > von einem (Profi-?) PeDa anders erwartet ..... Naja, es ist einer der häßlichen C-Tricks, mit verschachtelten switch/case und if. Würde ich auch nicht so machen wollen. Bringt keinen funktionalen und leistungsmäßigen Gewinn, dafür umso mehr Spaghetticode.
Martin schrieb: > Lässt sich das 1-Wire Protokoll gut mit einer state machine abbilden > oder würdet ihr diese Aufgabe rein vom Konzept her anders angehen? So pauschal gefragt: ja, ganz anders, und zwar wegen der Hardware. * Der 1-Wire Bus ist eigentlich für 5V ausgelegt. * 1-Wire EEPROMs z.B. funktionieren mit 3.3V nur "gerade noch" * manche Chips brauchen viel Strom, also einen umschaltbaren Pull-Up * STM32-Pins erzeugen unnötig steile Flanken * STM32-Pins sind relativ empfindlich, man möchte kein Kabel ohne ESD-Schutz anschließen. Mehr als wenige Dutzend Ohm Serienwiderstand sind aber nicht erlaubt und Kapazitäten stören sowieso. Man braucht also meistens ein paar externe Bauteile. Ein DS2484 erledigt das alles in einem 6-Pin SOT-23, inklusive Level Shifter und 8kV ESD Schutz. Nebenbei sorgt er selbständig für das korrekte Timing, auch mit Overdrive Speed. Und dank I2C braucht er ggf. keinen einzigen uC-Pin extra. Es gibt auch noch andere 1-Wire Master, z.B. den DS2480 für UART zu 1-Wire, jeder mit eigenen Vor- und Nachteilen: https://www.maximintegrated.com/en/products/parametric/search.html?fam=1wire&node=4868
:
Bearbeitet durch User
Falk B. schrieb: > dafür umso mehr Spaghetticode. State machines sind von Natur aus Spaghetticode. Übersichtlichen sequentiellen Code gibt es nur mit mindestens Coroutinen.
Bauform B. schrieb: > Der 1-Wire Bus ist eigentlich für 5V ausgelegt Die gerne genutzten 1820er haben auch mit 3,0V kein Problem.
(prx) A. K. schrieb: > State machines sind von Natur aus Spaghetticode. Nö! Du weißt genau was ich meine, denn ich habe es EXPLIZIT beschrieben! Was soll die Besserwisserei?
Falk B. schrieb: > Was soll die Besserwisserei? Du Besserwisser kritisierst ihn, ich Besserwisser dich. Wirst du verkraften müssen. Ich finde seinen Code überdies recht geschickt so gestaltet, dass die Abfolge in etwa erhalten bleibt.
:
Bearbeitet durch User
(prx) A. K. schrieb: > Ich finde seinen Code überdies recht geschickt so gestaltet, dass die > Abfolge in etwa erhalten bleibt. Magst du deine Statemachine mit RTOS auch zur Verfügung stellen? Ist nur Neugierde, wie du das mittels RTOS gelöst hast.
Martin schrieb: >> Generiere die Pulse via UART -> Maxim AN126 > > Ich werde das mit dem UART in Erwägung ziehen. Wie würde man denn bei > 1-Wire über UART den 1-Wire-Slave anschließen? In einem Schema von Maxim > sieht es so aus, als würde man den UART-TX via PullUp gleichzeitig mit > UART-RX + DQ verbinden. Ist das der Trick, damit man das Gesendete > entweder 1:1 empfängt (weil der Slave den Bus nicht auf Low zieht) oder > eben etwas anderes, was durch die Bitzeiten in der jeweiligen Baudrate > erzeugt wird? https://www.maximintegrated.com/en/design/technical-documents/tutorials/2/214.html
900ss D. schrieb: > Ist nur > Neugierde, wie du das mittels RTOS gelöst hast. ich bin nicht Falk, habe es aber auch gerade mit RTOS und RP2040 gemacht. D.h., eine fertige Komponente genommen und die funktioniert, arbeitet mit wait_us() und afaik vertrödelt das Zeit mit auf Timer warten. Habe noch nicht nachgemessen wie gut das Timing (unter Last) ist, werde ich nachholen. Das RTOS macht es jedenfalls einfach etwas parallel laufen zu lassen, nur wenn der DS in einem Thread mit höherer Prio läuft, dann blockiert das trödeln andere trotzdem. Bei niedriger Prio stören andere das Timing, da ist die Frage wie Tolerant der DS ist. Temperaturen liest man ja zyklisch und wenige Ausfälle (wenn sie von der CRC erkannt werden) sind je nach Anwendung tolerierbar, micht würde das nicht stören. Die CRC wird Dallas doch sicher eingebaut haben weil OneWire nicht so sicher ist? Eine Statistik für fails einzubauen wäre interessant. Beim RP2040 lässt sich die Kommunikation sicher vom PIO unterstüzen? Hatte die DS bisher lange Zeit rumliegen, möchte aber jetzt wie wohl viele andere auch die Heizungsanlage besser überwachen. Ich hatte die DS mit Edelstahlgehäuse und andere Teile bei AZ bestellt, die DS konnten innerhalb 24 h ohne Aufpreis geliefert werden, die anderen Teile kamen einen Werktag später. Interessant, das scheint ja aus Lagern zu kommen die Bedarfsgesteuert gefüllt werden.
Falk B. schrieb: > Naja, es ist einer der häßlichen C-Tricks, mit verschachtelten > switch/case und if. Vom Prinzip her ist switch/case nur eine andere Schreibweise von goto. Das Durchfallen erlaubt aber, Codesequenzen nicht ausufernd für jeden Case duplizieren zu müssen und macht es daher übersichtlicher. Auch ist es während der Entwicklung deutlich einfacher, den Code nur an einer Stelle korrigieren zu müssen und nicht auch in haufenweise Duplikaten. Das Durchfallen ist quasi das Prinzip der optimalen Reihenfolge, kommt also dem (faulen) Menschen entgegen. Mich stört jede gleiche Codesequenz, die ich an 2 Stellen hinschreiben müßte, weil man sie dann auch an 2 Stellen lesen und verstehen müßte und an 2 Stellen Fehler machen kann. Wenn es aber nicht anders geht, mache ich daraus eine Unterfunktion, die ich an n Stellen aufrufe.
:
Bearbeitet durch User
Peter D. schrieb: > Mich stört jede gleiche Codesequenz, die ich an 2 Stellen hinschreiben > müßte, ja, nur das man in den if Block reinspringen darf hatte ich noch nicht gesehen, das sieht nicht schön aus. Die neueren gcc meckern beim Fallthru auch mehr, wenn man das möchte soll man das im Code als Kommentar hinschreiben.
Martin schrieb: > Guten Tag, > > ich beschäftige mich aktuell mit 1-Wire auf STM32 > dass der Code nicht blockierend Mit so einem popeligen schnarchprozessor wird das schwierig.
J. S. schrieb: > ja, nur das man in den if Block reinspringen darf hatte ich noch nicht > gesehen, das sieht nicht schön aus. Die Protothreads des Adam Dunkels basieren auf dem gleichen Prinzip.
Alt G. schrieb: > Mit so einem popeligen schnarchprozessor wird das schwierig. Das läuft sogar auf einem standard 8051 (mit Keil C51 Compiler getestet). Und der teilt durch 12, hat also wahnsinnige 1MIPS an einem 12MHz Quarz.
:
Bearbeitet durch User
900ss D. schrieb: > Magst du deine Statemachine mit RTOS auch zur Verfügung stellen? Ist nur > Neugierde, wie du das mittels RTOS gelöst hast. Heute Abend. Ist aber unspektakulär. Er basiert auf einem anderen, linearen Code von Peter D, bei dem ich die Delayloops jenseits des inneren Bit-Timings durch Timer-Waits des RTOS ersetzte. Damit sind die Bits zwar aufgrund des 10 kHz RTOS-Ticks mit 100us weiter auseinander als möglich, aber das stört nicht.
:
Bearbeitet durch User
(prx) A. K. schrieb: > 900ss D. schrieb: >> Magst du deine Statemachine mit RTOS auch zur Verfügung stellen? Ist nur >> Neugierde, wie du das mittels RTOS gelöst hast. > > Heute Abend. Ist aber unspektakulär. Er basiert auf einem anderen, > linearen Code von Peter D, bei dem ich die Delayloops jenseits des > inneren Bit-Timings durch Timer-Waits des RTOS ersetzte.
1 | #define USE_TIMER (AVRX && TICK<=200) /* use an AvrX timer? */ |
2 | |
3 | #if USE_TIMER
|
4 | static TimerControlBlock ds_timer; |
5 | #define wait_sync() AvrXDelay(&ds_timer, 1); // synchronize to timer tick
|
6 | #define wait_us(us) AvrXDelay(&ds_timer, TICKS_US(us));
|
7 | #define wait_ms(ms) AvrXDelay(&ds_timer, TICKS_MS(ms));
|
8 | #else
|
9 | #define wait_sync()
|
10 | #define wait_us(us) delay_us(us)
|
11 | #define wait_ms(ms) delay_ms(ms)
|
12 | #endif
|
Der Code nutzt wait_xx, wenn das Timing nach oben relativ offen ist, und delay_xx, wenn nicht. Das war schon praktisch alles, was als Anpassung an das preemptive RTOS erforderlich war. Unabhängig von RTOS oder nicht gibt es natürlich noch BeginCritical() und EndCritical() um Sektionen ohne Interrupt, wie die Übertragung eines Bits. Eine einzelne Bitübertragung läuft also am Stück (sowas wie 80µs), zwischen den Bits oder im 1W-Reset kann der Code aber unterbrochen werden. Mit RTOS kann es also zwischen den Bits zu einem Taskwechsel kommen, und bei wait_xx ohnehin. Das ist der ganze Unterschied zwischen dem Betrieb mit RTOS und ohne, was die Ansteuerung von 1-Wire angeht. Um auf diese Art auch das Timing innerhalb der Bitübertragung ohne Delayloops machen können, braucht man mehr als einen Mega32. > Bits zwar aufgrund des 10 kHz RTOS-Ticks mit 100us weiter auseinander > als möglich, aber das stört nicht. Das hatte ich falsch in Erinnerung. Mit Taskwechsel zwischen den Bits kann dort eine nicht klar definierte Zeit verstreichen, was aber im 1-Wire Protokoll nicht relevant ist. Das Timing vom 1W-Reset ist durch den Timer-Tick nach oben etwas offen, aber das sind die Devices auch.
:
Bearbeitet durch User
An Tasks gab es: - Abfrage der lokalen Tastatur - Benutzerinteraktion mit LCD-Anzeige - Kommunikation mit Bedienmodul im Wohnbereich - Die Steuerung, darin wird der 1-Wire-Code aufgerufen - Überwachung, ob alles mit rechten Dingen zugeht
:
Bearbeitet durch User
Hallo Leute, nochmal vielen Dank für die Hilfe. Die Übertragung mit Hilfe von UART funktioniert inzwischen. Ich habe jetzt beim STM32 den USART_TX als Alternate Function Push Pull konfiguriert, den USART_RX als Alternate Function Open Drain und einen PullUp mit 1,5K so wie im folgenden Schema eingelötet: https://www.maximintegrated.com/content/dam/images/design/tech-docs/214/214fig01.png Der 1-Wire Slave ist über 3 Adern angeschlossen und wird über die dritte Leitung mit den 3,3 Volt für den µC mitversorgt. Ich hoffe, dass ist so in Ordnung. LG, Martin
:
Bearbeitet durch User
Martin schrieb: > Ich habe jetzt beim STM32 den USART_TX als > Alternate Function Push Pull konfiguriert, den USART_RX als Alternate > Function Open Drain und einen PullUp mit 1,5K so wie im folgenden Schema > eingelötet: Das ist aber arg hochohmig bei Low-Pegel. Ich würde TXD auf Open Drain setzen und den Pullup gegen VCC. Zum Bedämpfen von Reflexionen noch ein 47..220Ω in Reihe zu TXD. Wie kann man einen Eingang (RXD) auf Open Drain setzen?
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.