' ####################################################
' ##### Zisternensensor mit AVR ATtiny2313 ###########
' ####################################################
' (c) 26.06.2012 by Dino
'
' Frequenzmessung und Temperaturmessung fuer
' Zisternenanzeige (Fuellstand und Innentemperatur)
' BASCOM 2.0.7.3
' 58% Flash used
'
'Hardware: PD5/T1 : Oszillatoreingang
' PD4 : 1Wire-Sensor DS18S20 (Temperatur)
' PD0/RxD: Kommandos empfangen 9k6 8n1
' PD1/TxD: Daten senden 9k6 8n1
' Stecker Pin 1+2 = Sensor, heißes Ende (Osc)
' Stecker Pin 3+G = Sensor, kaltes Ende (GND)
' RJ45 Pin 1 = ws/or ------- TxD
' RJ45 Pin 2 = or - GND
' RJ45 Pin 3 = ws/gn ------- RxD
' RJ45 Pin 4 = bl - GND
' RJ45 Pin 5 = ws/bl ---- +UB
' RJ45 Pin 6 = gn - GND
' RJ45 Pin 7 = ws/bn ---- +UB
' RJ45 Pin 8 = bn ---- +UB
' RJ45 Schirm = Draht - GND
' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
' Systemtakt von 20MHz (externer Quarz)
$crystal = 20000000
$hwstack = 48
$swstack = 8
$framesize = 28
$noramclear
' ####################################
' ##### DEFINITION DER VARIABLEN #####
' ####################################
'
' Array fuer den 1Wire-Sensor
Dim Ds18s20(9) As Byte ' Array fuer Scratchpad
' Variablen fuer DS18S20 Temperatur
Dim Ds_count As Byte ' Zaehler fuer Scratchpad bearbeiten '
Dim Deg_lo As Byte ' unteres Temperaturbyte
Dim Deg_hi As Byte ' oberes Temperaturbyte
' Variablen fuer Frequenzmessung
Dim Ticks As Word ' Zaehler fuer Messinterfall in 1ms-Ticks
Dim Cnt_lo As Byte ' Wert des Low-Bytes vom 16Bit-Timer 1
Dim Cnt_hi As Byte ' Wert des High-Bytes vom 16Bit-Timer 1
Dim Cnt_ovf As Word ' Wert vom 16-Bit Ueberlaufzaehler fuer 16Bit-Timer 1
Dim T1ovf As Word ' 16-Bit Ueberlaufzaehler fuer 16Bit-Timer 1
Dim Temp As Byte ' Temporaere Byte-Variable fuer alles moegliche
' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' DDR => 0-Bit = Eingang / 1-Bit = Ausgang
' PORT => 0-Bit = PullUp aus / 1-Bit = PullUp an (bei Eingang)
' PD0 -------<---- UART RxD | UART
' PD1 --------->-- UART TxD | TTL-Pegel
' PD2/INT0 --
' PD3/INT1 --
' PD4/T0 ----<->-- 1Wire-Bus (Timer0 = 8Bit)
' PD5/T1 ----<---- Mess-Oszillator (Timer1 = 16Bit)
' PD6/ICP1 --
'
' ===== PortD =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= O=1= I=0= => 00000010 => DDRD
' ---- ---- T1 1Wir ---- ---- TxD RxD => 11111101 => PORTD (init)
' | | | | | | | |
'
Ddrd = &B0000_0010
Portd = &B1111_1101
' PB0 --
' PB1 --
' PB2 --
' PB3 --
' PB4 --
' PB5/SDA -------- MOSI |
' PB6 ------------ MISO | ISP-Port
' PB7/SCL -------- SCK |
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRB
' ISP ISP ISP ---- ---- ---- ---- ---- => 11111111 => PORTB (init)
' | | | | | | | |
'
Ddrb = &B0000_0000
Portb = &B1111_1111
' PA0 -- XTAL1 | Systemquarz
' PA1 -- XTAL2 | 20,000MHz
' PA2 -- RESET
'
' ===== PortA =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRA
' ---- ---- ---- ---- ---- Rst XTl1 XTl2 => 11111111 => PORTA (init)
' | | | | | | | |
'
Ddra = &B0000_0000
Porta = &B1111_1111
' ===== UART (TTL) initialisieren =============================================
Config Com1 = 1200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
' Config Serialin = Buffered , Size = 4 ' Buffer kostet wertvolles SRAM
Open "com1:" For Binary As #1
' Clear Serialin ' Braucht man ohne Buffer auch nicht
' ===== 1Wire-Bus DS18S20 Temperatursensor ====================================
Config 1wire = Portd.4
' ===== Timer Initialisieren ==================================================
Config Timer0 = Timer , Prescale = 256 ' Timer0 liefert die Messzeit (1sec)
On Ovf0 Tim0_isr
Config Timer1 = Counter , Edge = Falling , Prescale = 1 ' Timer1 zaehlt die Eingangstakte
On Ovf1 Tim1_isr
Enable Timer0 ' Timer starten
Enable Timer1 ' Timer starten
Waitms 100 ' kleine Wartezeit
Print #1 , "Ready" ' Startmeldung ueber UART senden
Waitms 100 ' nochmal etwas warten
Temp = 1 ' Flag Auf "Messung läuft nicht" setzen
' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do
' Damit man mit dem "Wait 1100" nicht unnoetig Zeit verbrennt habe ich das Messende nun ueber ein Flag
' anzeigen lassen. Nun kann man waehrend der Messzeit auch noch was anderes machen.
If Temp = 0 Then ' Test ob die Messung zu Ende ist
' Die Messung laeuft noch
' Ischarwaiting(#1)
' inkey(#1)
' ===== Messungen ausschalten ===== Character "e" (ende)
' Disable Interrupts
' Temp = 0
' Senden "EE EE EE EE EE EE EE EE EE EE ...."
' ===== Messungen einschalten ===== Character "a" (anfang)
' Gosub Ds18s20_mess ' 1Wire Messung starten - der Chip arbeitet alleine weiter
' Senden "AA AA AA AA AA AA AA AA AA AA ...."
' Temp = 0 ' Temp als Flag nutzen : Messung noch nicht fertig
' ----- Frequenz-Messung starten -----
' Ticks = 0 ' Timer0-Ticks initialisieren
' Enable Interrupts ' Interrupts für Frequenzmessung anschalten
' ' Die Frequenzmessung sollte nach 1 sec beendet sein.
' und damit die Interrupts auch wieder abgeschaltet (siehe ISR)
'
Else ' Frequenz-Messung ist zu Ende
Gosub Ds18s20_temp ' 1Wire Temperatur abfragen (vom letzten Messzyklus)
Gosub Ds18s20_mess ' 1Wire Messung starten - der Chip arbeitet alleine weiter
' Uebertragung der Daten ueber UART (1k2 8n1) im Binaerformat mit crlf (0D 0A) als Endmarke
' gesamt : 13 Byte => 26 Chr in Hex ... + Ende-Zeichen crlf (0d 0a)
' Daten des Temperatursensors (Scratchpad des DS18S20) ausgeben (9 Byte => 18Cht r in Hex)
For Ds_count = 1 To 9
' Printbin #1 , Ds18s20(ds_count); ' Scratchpad auf UART ausgeben
Print #1 , Hex(ds18s20(ds_count)); ' Scratchpad auf UART als HEX ausgeben
Next
' 32Bit Frequenzmessung ausgeben (4 Byte => 8Chr in Hex)
Temp = High(cnt_ovf)
' Printbin #1 , Temp; ' Frequenzmessung auf UART ausgeben (Bits 31-24)
Print #1 , Hex(temp); ' Frequenzmessung auf UART als HEX ausgeben (Bits 31-24)
Temp = Low(cnt_ovf)
' Printbin #1 , Temp; ' Frequenzmessung auf UART ausgeben (Bits 23-16)
' Printbin #1 , Cnt_hi ; Cnt_lo ' Frequenzmessung auf UART ausgeben (Bits 15-0)
Print #1 , Hex(temp); ' Frequenzmessung auf UART als HEX ausgeben (Bits 23-16)
Print #1 , Hex(cnt_hi) ; Hex(cnt_lo) ' Frequenzmessung auf UART als HEX ausgeben (Bits 15-0)
Temp = 0 ' Temp als Flag nutzen : Messung noch nicht fertig
' ----- Frequenz-Messung starten -----
Ticks = 0 ' Timer0-Ticks initialisieren
Enable Interrupts ' Interrupts für Frequenzmessung anschalten
' Waitms 1100 ' Die Frequenzmessung sollte nach 1,1sec beendet sein.
' und damit die Interrupts auch wieder abgeschaltet (siehe ISR)
End If
Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################
' ============================================
' ===== Sub fuer DS18S20 Messung starten =====
' ============================================
Ds18s20_mess:
' ===== Befehlsbytes =====
' SEARCH ROM [F0h]
' READ ROM [33h]
' MATCH ROM [55h]
' SKIP ROM [CCh]
' ALARM SEARCH [ECh]
' CONVERT T [44h]
' WRITE SCRATCHPAD [4Eh]
' READ SCRATCHPAD [BEh]
' COPY SCRATCHPAD [48h]
' RECALL E2 [B8h]
' READ POWER SUPPLY [B4h]
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &H44 ' Temperaturmessung starten
Return
' ================================================
' ===== Sub fuer DS18S20 Temperatur einlesen =====
' ================================================
Ds18s20_temp:
' ===== Scratchpad =====
' 1. Byte 0 - Temperature LSB
' 2. Byte 1 - Temperature MSB
' 3. Byte 2 - TH Register or User Byte 1 <-> TH Register or User Byte 1
' 4. Byte 3 - TL Register or User Byte 2 <-> TL Register or User Byte 2
' 5. Byte 4 - Reserved (FFh)
' 6. Byte 5 - Reserved (FFh)
' 7. Byte 6 - COUNT REMAIN
' 8. Byte 7 - COUNT PER deg
' 9. Byte 8 - CRC8
' ===== Seriennummer / ROM-Code =====
' 8-BIT CRC , 48-BIT SERIAL NUMBER , 8-BIT FAMILY CODE (10h)
' ===== Temperaturberechnung =====
' After reading the scratchpad, the TEMP_READ value is obtained
' by truncating the 0.5°C bit (bit 0) from the temperature data
' TEMPERATURE = TEMP_READ - 0,25 + ( COUNT_PER_C - COUNT_REMAIN ) / COUNT_PER_C
'
1wreset ' 1Wire-Bus zuruecksetzen
1wwrite &HCC ' Alle 1Wire-Devices ansprechen
1wwrite &HBE ' Scratchpad einlesen
Ds18s20(1) = 1wread(9) ' diese Version spart etwas Flash (85% zu 87%)
' For Ds_count = 1 To 9
' Ds18s20(ds_count) = 1wread() ' Scratchpad in Array uebertragen
' Next
' die naechsten 4 Zeilen brauch ich eigentlich nicht wenn ich sowieso immer das ganze Scratchpad sende
' dann kann auch der empfangende ATmega die CRC pruefen.
If Ds18s20(9) = Crc8(ds18s20(1) , 8) Then ' Wenn CRC8 korrekt dann Temperaturwerte sichern
Deg_lo = Ds18s20(1) ' Temperatur LSB
Deg_hi = Ds18s20(2) ' Temperatur MSB
End If
Return
' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist das Gate fuer die Frequenzmessung
Tim0_isr:
Timer0 = 178 ' Initialisierung fuer 1ms Takt (Prescaler 256)
Incr Ticks ' 1ms-Ticks zaehlen
If Ticks = 1 Then ' beim ersten Tick ...
Timer1 = 0 ' Timer1 fuer Taktzaehlung initialisieren
T1ovf = 0 ' und Timer1-Ueberlaufszaehler auf 0
End If
If Ticks = 1001 Then ' 1sec Messzeit ist vorbei -> Werte sichern
Cnt_lo = Tcnt1l ' Frequenz LSB (Byte 1) - Timer1 LowByte
Cnt_hi = Tcnt1h ' Frequenz (Byte 2) - Timer1 HighByte
Cnt_ovf = T1ovf ' Frequenz MSW (Byte 3+4) - Timer1-Ueberlaufszaehler
Disable Interrupts
Temp = 1 ' Temp als Flag nutzen : Messung ist jetzt fertig
End If
Return
' ================================================
' ===== ISR fuer Timer1 Overflow =================
' ================================================
' Timer1 ist der Zaehler fuer die Frequenzmessung
Tim1_isr:
Incr T1ovf ' Ueberlauf vom 16Bit-Timer (Byte3+4) bearbeiten
Return
' ###############################################
' ##### Programm Ende ###########################
' ###############################################
Close #1
End
' - - - - - - - - - - - - - - - - S C H L U S S - - - - - - - - - - - - - - - - - - -