;------------------------------------------------------------------------ Hauptprogramm: Dallas DS1821 an portd 5 bei 4MHz Funktionsweise: Befehl zum starten der Wandlung wird abgeschickt Anschließend wird der alte Wert ausgelesen und in r16 abgelegt. Viel Spaß dabei!!! Danke für die vielen geduldigen Antowrten written by bluemole ;------------------------------------------------------------------------ loop: rcall Tempini rcall w0ms4 ldi r16,0xEE ;Befehl Read Temperatur in r16 laden rcall TemOrd ;Befehl EE == Temperaturwandlung starten an Sensor schicken rcall Tempini rcall w0ms4 ldi r16,0xAA ;Befehl Read Temperatur in r16 laden rcall TemOrd ;Befehl an Sensor schicken rcall TemRead ;Funktion bereitstellen, die die Daten aus dem Sensor ließt Ergebnis in r16 rjmp loop ;------------------------------------------------------------------------ ; Warteschleife 4 Micro Sekunden ;------------------------------------------------------------------------ w4mys: push r16 ldi r16,0 w4mys1: inc r16 cpi r16,2 brne w4mys1 pop r16 ret ;------------------------------------------------------------------------ ; Warteschleife 8,75 Mikro Sekunden ;------------------------------------------------------------------------ w8mys: push r16 ldi r16,0 w8mys1:inc r16 cpi r16,6 brne w8mys1 pop r16 ret ;------------------------------------------------------------------------ ; Warteschleife 11 Mikro Sekunden ;------------------------------------------------------------------------ w11mys: push r16 ldi r16,0 w11mys1:inc r16 cpi r16,9 brne w11mys1 pop r16 ret ;------------------------------------------------------------------------ ; Warteschleife 31 Mikro Sekunden ;------------------------------------------------------------------------ w31mys: push r16 ldi r16,0 w31mys1:inc r16 cpi r16,29 brne w31mys1 pop r16 ret ;------------------------------------------------------------------------ ; Warteschleife 200 Micro Sekunden ;------------------------------------------------------------------------ w0ms2: push r17 clr r17 ;einen 3-Byte-Zähler w0ms2u: dec r17 ;niedrigstes Byte -1 brne w0ms2u ;0 erreicht? nein -> Schleife ldi r17,0x08 ;einen 3-Byte-Zähler w0ms2w: dec r17 ;niedrigstes Byte -1 brne w0ms2w ;0 erreicht? nein -> Schleife nop nop pop r17 ret ;------------------------------------------------------------------------ ; Warteschleife 400,75 Micro Sekunden ;------------------------------------------------------------------------ w0ms4: push r17 push r19 ldi r19,0x03 ldi r17,0x0F w0ms4u: dec r17 ;niedrigstes Byte -1 brne w0ms4u ;0 erreicht? nein -> Schleife clr r17 dec r19 brne w0ms4u pop r19 pop r17 ret ;------------------------------------------------------------------------ ; Warteschleife 49,46 Milli Sekunden ;------------------------------------------------------------------------ wait: push r17 push r18 push r19 ldi r19,10 ;r19, r18 und r17 ldi r18,0 ;ergeben zusammen clr r17 ;einen 3-Byte-Zähler wait1: dec r17 ;niedrigstes Byte -1 brne wait1 ;0 erreicht? nein -> Schleife dec r18 ;mittleres Byte -1 brne wait1 ;0 erreicht? nein -> Schleife pop r19 pop r18 pop r17 ret ;Schleifenende, Rückkehr ;------------------------------------------------------------------------ ; Warteschleife 492,81 Milli Sekunden ;------------------------------------------------------------------------ w500ms: push r17 push r18 push r19 ldi r19,10 ;r19, r18 und r17 clr r18 ;ergeben zusammen clr r17 ;einen 3-Byte-Zähler w500u: dec r17 ;niedrigstes Byte -1 brne w500u ;0 erreicht? nein -> Schleife dec r18 ;mittleres Byte -1 brne w500u ;0 erreicht? nein -> Schleife dec r19 brne w500u pop r19 pop r18 pop r17 ret ;Schleifenende, Rückkehr ;------------------------------------------------------------------------ ; Warteschleife ca. 10 Sekunden ;------------------------------------------------------------------------ w10s: push r19 clr r19 w10su: rcall w500ms inc r19 cpi r19,10 brlo w10su pop r19 ret ;------------------------------------------------------------------------ ; TempSensor- PinD5 Out ;------------------------------------------------------------------------ PD5Out: ldi r16,0b00010000 ;PortD Ausgänge auf 0 setzen out portd,r16 ;und Eingang mit Pullup setzen ldi r16,0b01101111 ;PortD0,D1,D2,D3 und D5 (für TempSensor) Ausgänge 1, out ddrd,r16 ;die anderen PortD als Eingänge 0 ret ;------------------------------------------------------------------------ ; TempSensor- PinD5 In ;------------------------------------------------------------------------ PD5in: ldi r16,0b00010000 ;PortD Ausgänge auf 0 setzen out portd,r16 ;und Eingang mit Pullup setzen ldi r16,0b01001111 ;PortD0,D1,D2,D3 und D5 (für TempSensor) Ausgänge 1, out ddrd,r16 ;die anderen PortD als Eingänge 0 ret ;------------------------------------------------------------------------ ; TemperaturSensor- Init ;------------------------------------------------------------------------ tempini: rcall PD5Out ;Controller schickt reset pulse (GND) sbi portd,5 rcall w4mys cbi PortD,5 ;Reset pulse auf Port D Pin 5 rcall w0ms4 ;Reset pulse muss min. 480 Microsek- rcall w0ms2 ;unden lang sein; daher zwei Zeitschleifen rcall PD5in ;Umschalten Port D Pin 5 auf Eingang, um Ant- rcall w31mys ;wort zu empfangen... rcall w31mys rcall w31mys ;Antwort (0 an Pin 5) müßte jetzt anliegen in r16,PIND ;Test der Antwort andi r16,0x20 ;Eingelesenen Port Maskieren cpi r16,0x00 brne noans sbi portd,6 ;Antwort ja dann LED an bei Portd 6 noans: nop ret ;------------------------------------------------------------------------ ; Tempsensor- Read_Time_Slot ;------------------------------------------------------------------------ ReSlot: rcall PD5Out ;Controller schickt reset pulse (GND) cbi PortD,5 ;Reset pulse auf Port D Pin 5 rcall w4mys ;Reset pulse muss min. 1 Microsek- ;unden lang sein rcall PD5in ;Umschalten Port D Pin 5 auf Eingang, um Ant- nop ;wort zu empfangen...Bis hier vergehen 9,25 us nop nop ;seit GND anliegt sind genau 10.00us vergangen ;Antwort (0 an Pin 5) müßte jetzt anliegen in r17,PIND ;Einlesen und testen der Antwort andi r17,0x20 ;Eingelesene Antwort Maskieren lsl r17 ;Ergebnis auf 6.Stelle schieben lsl r17 ;Ergebnis auf 7.Stelle schieben clr r16 or r16,r17 ;Ergebnis mit mit Ergebnisreg. r16 verknüpfen rcall w31mys rcall w11mys rcall w8mys ;Mindestdauer eines Readslots von > 60us erfüllen ret ;------------------------------------------------------------------------ ; Tempsensor- Write_Time_Slot 0 (für ca. 80us 0 auf pind 5) ;------------------------------------------------------------------------ WrSlot0:rcall PD5Out ;Pin D 5 als Ausgang definieren cbi portd,5 ;Pin D 5 -> GND und somit Read Prozess einleiten rcall w31mys ;Pin D 5 für ca 80us auf GND rcall w31mys rcall w11mys rcall w11mys rcall PD5in ;Pin D 5 auf 1 rcall w4mys ret ;------------------------------------------------------------------------ ; Tempsensor- Write_Time_Slot 1 ;------------------------------------------------------------------------ WrSlot1:rcall PD5Out ;Pin D 5 als Ausgang definieren cbi portd,5 ;Pin D 5 -> GND und somit Read Prozess einleiten rcall w4mys ;Pin D 5 für ca 11us auf GND rcall PD5in ;Der Master muss den Bus wieder freigeben rcall w31mys rcall w31mys ret ;------------------------------------------------------------------------ ; Tempsensor- Befehle schicken; Übergaberegister r16 ;------------------------------------------------------------------------ TemOrd: ldi r19,0x01 ;Stellenzähler mov r20,r16 TemOrd0:mov r16,r20 and r16,r19 ;Register entsprechen maskiern um Bit für Bit zu testen tst r16 ;Test ob 1 oder 0 geschrieben werden soll brne TemOrd1 ;Test == 1 dann springe zu TemOrd1 rcall WrSlot0 ;Test == 0 rufe Funktion auf die 0 schreibt rjmp TemOrd3 ;Überspringe nächste Zeile TemOrd1:rcall WrSlot1 ;Rufe Funktion auf die 1 schreibt TemOrd3:lsl r19 ;Make um ein Bit nach links verschieben cpi r19,0 brne TemOrd0 ret ;------------------------------------------------------------------------ ; Tempsensor- Anwort lesen Ergebnis in r16 ;------------------------------------------------------------------------ TemRead:clr r19 ;Stellenzähler clr r16 clr r20 TemRed1:rcall ReSlot ;Ergebnis des Lesens in r16 im MSB (7. Bit Most Significant Bit) or r20,r16 ;Ergebnis in r20 MSB reinkopiern lsr r20 ;r20 nach um eine Stelle nach rechts schieben inc r19 ;Stellenzähler inkrementieren cpi r19,7 ;Schleifendurchlaufzahl prüfen brne temRed1 rcall ReSlot ;MSB auslesen und in r20 reinkopieren es darf hier or r20,r16 ;kein zusätzliches schieben mehr stattfinden mov r16,r20 ;Ergebnis des Auslesens in Register r16 schieben ret