Hallo liebe Gemeinde, ich versuche mit folgendem Code einen DS18B20 auszulesen! Leider erhalte ich immer eine Ausgabe von 1111 1111 1111 1111 ! Der Sensor ist per +5V, 1-Wire-Bus mit 4,7k an +5V und GND angeschlossen. Der 1-Wire Bus ist an PA7 angeschlossen! uC ist ein ATmega 16, mit internem Takt 1Mhz betrieben Wäre super wenn jemand einen Tipp hat! Gruß Fabian
Ich habe es mit der lcd-routines.asm aus dem AVR-Tutorial im Simulator laufen lassen. Die doppelte Definition von r22/r23 habe ich bereinigt. 1/ Wesentlicher Bug in sensor.asm: ConT läuft in SendScratchpad weil ein ret fehlt. Es sieht auch so aus, als ob du an der Stelle das Original geändert hast. 2/ Nachsehen: Hast du die Wartezeiten selbst implementiert? Die sind etwas ungenau: Soll/ist 480/487 10/17 58/65 2/9. Weiter habe ich nicht simuliert.
> Womit hast du das ganze simuliert? AVR Studio. Weitere siehe AVR-Simulation. Du musst es nur schaffen, dein Programm in den Simulator reinzuschaffen und dass es Funktionen für Step (Einzelschritt) und fürs bequeme Simulieren Step Over (Überspringen wg. der langen Wartefunktionen) dort gibt.
Erstmal vielen Dank für die Tipps, ich kann nun den Sensor auslesen und den Wert Binär auf dem Display ausgeben! Nun habe ich zum Beispiel den Wert: 0000 0010 0101 1110 - was ja 37,875°C laut Datenblatt entspricht. Nun möchte ich eine Verzweigung haben, welche zwischen Über- und Unterschreitung dieser Temperatur entscheidet. Kann mir da noch einmal jemand auf die Sprünge helfen?! Wäre super! Danke Fabian
Sorry ASM debuggen OK, schreiben tue ich es nur, wenn es nicht anders geht :) http://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche http://www.mikrocontroller.net/articles/AVR-Tutorial:_Mehrfachverzweigung
So, ich habe mich damit noch mal ein wenig auseinandergesetzt! In 8 Bit würde es dann ja ca. so Aussehen, angenommen r16 wäre der gelesene Wert:
1 | loop: |
2 | cpi r16, 0b01011110 |
3 | brsh heizung_aus |
4 | brlo heizung_ein |
5 | rjmp loop |
6 | |
7 | heizung_aus: |
8 | ldi r21, 0b00000000 |
9 | out PortC, r21 |
10 | rjmp loop |
11 | |
12 | heizung_ein: |
13 | ldi r21, 0b11000000 |
14 | out PortC, r21 |
15 | rjmp loop |
allerdings habe ich ja leider einen Wert von 0000 0010 0101 1110 als "Soll-Wert" und den Wert vom DS18B20 aus "Ist-Wert". Wie kann ich diese beiden nun direkt vergleichen?
Ich denke der CPC Befehl ist dein Freund! Hier aus der Hilfe des AVR Studios: Syntax: Operands: Program Counter: CPC Rd,Rr 0 ≤ d ≤ 31, 0 ≤ r ≤ 31 PC <- PC + 1 Operation: Rd - Rr - C Example:
1 | ; Compare r3:r2 with r1:r0 |
2 | |
3 | cp r2,r0 ; Compare low byte |
4 | cpc r3,r1 ; Compare high byte |
5 | brne noteq ; Branch if not equal |
6 | ... |
7 | noteq: |
8 | nop ; Branch destination (do nothing) |
Du liest ja in r25 das Highbyte und Lowbyte des Sensors ja nacheinander aus. Wenn du freie Register hast, kannst du die füllen und vergleichen. so etwa (ohne Rücksicht auf effiziente Registernutzung!)
1 | ... |
2 | rcall ReadScratchpad ; Scratchpad Byte 2 Empfangen |
3 | mov r3, r25 ; Highbyte retten |
4 | rcall lcd_clear |
5 | rcall Binaerausgabe ; Bildschirmausgabe |
6 | clr r24 |
7 | rcall ReadScratchpad ; Scratchpad Byte 1 Empfangen |
8 | mov r2, r25 ; Lowbyte retten |
9 | rcall Binaerausgabe ; Bildschirmausgabe |
10 | |
11 | ; 16-Bit Vergleich mit Vorzeichen |
12 | ldi r0, LOW(0b0000001001011110) |
13 | ldi r1, HIGH(0b0000001001011110) |
14 | cp r2,r0 |
15 | cpc r3,r1 |
16 | brge heizung_aus |
17 | rjmp heizung_ein |
18 | |
19 | heizung_aus: |
20 | ldi r21, 0b00000000 |
21 | out PortC, r21 |
22 | rjmp loop |
23 | |
24 | heizung_ein: |
25 | ldi r21, 0b11000000 |
26 | out PortC, r21 |
27 | rjmp loop |
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.