Mach flott den Schrott.
Hier möchte ich ein etwas älteres Projekt nochmal vorstellen.
Ein Nokia Mobiltelefon umgebaut zu einer Temperaturanzeige.
Das Telefon wurde dazu komplett ausgeräumt, nur noch das Display kommt zum Einsatz.
Das Display ist ein Monochromes Grafikdisplay mit 84*48 Pixeln, organisiert als 504*8, angesteuert wird es über SPI.
Es bringt seine eigene Ladungspumpe für die negative Versorgungsspannung mit und braucht nur noch einen externen Kondensator dafür.
Ich habe eine Batteriehalterung und ein eigenes Tastenfeld eingebaut, um die Uhrzeit einstellen zu können.
Der AVR benutzt einen 4MHz Quarz als Taktquelle, da bei 3V der interne Oszillator nicht sicher anläuft.
Einmal pro Sekunde wird die Ladungspumpe gestartet und aus den 3V Versorgung etwa 5V für den DS18s20 erzeugt.
Die 1wire Daten werden mit einer eigenen Routine ausgelesen, Bascom schafft das nur ab einer Mindest-Taktfrequenz von (ich glaube) 2MHz
Es wird die Temperatur, der Temperaturtrend als Pfeil und als Diagramm und der Batteriestatus angezeigt.
Dazu sind verschiedene (abgespeckte) Zeichensätze nötig.
Die Batterie hält sehr lange da der AVR mit 500kHz taktet und zwischendurch in Idle geht.
Im Anhang habe ich die benötigten Dateien gepackt.
Gruß, Michael
Alles anzeigen
Fertig.jpgRueckseite.jpg
Platine.pngInnen.jpg
Hier möchte ich ein etwas älteres Projekt nochmal vorstellen.
Ein Nokia Mobiltelefon umgebaut zu einer Temperaturanzeige.
Das Telefon wurde dazu komplett ausgeräumt, nur noch das Display kommt zum Einsatz.
Das Display ist ein Monochromes Grafikdisplay mit 84*48 Pixeln, organisiert als 504*8, angesteuert wird es über SPI.
Es bringt seine eigene Ladungspumpe für die negative Versorgungsspannung mit und braucht nur noch einen externen Kondensator dafür.
Ich habe eine Batteriehalterung und ein eigenes Tastenfeld eingebaut, um die Uhrzeit einstellen zu können.
Der AVR benutzt einen 4MHz Quarz als Taktquelle, da bei 3V der interne Oszillator nicht sicher anläuft.
Einmal pro Sekunde wird die Ladungspumpe gestartet und aus den 3V Versorgung etwa 5V für den DS18s20 erzeugt.
Die 1wire Daten werden mit einer eigenen Routine ausgelesen, Bascom schafft das nur ab einer Mindest-Taktfrequenz von (ich glaube) 2MHz
Es wird die Temperatur, der Temperaturtrend als Pfeil und als Diagramm und der Batteriestatus angezeigt.
Dazu sind verschiedene (abgespeckte) Zeichensätze nötig.
Die Batterie hält sehr lange da der AVR mit 500kHz taktet und zwischendurch in Idle geht.
Im Anhang habe ich die benötigten Dateien gepackt.
Gruß, Michael
Quellcode
- 'Nokia 3310 Umbau auf Temperaturanzeige
- 'Versorgung über 2x AA Batterien mit Ladungspumpe für DS18S20 Sensor
- 'Quarz 4MHz, ClockDiv8 aktiviert
- 'Autor Michael Kinz bascomforum.de mit besten Dank für die Anregungen
- 'von Michael König www.mkprojekt.de
- 'und die ASM-Programmsequenzen von MagicWhiteSmoke
- 'dieser Quelltext steht unter der CC Lizenz
- 'http://creativecommons.org/licenses/by-nc-sa/3.0/de/
- 'Namensnennung, keine kommerzielle Nutung, Weitergabe nur unter gleichen Bedingungen
- $crystal = 500000
- $regfile = "m88def.dat"
- $hwstack = 64
- $swstack = 128
- $framesize = 80
- $noramclear
- Ddrd.5 = 1 'GND Display
- Ddrd.0 = 1 'Taster GND
- Ddrb.0 = 1 'Data/Command
- Ddrd.6 = 1 'Chip Enable
- Ddrd.7 = 1 'Reset Display
- Ddrc.1 = 1 'Versorgung Spannungsteiler
- Ddrd.3 = 1 'Ladungspumpe PWM
- Ddrd.1 = 1 'Versorgung Ladungspumpe
- Ddrb.4 = 1
- Portc = &B00111100 'Taster Pullup
- Dc Alias Portb.0
- Ce Alias Portd.6
- Re Alias Portd.7
- Lp_power Alias Portd.1
- Sp_teiler Alias Portc.1
- Re = 0 'Dislpay reset
- Waitms 20
- Re = 1
- Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 0
- Config Clock = User
- Config Date = Dmy , Separator = .
- Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
- Start Adc
- 'Sekundeninterrupt
- Config Timer1 = Timer , Prescale = 8
- On Timer1 T1_irq
- Enable Timer1
- Enable Interrupts
- '7,6 kHz für Ladungspumpe
- Tccr2a = &B00010010
- Tccr2b = &B01000001
- Ocr2a = &B00100000
- Ocr2b = &B00010000
- Ce = 0
- Spiinit
- Dim Lsyssec As Long
- Dim Zeigersec As Long
- Dim Ltemp As Long
- Dim Temp As Byte
- Dim Count As Word
- Dim Batt As Integer
- Dim Tempw As Word
- Dim Temp_l As Byte At Tempw Overlay
- Dim Temp_h As Byte At Tempw + 1 Overlay
- Dim Forend As Byte
- Dim Foranf As Byte
- Dim Grafikbreite As Byte
- Dim L_breite As Byte
- Dim Werte(60) As Integer
- Dim Wertzeiger As Byte
- Dim Diamin As Integer
- Dim Diamax As Integer
- Dim Iii As Integer
- Dim B_iii As Byte
- Dim Tempi As Integer
- Dim W_max As Integer
- Dim W_min As Integer
- Dim W_diff As Word
- Dim Graph As Byte
- Dim Xaddress As Byte
- Dim Yaddress As Byte
- Dim Text As String * 14
- Dim Text_a As String * 14
- Dim Sign As String * 1
- Dim Lenght As Byte
- Dim Loops As Byte
- Dim Taster As Byte
- Dim Breite As Byte
- Dim I As Byte
- Dim Zeilenstart As Byte
- Dim Invertiert As Bit
- Dim Sec_flag As Bit
- Dim Startflag As Bit
- Dim Templ As Long
- Declare Sub Address
- Declare Sub Graphic
- Declare Sub Words
- Declare Sub Uhrzeit
- Declare Sub Tasterlesen
- Declare Sub Batterie
- Declare Sub Temperaturanzeige
- Declare Sub Zeiteinstellung
- Declare Sub Kleineanzeige
- Declare Sub Klein_case
- Declare Sub Big_raus
- Declare Sub Kleinraus
- Declare Sub Big_sign_select
- Declare Sub Diagramm
- 'Spannungsgrenzen Batterie in Zehntelvolt
- Const Obergrenze = 310
- Const Untergrenze = 220
- Const Diff = 90
- '############ DS18S20 ###############
- Dim 1w_i As Byte
- Dim 1w_t1 As Integer
- Dim 1w_t As Integer
- Dim Spp(9) As Byte
- Dim Temperatur_str As String * 6
- Dim T_single As Single
- Declare Function Ds1820_get_temp() As Single
- Declare Sub Temperatur_starten
- 'Config 1wire = Portd.2
- 1w Alias Ddrd.2
- 1win Alias Pind.2
- Const L = 1
- Const H = 0
- Call Temperatur_starten
- '######################################
- If Lsyssec < 86400 Then 'wegen Überlauf beim zurückstellen der Uhr
- Lsyssec = 86400
- End If
- Gosub Display_init
- Xaddress = 0 + 128
- Yaddress = 1 + 64
- Call Address
- Text = " Michael Kinz "
- Call Words
- Xaddress = 0 + 128
- Yaddress = 3 + 64
- Call Address
- Text = " Juni 2011 "
- Call Words
- Waitms 450 'für die erste Temperaturmessung
- Startflag = 1
- Zeigersec = -1
- Wertzeiger = 0
- ' ##############################################################################
- ' ############################# Hauptschleife ################################
- ' ##############################################################################
- Do
- Call Uhrzeit
- Disable Pcint0
- Disable Pcint1
- Acsr.7 = 1
- Power Idle 'warte auf die nächste Sekunde im Idle-Mode
- Call Tasterlesen
- Call Zeiteinstellung
- 'Messung alle 10 Sekunden starten
- Temp = _sec Mod 10
- If Temp = 9 Then
- Call Temperatur_starten
- End If
- ' und ausgeben
- If Temp = 0 Then
- Call Temperaturanzeige
- Call Batterie 'Batterie alle 10 Sekunden auch messen
- End If
- Ltemp = Zeigersec Mod 1440 '60 mal pro Tag, alle 24 Minuten bzw 1440 Sekunden
- If Startflag = 1 Then Ltemp = 0 'Beim Start sowieso
- If Ltemp = 0 Then
- Incr Wertzeiger 'Attayzeiger erhöhen
- Werte(wertzeiger) = 1w_t 'aktuelle Temperatur ins Array
- End If
- If Wertzeiger > 59 Then Wertzeiger = 0 'Überlauf vermeiden
- W_max = -200
- W_min = 600
- If 1w_t > W_max Then W_max = 1w_t
- If 1w_t < W_min Then W_min = 1w_t
- For Count = 1 To 60 'Max-Min Werte finden
- If Werte(count) > W_max Then W_max = Werte(count)
- If Werte(count) < W_min Then W_min = Werte(count)
- Next
- If Startflag = 1 Then 'beim Start Array füllen
- For Count = 1 To 60
- Werte(count) = 1w_t
- Next
- Startflag = 0
- End If
- Call Kleineanzeige 'Min-Max Anzeige vor dem Diagramm
- Call Diagramm
- Loop
- End
- '###############################################################################
- '###############################################################################
- '###############################################################################
- Sub Big_raus
- Local B_byte As Byte
- B_byte = 0
- Dc = 1
- For I = 0 To 2 '3 Zeilen bei großen Zeichen
- Yaddress = Zeilenstart + I
- Call Address
- Call Graphic '1 Zeile eines Zeichens ausschieben
- Next
- Dc = 0
- Yaddress = Yaddress - 2
- End Sub
- '----------------------------------------------------------------
- Sub Zeiteinstellung
- 'Taster = Pinc And &B00111100
- ' 60 - nichts gedrückt
- If Taster = 36 Then '2 Taster gleichzeitig
- Gosub Display_init 'Display löschen
- Do
- Call Tasterlesen
- Waitms 30 'Prellen abwarten
- Loop Until Taster = 60 'warten bis losgelassen
- Waitms 30 'Prellen abwarten
- Do
- Call Uhrzeit 'Anzeige Uhrzeit
- Call Tasterlesen
- If Taster = 52 Then 'Taster hoch
- Lsyssec = Lsyssec + 59
- Gosub T1_irq
- End If
- If Taster = 44 Then 'Taster runter
- Lsyssec = Lsyssec - 61
- Gosub T1_irq
- End If
- ' Xaddress = 0 + 128 'Debug
- ' Yaddress = 5 + 64
- ' Call Address
- ' Text = Str(taster)
- ' Call Words
- Waitms 50
- Loop Until Taster = 56 'Taster rechts
- Gosub Display_init 'Display löschen
- End If
- End Sub
- '-----------------------------------------------------------------------------
- Sub Kleineanzeige
- Breite = 4
- Xaddress = 0 + 128
- Yaddress = 4 + 64
- Call Address
- Tempi = W_max
- Call Kleinraus
- Yaddress = 5 + 64
- Call Address
- Tempi = W_min
- Call Kleinraus
- End Sub
- Sub Kleinraus
- If Tempi < 0 Then 'negativ?
- Restore Klein_minus
- Breite = 3
- Call Graphic
- Tempi = Abs(tempi) 'positiv machen
- End If
- If Tempi > 99 Then
- Iii = Tempi / 100
- B_iii = Iii
- Call Klein_case
- Tempi = Tempi Mod 100
- End If
- If Tempi > 9 Then
- B_iii = Tempi / 10
- Call Klein_case
- End If
- B_iii = Tempi Mod 10
- Breite = 1
- Restore Klein_punkt
- Call Graphic
- 'Breite = 4
- 'W_max ausgeben
- Call Klein_case
- Restore Klein_grad
- Breite = 2
- Call Graphic
- 'Grad ausgeben
- End Sub
- Sub Klein_case
- B_iii = B_iii + &H30
- Breite = 4
- '########## MWS ##########
- LDS R17, {b_iii}
- Loadwordadr Font_klein
- !MOVW XL, ZL
- Loadwordadr Char_data
- !Get_Next_Char:
- !LPM R16, Z+
- !CP R16, R17
- !BREQ Got_Match
- !ADIW XL, 4
- !TST R16
- !BRNE Get_Next_Char
- !Got_Match:
- !MOVW R8, XL
- 'Waitus 330
- '########## MWS ##########
- Call Graphic
- End Sub
- '-------------------------------------------------------------------------------
- Sub Diagramm
- W_diff = W_max - W_min 'Diagrammhöhe erfassen
- Incr W_diff
- Xaddress = 22 + 128
- Forend = Wertzeiger + 60
- Foranf = Wertzeiger + 1
- For I = Foranf To Forend 'aktueller Diagrammbereich
- Temp = I
- If Temp > 60 Then Temp = Temp - 60
- Yaddress = 4 + 64
- Call Address
- Tempw = Werte(temp) - W_min 'Array-Werte umrechnen Temperatur -> 0 bis 15
- Tempw = Tempw * 16
- Tempw = Tempw / W_diff
- Temp = 15 - Tempw
- Tempw = 0
- Tempw.temp = 1 'Ausgabe zuweisen
- Dc = 1 'Daten
- Ce = 0
- Spiout Temp_l , 1 'obere Diagrammhälfte
- Ce = 1
- Yaddress = 5 + 64
- Call Address
- Dc = 1 'Daten
- Ce = 0
- Spiout Temp_h , 1 'untere Diagrammhälfte
- Ce = 1
- Incr Xaddress 'nächste Position
- Next
- End Sub
- '-------------------------------------------------------------------------------
- Sub Temperaturanzeige
- T_single = Ds1820_get_temp()
- Text = Fusing(t_single , "#.#")
- Xaddress = 0 + 128
- Yaddress = 1 + 64
- Zeilenstart = Yaddress
- Breite = 0
- Call Address
- Lenght = Len(text)
- Grafikbreite = 0
- For Loops = 1 To Lenght 'Breite der großen zeichen bestimmen
- Sign = Mid(text , Loops , 1)
- Call Big_sign_select
- Read Breite
- Grafikbreite = Grafikbreite + Breite
- Incr Grafikbreite
- Next
- Grafikbreite = Grafikbreite + 20
- Breite = 84 - Grafikbreite
- L_breite = Breite / 2
- L_breite = L_breite + 1 'mitteln und Rand links bestimmen
- Lenght = Len(text)
- For I = 0 To 2
- Yaddress = Zeilenstart + I
- Xaddress = 128
- Call Address
- Dc = 1
- Breite = L_breite
- For Count = 1 To Breite 'Rand links löschen
- Graph = &H00
- Ce = 0
- Spiout Graph , 1
- Ce = 1
- Next
- Next
- Decr Breite
- For Loops = 1 To Lenght 'große Zeichen nacheinander rausschieben
- Sign = Mid(text , Loops , 1)
- Call Big_sign_select
- Xaddress = Xaddress + Breite
- Incr Xaddress
- Read Breite
- Gosub Big_raus
- Next
- Xaddress = Xaddress + Breite
- Incr Xaddress
- Restore Big_grad 'Gradzeichen hinterher
- Read Breite
- Gosub Big_raus
- Breite = 84 - Grafikbreite 'Restbreite ermitteln
- Breite = Breite - L_breite
- Grafikbreite = Grafikbreite + L_breite
- Xaddress = Grafikbreite
- Xaddress = Xaddress + 128
- Breite = L_breite
- For I = 0 To 2 'Restbreite rausschieben
- Yaddress = Zeilenstart + I
- Call Address
- Dc = 1
- For Count = 1 To Breite
- Graph = &H00
- Ce = 0
- Spiout Graph , 1
- Ce = 1
- Next
- Next
- End Sub
- '-----------------------------------------------------------------------------
- Sub Big_sign_select
- Select Case Sign
- Case "0" : Restore Big_0
- Case "1" : Restore Big_1
- Case "2" : Restore Big_2
- Case "3" : Restore Big_3
- Case "4" : Restore Big_4
- Case "5" : Restore Big_5
- Case "6" : Restore Big_6
- Case "7" : Restore Big_7
- Case "8" : Restore Big_8
- Case "9" : Restore Big_9
- Case "." : Restore Big_komma
- Case "-" : Restore Big_minus
- End Select
- End Sub
- Sub Batterie
- Start Adc
- Sp_teiler = 1 'alle 2 Sekunden
- Waitms 2
- Count = Getadc(7) 'Batteriespannung messen
- Sp_teiler = 0
- Stop Adc
- Templ = Count * 100
- Templ = Templ / 299
- Batt = Templ
- Xaddress = 78 + 128
- Yaddress = 64
- Batt = Batt - Untergrenze
- Batt = Batt / 18
- If Batt > 5 Then
- Batt = 5
- End If
- If Batt < 0 Then
- Batt = 0
- End If
- Batt = Batt + 128
- Text = Chr(batt)
- Call Address
- Call Words
- End Sub
- Sub Tasterlesen
- Taster = Pinc And &B00111100
- End Sub
- Sub Uhrzeit
- Xaddress = 0 + 128
- Yaddress = 0 + 64
- Call Address
- Text = Time$
- Call Words
- End Sub
- Function Ds1820_get_temp() As Single
- 1w = L
- Waitus 500
- 1w = H
- Waitus 30
- Bitwait 1win , Set
- Temp = &HCC
- Gosub 1wsend
- Temp = &HBE ' Temperatur auslesen
- Gosub 1wsend
- For Count = 1 To 9
- For I = 0 To 7
- 1w = L
- Waitus 1
- 1w = H
- Waitus 2
- Spp(count).i = 1win
- Waitus 55
- Next
- Next
- Stop Timer2
- Lp_power = 0
- 1w_i = Spp(1) And 1
- If 1w_i = 1 Then Decr Spp(1)
- 1w_t = Makeint(spp(1) , Spp(2))
- 1w_t = 1w_t * 50
- 1w_t = 1w_t - 25
- 1w_t1 = Spp(8) - Spp(7)
- 1w_t1 = 1w_t1 * 100
- 1w_t1 = 1w_t1 / Spp(8)
- 1w_t = 1w_t + 1w_t1
- 1w_t = 1w_t / 10
- ' Temperatur in 0,1 Grad Schritten
- 1w_t1 = 1w_t / 10
- Ds1820_get_temp = 1w_t / 10
- End Function
- Sub Temperatur_starten
- 'Ocr2b = 127 'Taktgeber Ladungspumpe
- Lp_power = 1 'Versorgung Ladungspumpe
- 'Start Timer2
- Tccr2a = &B00010010
- Tccr2b = &B01000001
- 'Ocr2a = &B00010000
- 'Ocr2b = &B00001000
- Ocr2a = &B00100000
- Ocr2b = &B00010000
- Waitms 10
- ' 1wreset
- ' 1wwrite &HCC
- ' 1wwrite &H44
- 1w = L
- Waitus 500
- 1w = H
- Waitus 30
- Bitwait 1win , Set
- ' 1wwrite &H33 Read ROM
- Temp = &HCC
- Gosub 1wsend
- Temp = &H44
- Gosub 1wsend
- End Sub
- 1wsend:
- For I = 0 To 7
- If Temp.i = 0 Then
- 1w = L
- Waitus 55
- 1w = H
- Waitus 1
- Else
- 1w = L
- Waitus 1
- 1w = H
- Waitus 55
- End If
- Next
- Return
- ' ------------------- Sekunden Timer -------------------------
- T1_irq:
- Timer1 = 3036
- Incr Lsyssec
- _sec = Time(lsyssec)
- _day = Date(lsyssec)
- Sec_flag = 1
- Incr Zeigersec
- Return
- Settime:
- Return
- Getdatetime:
- Return
- '---------------- Initialisation Display ----------------------
- Display_init:
- Dc = 0
- Ce = 0
- Ce = 1
- Ce = 0
- Temp = &H21
- Spiout Temp , 1
- Temp = &H06
- Spiout Temp , 1
- Temp = &H13
- Spiout Temp , 1
- 'Kontrast
- Temp = &HC4
- Spiout Temp , 1
- Temp = &H20
- Spiout Temp , 1
- Temp = &H0C
- Spiout Temp , 1
- Ce = 1
- 'Display-RAM löschen
- Xaddress = 0 + 128
- Yaddress = 0 + 64
- Call Address
- Dc = 1
- Temp = &B00000000
- For Count = 0 To 503
- Ce = 0
- Spiout Temp , 1
- Ce = 1
- Next
- Return
- '################# Unterfunktionen für Ausgabe ##################
- Sub Address
- Dc = 0
- Ce = 0
- Spiout Yaddress , 1
- Spiout Xaddress , 1
- Ce = 1
- End Sub
- Sub Graphic
- Local Blub As Byte
- Dc = 1
- Ce = 0
- Blub = 0
- Spiout Blub , 1
- '
- For Count = 1 To Breite
- Read Blub
- Spiout Blub , 1
- Next Count
- Ce = 1
- End Sub
- Sub Words
- Lenght = Len(text)
- For Loops = 1 To Lenght
- Sign = Mid(text , Loops , 1)
- Breite = 5
- '########## MWS ##########
- LDS R17, {Sign}
- Loadwordadr Font_data
- !MOVW XL, ZL
- Loadwordadr Char_data
- !Get_Nexte_Char:
- !LPM R16, Z+
- !CP R16, R17
- !BREQ Gote_Match
- !ADIW XL, 5
- !TST R16
- !BRNE Get_Nexte_Char
- !Gote_Match:
- !MOVW R8, XL
- ' Waitus 330
- '########## MWS ##########
- Call Graphic
- Next Loops
- End Sub
- Char_data:
- Data "0123456789ABCDEFGHIJKLMNZ .,_-:öüaceghilnouvwxyz!)°äö{128}{129}{130}{131}{132}{133}"
- $include "Zeichensatz_5_mod.inc"
- $include "Ms_Sans_Serif_Michael.inc"
- Klein_minus:
- Data &H08 , &H08 , &H08
- Klein_grad:
- Data &H03 , &H03
- Klein_punkt:
- Data &H40
- Font_klein:
- Data &H3E , &H41 , &H41 , &H3E
- Data &H00 , &H42 , &H7F , &H40
- Data &H62 , &H51 , &H49 , &H46
- Data &H22 , &H41 , &H49 , &H36
- Data &H1C , &H12 , &H79 , &H10
- Data &H4F , &H49 , &H49 , &H30
- Data &H3E , &H49 , &H49 , &H30
- Data &H01 , &H71 , &H09 , &H07
- Data &H36 , &H49 , &H49 , &H36
- Data &H06 , &H49 , &H49 , &H3E
Fertig.jpgRueckseite.jpg
Platine.pngInnen.jpg