nochmal als Text: (sicherheitshalber ;--))
'S88_Rückmelder mit AtTiny2313 V1.4 180916, V1.0 180912, PRG zu S88-Keyboard von Wolfgang Kufer, Pinbelegung wie Original-Schaltplan
'--------------------------------------------------------------------------------------------------------------------------------------------------
$regfile = "ATtiny2313.DAT" 'Chip-Deklarationen
$crystal = 8000000 'int. Oszilator, ohne Teiler, 8000000 ist 'maximum für int. OSC
$hwstack = 32 'default use 32 for the hardware stack
$swstack = 8 'default use 8 for the SW stack
$framesize = 16 'default use 16 for the frame space
Acsr.acd = 1 'Analogen Comparator ausschalten, alternativ: Stop ADC
Ddrd = &B0000_0001 '1 = Ausgang, 0 = Eingang, PD0 ist LED, pd7 gibt es nicht
Portd = &B0111_1110 'PullUp's EIN
DDRa = &B0000_0000 'bis jetzt ungenutzt (Port 1,2 sind XTAL), 2=Reset gibt nur Porta0 bis a2
PORTa = &B0000_0111 'PullUp's
Ddrb = &B0100_0000 ' (7,6,5 sind MISO/MOSI)
Portb = &B1011_1111 'PullUp, PB6=Dout, Pb4=load, Pb5=Din, Pb7=S88-Clk
'Config COM1=dummy,synchrone=0,parity=none,stopbits=1,databits=8,clockpol=0 'Bei asynchron/8N1 unnötig
'Config Serialin = Buffered , Size = 10
'Ausgänge -----------------------------------------------------------------------------------------------------------------------------------
Dout Alias Portb.6 'Data OUT
Led Alias Portd.0 'LED zur Funktions-Anzeige
'Eingänge --------------------------------------------- 'S88_Reset wird nicht gebraucht, muß nicht angeschlossen werden -----------------
Sclk Alias Pinb.7 'S88_Clock
Sload Alias Pinb.4 'S88_Load
Din Alias Pinb.5 'Data IN
k7 Alias Pind.3 'Key-1 Low-Aktiver Eingang, intern vorgespannt
k6 Alias Pind.4 'Key-2
k5 Alias Pind.5 'Key-3
k4 Alias Pind.6 'Key-4
k3 Alias Pinb.0 'Key-5
k2 Alias Pinb.1 'Key-6
k1 Alias Pinb.2 'Key-7
k0 Alias Pinb.3 'Key-8
'Variablen --------------------------------------------------------------------------------------------------------------------------------------------
CONFIG BASE=0 '=> Arrays starten bei 0,1,2... (und nicht bei 1,2,3 ...) wegen Byte-Zugriff auf Variable
Dim s_reg as Byte ' Schiebe-Register mit 8 Bit
Dim kp(8) As Byte ' Key-Puffer 0 bis 7 , zum Aufsummieren beim Eingang-Scannen
Dim kh(8) As Byte ' Key-Hold 0 bis 7 , zum Verlängern des Eingangsimpulses (original=1sek), optimal 0,5 -0,7 sek ?
Dim Sc_m as Byte ' S88-Clock-Memory (war gerade 0 oder 1-Phase)
Dim x as byte ' Zähler
Const k_s = 100 ' Key-Schwelle, ab wann der Eingang als aktiv gewertet wird, momentan ca. 256 Scans / Zyklus ? jetzt deutlich besser, unempfindlicher
'-------------------------- 8Bit-Timer0 ---------------------------------------------------------------------------------------------------------------
'Config Timer0 = timer , Prescale = 1024 '3,6864 MHz/ 1024 /256 (ovfl) = 14,0625 mal pro sekunde (Hz)
'on OVF0 Wachhund 'Timer0 OverFlow
'Enable ovf0
'--------------------------- 16Bit-Timer1 ----timer -------------------------------------------------------------------------------------------
'Config Timer1 = Pwm , Pwm = 8 , Compare_A_Pwm = Clear_Up , Prescale = 1024
'Pwm1a = 100 'Frequenzausgabe: 'bei 8.000.000 Systemtakt /64 = 125 KHz /100 im CompareRegister=16Bit! /2 (toggle) => 625 mal pro sek.
'Config Timer1 = Timer , Prescale = 1024 , Clear_Timer = 1 '3,6864 MHz/ 1024 /256 (compare) = 14,0625 mal pro sekunde (Hz)
'Config Timer1 = Timer , Prescale = 64 , COMPARE_A = toggle, COMPARE_B = DISCONNECT 'bei 8.000.000 Systemtakt / 64 = 125 KHz / 60.000 => 2,08 mal pro sek.
'Compare1a = 9000 'hier kein Interrupt, sondern Frequenzausgabe an OC1a (PWM-Pin)
'Config Timer1 = Timer , Prescale = 1024 '3,6864 MHz/ 1024 /65535 (overflow) = 3,295 mal pro MINUTE
'on OVF1 Zeitschleife 'Timer1 OverFlow
'Enable ovf1 'kein Timer1 Int. bei compare1a
'
'----------- sonst. Interrupts -------- Brown OUT - einrichten mit den FUSES !!!!! ------------------------------------------------------------------------
'Mcucr = &B00110000 'unbedingt vor den weiteren Interupt-Settings 'Bits6,4: PowerDown-Mode Bit5 = 1 -> Sleep enable, Bit0,1 steuern Int.-Sense (00 = Low Level..)
'Config Int0 = RISING 'Hier: wenn LED an Empf.-Modul = high sonst: 'nur ein low-Level Interrupt funktioniert zum Aufwachen aus Power Down !!!! (Dies ist eigentlich im MCUCR mit Bits0,1=0enthalten)
'On Int0 Interrupt0 'Enable Int0 '
'
'-----------------------INIT------------------------------------- Initialisierung -----------------------------------------------------------------
disable Interrupts 'erstmal keine 'Enable Interrupts
'reset Led : wait 1 : set Led
'============================================================ Hauptprogramm ======================================================================
Main:
if Sclk = 1 and Sc_m = 0 then 'vorher war Down
waitus 5
if Sclk = 1 then gosub flanke_up 'Flanke UP
end if
if Sclk = 0 and Sc_m = 1 then 'vorher war UP
waitus 5
if Sclk = 0 then gosub flanke_down 'Flanke Down
end if
waitus 2 '50 mal Abtasten eines Clockpuls ? bei Z1-Wert=9 ist ein Clockpuls ca. 0,1 ms = 100 us (manchmal auch wesentlich länger)
Goto Main
End
'------------ Flanke - UP ----------------------------------------------------------------------------------
flanke_up:
if Sload =1 then 'neuer Zyklus ?
nop
nop
nop
if Sload =1 then 'neuer Zyklus !
toggle led 'kurzer Led-Flash wenn OFF, sonst ON je Eingang
gosub writekeys
toggle led
endif'
else
s_reg.0 = Din 'Data-In holen und in Schiebe-Register
x=0
nochmal:
nop
nop
if din <> s_reg.0 and x < 2 then
s_reg.0 = Din
incr x
goto nochmal
endif
end if
Sc_m = 1
return
'------------ Flanke - DOWN ----------------------------------------------------------------------------------
flanke_down:
Dout = s_reg.7
shift s_reg, left 'jetzt hier schieben, dadurch auch kein Zwischenspeicher für Dout nötig (und Platz für Din)
Sc_m = 0 'Merker setzen, wir sind in Zero Clock-Phase
gosub readkeys 'jetzt hier, besser bei Flanke DOWN aufrufen => ca. 256mal pro Zyklus (bei 32 Byte)
return
'------------ Eingänge lesen ----------------------------------------------------------------------------------
readkeys:
if k0 = 0 then incr kp(0) 'Key-Puffer rauf
if k1 = 0 then incr kp(1)
if k2 = 0 then incr kp(2)
if k3 = 0 then incr kp(3)
if k4 = 0 then incr kp(4)
if k5 = 0 then incr kp(5)
if k6 = 0 then incr kp(6)
if k7 = 0 then incr kp(7)
for x = 0 to 7
if kp(x) > 250 then kp(x) = 250 'Begrenzung
next
return
'------------ Eingänge schreiben --- in s_reg Schieberegister ----------------------------------------------------------------------------------
writekeys:
s_reg = 0 'alle Bits löschen
for x = 0 to 7
if kp(x) > k_s then kh(x) = 1 'aktiver Eingang ist größer Schwelle, aktiviert/startet neu den Key-Hold
if kh(x) > 0 then incr kh(x) 'wenn key active ist, dann Key-Hold erhöhen
if kh(x) > 10 then kh(x) = 0 'Key-Hold Time ist abgelaufen, rücksetzen (15 ist etwa 1 sek, => 14 x Zykluszeit)
if kh(x) > 0 then s_reg.x = 1 'aktiver/gehaltener Eingang in Schiebe-Register setzen
kp(x) = 0 'Rücksetzen des Eingangs-Summierers
next x
if s_reg > 0 then set led else reset led
return
'------------------------------------------------------------------------------------------
end