C-Control Beispiele


Hier sollen einige typische Beispielprogramme in CC-Basic vorgestellt werden, die sich z.T. aus Anfragen von Lesern ergeben haben. Die Listings sind hier einfach in den Text eingefügt. Man kann sie markieren und über die Zwischenablage direkt in CC-Basic kopieren.

1. Eine Funk-Uhr mit paralleler Ausgabe der Ziffern an Siebensegment-Decoder

Nach einer Idee von Hubert Eichler.

'**************************************
' C-Control/BASIC Parallel3.BAS
'
' Aufgabe:
'
' Ausgabe Minuten und Stunden
' im Parallelmodus, 4 Digits
''**************************************
' --- Definitionen --------------------
define Daten1 byteport[1]
define Daten2 byteport[2]

define Einer byte
define Zehner byte
' --- Programmoperationen -------------
#Loop
Einer = Hour mod 10
Zehner = Hour / 10
Daten1 = Zehner * 16 + Einer
Einer = Minute mod 10
Zehner = Minute / 10
Daten2 = Zehner * 16 + Einer
goto Loop

end

Mit diesem Programm können über insgesamt 16 Leitungen nur vier Ziffern angesteuert werden. Wenn mehr gebraucht werden, kann man Zwischenspeicher 74HC573 (vgl. MSR mit CC-Basic S.148) verwenden. Das Verfahren ist hier für die ersten vier Ziffern gezeigt:

'**************************************
' C-Control/BASIC Parallel2.BAS
'
' Aufgabe:
'
' Ausgabe der Sekunden
' im Parallelmodus mit vier Latches
''**************************************
' --- Definitionen --------------------
define Datenbus byteport[1]
define Latch1 port[9]
define Latch2 port[10]
define Latch3 port[11]
define Latch4 port[12]
define Ausgabe byte
define Einer byte
define Zehner byte
' --- Programmoperationen -------------
#Loop
Einer = SECOND mod 10
Datenbus = Einer
Pulse Latch1
Zehner = Second / 10
Datenbus = Zehner
Pulse Latch2
Einer = Minute mod 10
Datenbus = Einer
Pulse Latch3
Zehner = Minute / 10
Datenbus = Zehner
Pulse Latch4
goto Loop

2. Motorsteuerung mit Stromüberwachung

Nach einer Idee von Norbert Götte

Zwei Motoren sollen mit vier Schaltern in zwei Richungen gesteuert werden. In der verwendeten Mechanik sollen Endschalter eingespart werden. Die Bewegung wird durch Anschläge begrenzt. Durch eine Stromüberwachung soll die Grenze erkannt und der Motor angehalten werden.

Als Basis dient das C-Control Experimenterboard von Modul-Bus (vgl. CC-Anwendungen). Motor 1 liegt zwischen den Leistungsausgängen 1 und 2, Motor 2 zwischen 3 und 4. Die Ausgänge sind gleichzeitig an die (im Board nícht verwendeten) Analogeingänge 5 bis 8 angeschlossen. Es wurde gemessen, dass die erhöhte Eingangsspannung von 12 V problemlos ist. Die Eingänge sind nicht durch Begrenzerdioden geschützt und können eine höhere Spannung vertragen. Außedem sind auf der Unit Schutzwiderstände von 10 k, die eine Überlastung sicher verhindern.

Ein Motor wird eingesschaltet, indem die eine Seite hochgelegt wird, die andere aber tief bleibt. Wegen des endlichen Innenwiderstands der Ausgangstreiber L272 ergibt sich an der Low-Seite eine Spannung von ca. 0,5 V. Bei steigender Belastung, also z.B. wenn der Motor gewaltsam angehalten wird, steigt die Soannung bis über 0, 8 V an. Man kann also hier indirekt den Strom durch den Motor messen und einen Grenzwert festlegen. Das Programm schaltet dann ab. Die Sperre soll bestehen bleiben, bis die entsprechende Taste freigegeben wird.

'**************************************
'
' C-Control/BASIC Motoren.BAS
'
' Aufgabe:
'
' - Zweikanal-Motorschalter mit Endabschaltung
' - bei Überstrom
'
'**************************************
' --- Definitionen --------------------

define Motor1l port[1]
define Motor1r port[2]
define Motor2l port[3]
define Motor2r port[4]
define Motoren Byteport[1]
define S1 port[9]
define S2 port[10]
define S3 port[11]
define S4 port[12]

define Last1l AD[5]
define Last1r AD[6]
define Last2l AD[7]
define Last2r AD[8]
define DA1 DA[1]

define M1l bit[1]
define M1r bit[2]
define Ende1 bit[3]
define Ende2 bit[4]


' --- Programmoperationen -------------

#Loop
' Motor1l = 1 'Einschalten
' pause 25 '0,5 s warten
' Motor1L = 0 'Ausschalten
' pause 25 '0,5 s warten
gosub Tasten
goto Loop 'Endlosschleife


#Tasten
if not (S1 or S2 or S3 or S4) then goto Ende
if S1 then goto Taste1
if S2 then goto Taste2
if S3 then goto Taste3
if S4 then goto Taste4

#Ende
Motoren = 0
Ende1=0
Ende2=0
goto Fertig

#Taste1
if Ende1 then goto Fertig
Ende1 = (Last1r > 75)
if Ende1 then Motor1l=0 else Motor1l = 1
goto Fertig

#Taste2
if Ende1 then goto Fertig
Ende1 = (Last1l > 75)
if Ende1 then Motor1r=0 else Motor1r = 1
goto Fertig

#Taste3
if Ende2 then goto Fertig
Ende2 = (Last2r > 75)
if Ende1 then Motor2l=0 else Motor2l = 1
goto Fertig

#Taste4
if Ende2 then goto Fertig
Ende2 = (Last2l > 75)
if Ende2 then Motor2r=0 else Motor2r = 1
goto Fertig

#Fertig
Pause 2
return

end

3. Online-Messung an allen Analogeingängen

Dieses Programm wurde zur Überprüfung eines speziellen Geräts an der Uni Hamburg benötigt. Außer den acht analogen Eingängen wird auch noch der Frequenzeingang und ein Zähler am IRQ-Eingang gezeigt. Zurm Ansehen der Ergebnisse braucht man ein Terminalprogramm mit 9600 Baud.

'**************************************
'
' C-Control/BASIC Analogtest.BAS
'
' Aufgabe:
'
' - Test aller Analogkanäle
' - Hintergrund-Zaehler mit
' - IRQ-Eingang
' - Gleichzeitige Frequenzmessung
'
'**************************************
' --- Definitionen --------------------

define U1 AD[1]
define U2 AD[2]
define U3 AD[3]
define U4 AD[4]
define U5 AD[5]
define U6 AD[6]
define U7 AD[7]
define U8 AD[8]
define Zaehler Word

' --- Programmoperationen -------------

interrupt Impuls
Zaehler = 0
#Loop
print "K1", U1
Pause 10
print "K2", U2
Pause 10
print "K3", U3
Pause 10
print "K4", U4
Pause 10
print "K5", U5
Pause 10
print "K6", U6
Pause 10
print "K7", U7
Pause 10
print "K8", U8
Pause 10
print "Freq", Freq
Pause 10
print "Interrupt", Zaehler
Pause 200
goto Loop 'Endlosschleife

#Impuls
Zaehler = Zaehler + 1
print Zaehler
return interrupt

end

4. Messung der Genauigkeit der CC-Uhr und 2-MHz Taktsignal

Wie kann man auf die Schnelle mit einem Oszilloskop herausfinden, um wieviel zwei CC-Units in der Geschwindigkeit abweichen? Ganz einfach mit dem 25-Hz-Ausgang TCMP2 am Pin 1 des Prozessors. Die 25-Hz-Signale beider Systeme werden mit einem Zweikanal-Oszi verglichen. Dabei sieht man sehr schnell, wie stark sie aweichen.

Ein Beispiel: Es wurde eine Verscheibung von 2 ms in 35 s gemessen. Umgerechnet ergibt das einen Unterschied von 230 Hz bei 4 MHz oder 57 ppm oder 5 Sekunden am Tag. Zum Vergleich: Normale Quarze werden mit einer Abweichung von +/-50 ppm angegeben, also 200 Hz bei 4 MHz oder 4,3 s am Tag.

Ziel der Untersuchung war hauptsächlich herauszufinden, ob es Situationen gibt, in denen Timer-Interrupts nicht rechtzeitig bedient werden können, in denen also die Uhr Zeit verliert. Das 25-Hz-Signal wird ja in der Interruptroutine per Software gebildet. Daher kann man Abweichungen am Oszi gut sehen. Und in der Tat, zwei solche Situationen wurden gefunden:

Der letzte Punkt war der gesuchte Auslöser des Problems. Zum Stromsparen wurde der Sclowmode gewählt, zum Messen und zum Senden über die RS232 aber der normale Modus. Dadurch ging die Uhr nach.

Wenn man die Genauigkeit absolut messen will, kann man die Quarzfrequenz über einen Frequenzzähler messen. Aber Vorsicht, das Kabel zum Messgerät hat ja auch Kapazität und verstimmt den Oszillator. Ohne Fehler geht es, wenn man 2 MHz an einem Portpin misst. Der Prozessor hat eine spezielle Funktion, die halbe Quarzfrequenz am Port 11 auszugeben. Dazu braucht man nur ein kleines Programm:

'**************************************
'
' C-Control/BASIC ECLK.BAS
'
' Aufgabe:
'
' - Assemblercode im Varablenspeicher
' - Ausgabe von 2 MHz an Port 11
'
'**************************************
' --- Definitionen --------------------

define Data1 Byte '&A1
define Data2 Byte '$A2

define A3 Byte 'Platzhalter
define A4 Byte
define A5 Byte

define n Byte
' --- Programmoperationen -------------


A3 = &H16 'bset 3,7 ; ECLK
A4 = &H07
A5 = &H81 'rts

A3= &H16: sys &HA3 'Takt an
#Loop
goto Loop
end




Das Programm schaltet über ein kleines Maschinenprogramm das Bit ECLK ein (siehe Datenblatt des Prozessors). Das besondere hier: Das Maschinenprogramm befindet sich im RAM, und zwar im Variablenbereich! Diese Möglichkeit habe ich in der CD "CC-Hardware-Erweiterungen" verwendet, um Portzugriffe auf zusätzliche Anschlüsse zu realisieren. Man kann auch selbst-modifizierende Programme schreiben, was im EEPROM nicht geht. Dort wird damit das 2-MHz-Signal moduliert und als Testsender verwendet.


5. Ein Codeschloss mit CC-Basic

Dieses Programm wurde von meinem Sohn Fabian (12 J.) benötigt, um sein Zimmer vor unberechtigten Gästen zu sichern. Es gab schon eine Lösung mit einer Relais-Schaltung, die aber noch verbessert werden musste. Jetzt hat die Anlage neben dem Tastenblock außen noch einen Freigabetaster innen und enen Magnetkontakt an der Tür.

Der Besucher muss einen Zugangscode eingeben, der aus drei Ziffern besteht. Nur mit der richtigen Kombination wird der Zugang freigegeben. Da ein elektrischer Türöffner nur schwer zu installieren ist, wird nur eine Alarmsirene gesteuert. Der Alarm ertönt, wenn entweder die Tür ohne Berechtigung geöffnet wird oder der falsche Code eingegeben wird.

Die Lösung mit C-Control verwendet neben dem Ziffernblock einen Magnetschalter, der an der Tür angebracht ist. Der Kontakt ist geschlossen, wenn die Tür zu ist. Zusätzlich ist an der Innenseite ein Tastschalter angebracht, mit dem von innen der Zugang freigegeben werden kann. Jemand könnte also von außen um Einlass bitten und ihn ohne Kenntnis des Zugangscodes erhalten. Außen am Ziffernblock gibt es noch zwei LEDs. Die rote LED signalisiert Stopp, die grüne den erlaubten Zugang.

Das Programm muss alle Kontakte überwachen. Es soll automatisch aktiv werden, wenn die Tür geschlossen ist. Falls jemand eine Ziffer drückt, wird die richtige Reihenfolge überwacht. Der Einfachheit halber wird hier mit Port 9 begonnen, danach folgt Port 10 usw. Die eigentliche Codierung wird durch den Anschluss der Tasten erreicht. Gleichzeitig muss das Programm zu jeder Zeit den Freigabetaster und den Türkontakt überwachen.

   

















6. Interface-Emulation CCIO und das Anwenderprogramm TurboCompact2000

Das universelle Mess-und Steuerungsprogramm Compact wurde von Hans-Joachim Berndt verbessert und auch für das C-Control angepasst. Das Programm kann in der jeweils neuesten Version auf der Homepage des Autors geladen werden. Eine ausführliche Dokumentation, das Programm und das C-Control Experimentierboard findet man bei Modul-Bus.

Damit das Programm mit C-Control funktioniert, muss die Interface-Emulation CCIO geladen und gestartet werden. Das Programm CCIO.BAS ruft eigentlich nur das Maschinenprogramm CCIOS.S19 auf. Dieses stellt ein eigenes Betriebssystem für die CC-Unit als Interface dar. Damit kann eine PC-Software wie TurboCompact2000 direkt auf die Ports und die Analogeingänge zugreifen. Das Programm CCIO kann hier geladen werden (CCIO.ZIP, 1k). Es ist den Lesern des Buchs "C-Control-Anwendungen" bereits bekannt. Dort findet man nähere Hinweise zum Aufbau des Assemblerprogramms.

Das Basicprogramm CCIO.BAS legt vor dem Start des Interface-Betriebssystems den BytePort 1 als Ausgangsport fest und setzt alle Ausgänge auf Null. Das System ist nun festgelegt auf acht digitale Ausgänge, acht digitale Eingänge, zwei analoge Eingänge und zwei analoge Ausgänge. Eine Erweiterung des Programms mit mehr Eingängen und einer flexiblen Zuordnung der Ports findet man auf der CD "C-Control Hardware-Erweiterungen".


7. Speichererweiterung auf 64 KB

Bisher gab es schon den AT24C256 mit 32 KB für die CC-Unit. Inzwischen ist auch der doppelt so große AT24C512 zu bekommen (Lieferung z.B. über Modul-Bus). Diesen Baustein habe ich mit dem folgenden Programm in der CC-Unit getestet. Es wurden 60 K Daten in den Speicher geschrieben und wieder ausgelesen.. Das Ergebnis: Alles funktioniert problemlos. Von anderer Seite habe ich gehört, dass auch größere Programme (Spezielle DLL für den Compiler erforderlich) mit dem IC klarkommen.

'**************************************
'
' C-Control/BASIC EEPROM64.BAS
'
' Aufgabe:
'
' - Test eines EEPROM 24C512
' - 30000 Worte = 60 K schreiben/lesen
'
'**************************************
' --- Definitionen --------------------

define Ausgang port[1]
define n word
define data word

' --- Programmoperationen -------------

#Loop
Ausgang = 1 'Einschalten
pause 25 '0,5 s warten
Ausgang = 0 'Ausschalten
pause 25 '0,5 s warten

open# for write
for n= 1 to 30000
print# (100+n)
print (100+n)
next n
close#

Ausgang = 1 'Einschalten
pause 25 '0,5 s warten
Ausgang = 0 'Ausschalten
pause 25 '0,5 s warten

open# for read
for n=1 to 30000
input# data
print data
if data = 30000 then Ausgang = 1
next n
close#
end



Nachrag: Lange Programme in C-Control

Im Beispiel werden nur Daten, nicht aber Programme im neu hinzugekommenen Speicher abgelegt. Wenn man Programme mit einer Länge von mehr als 5900 Bytes schreiben will, erzeugt der CC-Basic Compiler eine Fehlermeldung. Man kann dies jedoch verhindern, indem man dem Compiler eine neue DLL unterschiebt, die das Verhalten in diesem Punkt verändert. Die DLL findet man z.B. hier:

http://www.idel-online.de/download.htm


8. RC5-Steuerung mit C-Control

RC5-Fernbedienungen für Fernseher und Videorecorder sind weit verbreitet. Deshalb liegt es nahe, sie auch für andere Zwecke einzusetzen. Aus der CD "C-Control Anwendungen" stammt das folgende Programm zur Steuerung von zwei Relais über die Tasten der Fernbedienung. Die Empfangssignale von einem SFH506 werden über Port 9 gelesen.

'**************************************
'
' C-Control/BASIC RC5_2.BAS
'
' Aufgabe:
'
' - RC5-Relaissteuerung, Adresse 0
' - 2 Relais, 1,2 AN, 4,5 AUS
'
'**************************************
' --- Definitionen --------------------

define Ctr byte 'Bytevar $0A1
define Kon byte 'Bytevar $0A2
define Adr byte 'Bytevar $0A3
define Tas byte 'Bytevar $0A4
Define Relais1 Port[1]
Define Relais2 Port[2]

' --- Programmoperationen -------------

#loop
sys &H0101
if Ctr < 100 then goto loop 'Lesefehler
if Adr <> 0 then goto loop 'Nur Adr 5
if Tas = 1 then Relais1 = 1
if Tas = 2 then Relais2 = 1
if Tas = 4 then Relais1 = 0
if Tas = 5 then Relais2 = 0
if rxd then end
goto loop
end

syscode "RC5.OBJ" 'Code laden

Das zugehörige Maschinenprogramm RC5.Obj findet man hier: CCRC5.Zip (4k)


9. Ansteuerung des DS1820

Bernard Weiler schickte die folgende Berichtigung zum Assemblerprogramm DS1820.ASM aus der CD "C-Control Hardware-Erweiterungen":

; this code was fetched from the "C-control Hardware-Erweiterungen" book CDROM. 
;I fixed some few bugs in assembler.

port .equ $02 ; Port C
portdir .equ $06 ; Datenrichtungsregister
ds18s .equ 7 ; bit 7
ds18smask .equ $80

bas_1 .equ $b7 ; erste Basic Variable => Fehlerrückgabe
bas_2 .equ $b8 ; zweite Basic Variable => Daten Rein&Raus


.ORG $101

reset sei ;mask any intr, as they inject heavy jitter
bclr ds18s,port ; port low
bset ds18s,portdir; Port als Ausgang
lda #$4b ; 4b 75 * 10 5sec => ~750 5sec
jsr delay ; in Warteschleife springen
bclr ds18s,portdir; Port high Z
lda #$08 ; 8 * 10 5sec => ~80 5sec
jsr delay ; warten auf PRESENCE-PULSE-DS1820
lda port
and #ds18smask ; nur bit1, alle anderen maskieren
bne error ; Fehler-Flag setzen
lda #$2d ; erneut 45 * ~10 5sec => ~450 5sec
jsr delay

byte_send lda #$08 ; 08 Bits
sta bas_1
bset ds18s,port
bset ds18s,portdir
byte_send_b bclr ds18s,port; Write 1 Slot ~5 5sec Port 1 Low
clc ; clear Carry bit
ror bas_2 ; in Carry schieben
bcc write0
bcs write1
write0 bclr ds18s,port
bra weiter
write1 bset ds18s,port
weiter lda #$07 ; 7 * ~10 => 70 5sec delay
jsr delay
bset ds18s,port
dec bas_1
bne byte_send_b
cli ;vor jedem rts ein cli nicht vergessen
rts

byte_read lda #$08 ; 08 Bits
sta bas_1
lda #$00
sta bas_2
byte_read_b bset ds18s,port; first set value, then drive, not vice versa
bset ds18s,portdir
bclr ds18s,port
bclr ds18s,portdir
nop ; 14 5sec abwarten
nop ; wenn ein hochkapazitives oder langes Kabel verwendet wird, haben die Dallas Probleme
nop ; von 0 auf highZ in 14us zu kommen. Event muessesn dann mehr nops eingebaut werden.
nop
nop
nop
nop
nop
brset ds18s,port,rot ; Bit in C lesen
rot ror bas_2
lda #$07 ; Gesamtzykluszeit abwarten (~60 5sec)
jsr delay
dec bas_1
bne byte_read_b
bset ds18s,port
bset ds18s,portdir
cli
rts

delay ldx #$02 ; ca. 10 5sec delay
inloop decx
bne inloop
deca
bne delay
rts

error lda #$ff ; Ein Fehler => 255 speichern
sta bas_1
cli
rts

.end

Und hier die passenden Basic-Programme dazu: Kapitel 7 des Handbuchs (ds1820cc.pdf, 38 KB)