$regfile = "ATtiny45.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 40
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Dim Timercount As Integer
Config Portb.0 = Output
Config Portb.4 = Input
Portb.4 = 1 ' Pullup active
Gimsk.5 = 1 ' PinChange enable
Pcmsk = &B00010000 ' PB4 change aktiv
Tccr1 = &B00001000 ' Prescale 128
On Pcint0 Readrctime
Portb.3 = 0
Enable Interrupts
Do
Loop
'-----------------------------------------------------------------------
Readrctime:
If Pinb.4 = 1 Then
Tcnt1 = 0
Else
Timercount = Tcnt1
Timercount = Timercount * 10
Pwm0a = Timercount
End If
Return
'------------------------------------------------------------------------
End
' #####################################################################################
' # -----------------------------RSSI2ANA------------------------------------ #
' # Firmware für ATTiny45 zur Auswertung des seriellen Datenstroms eines ACT #
' # DSL-8 DSQ R/C Empfängers um den RSSI (Feldstärke) Wert zu ermitteln und #
' # daraus eine äquivalente 0-1900 mV Analogspannung (0-100% RSSI) für den #
' # RSSI Eingang des EZ OSD zu erzeugen. #
' # #
' # Hinweis: #
' # Diese Programmeinstellungen sind für den DSL-8 geschrieben und bisher nicht mit #
' # anderen Receivern getestet, da diese einen anderen Wert für den RSSI Level #
' # ausgeben. Wenn das RSSI Byte 0-161 ist, sollte es allerdings funktionieren. #
' # #
' # Features: #
' # - Selbstkalibrierend um Bauteiltoleranzen und Umgebungstemperatur zu kompensieren #
' # - I2C Anbindung des DAC #
' # - DAC auf Null setzen bei fehlendem Datenstrom #
' # - LED Anzeige für erfolgreich ausgelesene Daten (1s Blinken) #
' # - LED Anzeige für fehlenden Datenstrom (schnelles Blinken) #
' # - RS232 UART Emulation #
' # - Debug Ausgabe #
' # #
' # Fusebits #
' # - Internal Clock Divider by 8 = OFF #
' # - RSTDISBL =1 - WIRD NUR FÜR DEN DEBUG AUSGANG BENUTZT - KEIN MUSS! #
' # #
' # VORSICHT! Sobald der Reset Pin disabled wurde kann der Baustein nicht mehr mit #
' # einem ISP Programmer gebrannt werden. Nur noch mit einem HV Progger!!! #
' # --------------------------------------------------------------------------------- #
' # (c) 2009 Moscito #
' # Sourcecode und Schaltung frei zur privaten Nutzung #
' # Gewerbliche Nutzung ausgeschlossen ! #
' # #
' #####################################################################################
$regfile = "atTiny45.dat"
$crystal = 8000000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
$lib "i2c_usi.lbx" ' I2C benutzt modifizierte USI Library
Config Scl = Portb.2 ' Ports fuer I2C-Bus definieren
Config Sda = Portb.0
Config Adc = Single , Prescaler = Auto , Reference = 2 'ADC Wandler konfigurieren - interne 2.5V Referenz
Tccr1 = &H00 ' Timer1 Prescaler = Aus (Timer anhalten)
On Timer1 Timer1_isr ' Timer ISR definieren
Dim Datenbyte As Byte
Dim Lastbyte As Byte
Dim Analogwert As Single
Dim Dacout As Integer
Dim Prozent As Single
Dim Adcin As Word
Dim Adcsum As Word
Dim X As Byte
Dim Calib As Single
Dim I2cval As Integer
Dim Max517 As Byte
Dim Cmd_max517 As Byte
Dim Blinker As Integer
' Deklarationen
Max517 = &H58 ' Max517 Slave Adresse
Cmd_max517 = 0 ' Das zweite (Command) Byte beim Max517 ist immer 0
Lastbyte = 1 ' Damit wir bei RRSI = 0 einen Unterschied haben
Declare Sub I2cout(byval I2cval As Integer) ' I2C Ausgaberoutine deklarieren
I2cinit ' I2C Bus initialisieren
Open "COMB.4:38400,8,N,1" For Input As #2 ' Soft UART Eingang konfigurieren
Open "COMB.5:38400,8,N,1" For Output As #1 ' Soft UART Ausgang konfigurieren
' Willkommensmeldung
Print #1 , "" ' im Debug ausgeben
Print #1 , "ACT DSL8 DSQ - RSSI TO ANALOG CONVERTER"
Print #1 , "(C) 2009 Moscito"
Print #1 , ""
Print #1 , "Calibrating ..."
Call I2cout(255) ' Analogausgang auf Maximum zum Kalibrieren
Start Adc ' 254 Messzyklen starten
For X = 1 To 254 ' Analogspannung des Max517 mit ADC einlesen
Adcin = Getadc(3) ' Analogwerte zusammenzählen
Adcsum = Adcsum + Adcin ' Im Debug ausgeben
Print #1 , " " ; Adcin; ' Wir lassen dem ADC ein wenig Zeit
Waitms 20
Next X
Adcsum = Adcsum / 254 ' Mittelwert der gemessenen Analogwerte ermitteln
Print #1 , ""
Print #1 , "AVG ADC: " ; Adcsum ' Im Debug ausgeben
Stop Adc ' ADC anhlten um Strom zu sparen
Calib = Adcsum / 250 ' Kalibrationsfaktor ermitteln für maximale Ausgabe von 1900 mV
Print #1 , "Calibration Factor : " ; Calib ' Im Debug ausgeben
Analogwert = 255 / Calib
Dacout = Analogwert
Call I2cout(dacout) ' Wir testen die Kalibration und geben mal 1900 mV aus
Print #1 , "Testing 100% Output" ' Im Debug ausgeben
Waitms 2000 'Für 2 sec
Call I2cout(0) ' Max517 wieder auf 0 setzen
Print #1 , "Calibration done" ' Im Debug ausgeben
'Wird erst hier konfiguriert, da sonst die DAC Kalibration in die Hose geht, da der LED Output den ADC3 verfälscht
Config Pinb.1 = Output ' LED Ausgabepin konfigurieren
Led Alias Portb.1 ' Spitzname für die LED
Enable Timer1 ' Timer1 einschalten
Enable Interrupts ' Interrupts für Timer1 einschalten
'Safe the Planet
Set Prtim0 'Timer0 deaktivieren
Set Pradc 'ADC deaktivieren
Do ' ****** HAUPTPOGRAMM ******
Datenbyte = Waitkey(#2) ' Datenbyte aus Empfänger einlesen
Tccr1 = &H0F ' Config Timer1 = Timer , Prescale = 16384
If Datenbyte = 255 Then ' Wenn 255 dann weiter
Datenbyte = Waitkey(#2) ' ... und nochmal
If Datenbyte = 255 Then
Datenbyte = Waitkey(#2) ' drei weitere
Datenbyte = Waitkey(#2) ' Datenbytes
Datenbyte = Waitkey(#2) ' auslesen
Datenbyte = Waitkey(#2) ' Das ist jetzt das RSSI Byte
If Datenbyte <> Lastbyte Then ' Änderung im RSSI Signal?
Analogwert = Datenbyte * 1.5838509316770186335403726708075 ' Der Receiver liefert nur Werte von 0 - 161
Analogwert = Int(analogwert) ' Daher Anpassung auf 0 - 255
Dacout = Analogwert / Calib ' Kalibrationsfaktor mit einrechnen
Prozent = Datenbyte / 1.61 ' Umrechnung für Prozentangabe im Debug Terminal
Prozent = Int(prozent) ' Wir basteln uns eine Ganzzahl
Print #1 , "DAC: " ; Dacout ; " (" ; Prozent ; " %)" ' Im Debug ausgeben
Call I2cout(dacout) ' I2C Routine für Ausgabe aufrufen
Lastbyte = Datenbyte ' Wert merken für nächsten Durchlauf
End If
If Blinker > 20 Then ' Bei jedem 20. Durchlauf wird die LED getoggled
Toggle Led ' sind so etwa 0.5s
Blinker = 0 ' (Anzeige für erfolgreichen Datenempfang)
Else
Incr Blinker ' Blinkerzähler hochzählen
Tccr1 = &H00 ' Stoppt Timer1 (Prescaler = 0)
Tcnt1 = &H00 ' Lädt Timer1 mit 0 (Langsames Blinken)
End If
End If
End If
Loop ' ****** ENDE HAUPTPROGRAMM ******
End
Timer1_isr: ' ****** Timer 1 Interrupt Service Routine ******
If Dacout <> 0 Then ' Den DAC bei Datenverlust nur einmal auf Null setzen,sonst spinnt er
Call I2cout(0) ' Max517 wieder auf 0 setzen
Dacout = 0 ' ... und merken ...
End If
Toggle Led ' LED toggeln
Print #1 , "Receiver Data Dropout!" ' Im Debug ausgeben
Tcnt1 = &HBF ' Timer 1 vorladen für schnelles Blinken
Return
Sub I2cout(byval I2cval As Integer) ' ****** Unterprogramm für I2C Ausgabe - I2Cval ist der Beiwert der gesetzt wird ******
I2cstart ' I2C Startbedingung setzen
I2cwbyte Max517 ' I2C Slave Adresse schicken
I2cwbyte Cmd_max517 ' I2C Command (0) schicken
I2cwbyte I2cval ' I2C Wert zum DAC schicken
I2cstop ' I2C Stopbedingung Setzen
End Sub