
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
> Hallo, > ich möchte meinen Programmablauf teilen. > Es soll den ersten Teil zu 9/10 der Bearbeitungs/Rechenzeit und der zweite Teil den verbleibenden Zeitraum nutzen. > Ich habe diese Möglichkeit der Programmierung schon gesehen , ich weiß nur nicht mehr wo oder in welchem Forum. > > Kann mir jemand auf die Sprünge helfen??????? > > mfg. > G.Bremus > > ' Beispiel zum BASIC-COMPUTER mit dem Programmer/Application-Board '-------------------------------------------------------------------- ' ANWENDUNG: TIMED INTERRUPT ' TASKS IM HINTERGRUND '-------------------------------------------------------------------- ' Der TIMED INTERRUPT ist bei der UNIT M 2.0 erst ab der Betriebsystem ' Version 2.02 verfügbar. Haben Sie eine frühere Version in Betrieb, ' so können sie den TIMED INTERRUPT emulieren, indem sie einen der ' DA-Ports mit dem IRQ-Eingang verbinden. Der PWM-DA Port muss dazu ' in den "SERVO-MODE" geschaltet werden (siehe CONFIG-Register) damit ' die Interruptrate 20ms ist. '-------------------------------------------------------------------- ' Der TIMER INTERRUPT eignet sich hervorragend um Aufgaben (TASKS) die ' im Hintergrund erledigt werden sollen auszuführen. Ausserdem lässt sich ' damit effizient die Rechenleistung der M 2.0 verteilen und ' Aktivität von Programmteilen leicht zeitlich begrenzen. ' So kann z.B. eine Tastaturabfrage nicht wie gewöhnlich in die Programm ' Hauptschleife integriert werden, wo sie viel häufiger als notwendig abgefragt ' wird, sondern sie wird über den TIMER-INTERRUPT abgefragt und dafür eine ' entsprechende Priorität vergeben. Für eine Tastaturabfrage ist z.B. ein ' Zeitabstand von 60ms durchaus ausreichend. Ein anderes Beispiel ist eine Portabfrage ' für eine Alarmanlage, wo ein Zyklus von 0.5s durchaus ausreichend ist. ' ' Dieses Beispiel stellt einen "TASKMANAGER" dar, der im Hintergrund ' 5 TASKS mit festlegbarer Priorität bedient. Der "TASKMANAGER" ' kann natürlich auf mehr TASKS erweitert werden wenn Bedarf besteht. ' Aber hier soll nur gezeigt werden, wie so etwas prinzipiell gemacht wird ' PRIO bestimmt die Priorität für jede TASK: '--------------------------------------------------------------------------- ' FF = CYCLE/1 I 20ms PRIO1 ' FE = CYCLE/2 I 40ms ' FC = CYCLE/4 I 80ms ' F8 = CYCLE/8 I 160ms ' F0 = CYCLE/16 I 320ms ' E0 = CYCLE/32 I 640ms ' C0 = CYCLE/64 I 1280ms ' 80 = CYCLE/128 I 2560ms PRIO8 ' 00 = CYCLE/256 I 5120ms PRIO9 '--------------------------------------------------------------------------- ' Entsprechend oft wird diese Task dann ausgeführt. Die Prioritäten sind als ' Konstanten vordefiniert (PR20 bis PR5120) ' Für PR320 ist die Task also nur jeden 16. Interrupt bzw. alle 320ms aktiv. ' Die BITVARIABLEN TSK0 bis TSK1 aktivieren oder beenden die jeweils zugehörige ' TASK. ' ' Beschreibung: ' In diesem Beispiel, das nur der Demonstration dienen soll haben wir ein ' Rechenintensives Hauptprogramm - in diesem Beispiel ein BENCHMARK um zu ' sehen wieviel das HINTERGRUND-Programm an Rechenleistung abzieht - und ' das Programm im Hintergrund (hier eine Tastaturabfrage und eine Uhr mit Datum) ' Dem Hauptprogramm gehört die Zeile 1 am LCD (BENCHMARK) die Zeile 2 ' gehört den anderen Programmteilen ' ' Die TASK1 - bedient den Tastaturdecoder ( F1= UHRZEIT,F2=Datum) ' Die TASK2 - Schreibt das Benchmark Ergebnis auf das LCd ' Die TASK3 - Schribt das DATUM auf das LCD ' Die TASK4 - Schreibt die Uhrzeit auf das LCD ' die Task5 - Wechselt die Anteige automatisch zwischen Datum und Uhrzeit ' ' Das Programm macht natürlich nicht viel Sinn, demonstriert aber wie der ' TIMER-INTERRUPT sinnvoll einzusetzen ist. ' Sie sehen wie Tasks sich untereinander aktivieren und sich gemeinsame ' Resourcen (hier das LCD) untereinander aufteilen lassen ohne Konflikte ' zu verursachen. ' Ausserdem sehen Sie wie man Rechenleistung auf verschieden Zwecke verteilt. ' Das Programm im Hintergrund (incl. Taskmanager) braucht etwa 7% der gesamt ' zur Verfügung stehenden Rechenzeit ' ' ' Anmerkung: ' Bei dem Beispiel handelt es sich natürlich nicht um echtes Multi-Tasking, ' mit gutem Willen kann man aber durchaus als ähnlich ansehen. '----------------------------------------------------------------------- ' ACHTUNG: ' Als Anwender müssen Sie dafür sorgen, dass Ihre INERRUPT-SERVICE ROUTINE ' keine PRINT Umleitungen öffnet ohne die bestehende vorher geschlossen zu haben. ' Ausserdem müssen Sie sich bewusst sein, dass ein Interrupt zu jedem x-beliebigen ' Zeitpunkt (- beliebige Stelle im Programm) auftreten kann. ' Interrupts können sehr vorteilhaft sein, müssen aber mit viel Sorgfalt bei der ' Programmierung des Anwenderprogrammes eingesetzt werden ' '---------------------------------------------------------------------------- '-------------------------- '------ I/O PORTS --------- '-------------------------- define LIGHT port[16] define ADC8 ad[8] define TEMP ad[1] define LED port[1] '-------------------------- '---- SYSTEM MEMORY ------- '-------------------------- define ACTIVETASKS byte[1] define TSK1 bit[1] define TSK2 bit[2] define TSK3 bit[3] define TSK4 bit[4] define TSK5 bit[5] define PRIO1 byte[2] define PRIO2 byte[3] define PRIO3 byte[4] define PRIO4 byte[5] define PRIO5 byte[6] define SLICES byte[7] '-------------------------- define PR20 &HFF'20 define PR40 &HFE'40 define PR80 &HFC'80 define PR160 &HF8'160 define PR320 &HF0'320 define PR640 &HE0'640 define PR1280 &HC0'1280 define PR2560 &H80'2560 define PR5120 &H00'5120 '-------------------------- define KEYCODE byte[8] define COUNTER byte[9] define ST byte[10] define OLDSEC byte[11] define INSTRUC word[10] define BM word[25] #INIT '--------- INTERRUPT ZIEL DEFINIEREN ------------- gosub SETCONFIG2 interrupt TIMER_INT LIGHT=off:YEAR=4 PRIO1=PR80:PRIO2=PR320:PRIO3=PR640:PRIO4=PR160:PRIO5=PR5120 print"#ON_LCD#";:print"#INIT#"; '------ NORMALBETRIEB TASTATURDEKODER, UHRZEIT ---- TSK1=on TSK4=on TSK2=on TSK5=on '------------------------------------------------- '-- HAUPTPROGRAMM BENCHMARK - '------------------------------------------------- #LOOP gosub BMX BM=INSTRUC goto LOOP '------------------------------------------------- #BMX INSTRUC=0:TIMER=0 #BMXRUN for COUNTER=1 to 5 'INSTRUCTION 1 INSTRUC=INSTRUC+14 'INSTRUCTION 2 ST=ST+1 'INSTRUCTION 3 ST=ST shl 2 'INSTRUCTION 4 goto JUMP 'INSTRUCTION 5 #JUMP looktab tab,0,ST 'INSTRUCTION 6 wait ST=0 'INSTRUCTION 7 gosub JSR 'INSTRUCTION 8+9+10+11 ST=ST*10 'INSTRUCTION 12 if TIMER>50 then return 'INSTRUCTION 13 next 'INSTRUCTION 14 INSTRUC=INSTRUC+2 'INSTRUCTION a goto BMXRUN 'INSTRUCTION b #JSR LED=on:led=off:return '---------------------------------------------- table tab 0 tabend 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 'IIII TASK MANAGER BACKGROUND TASKS IIII 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII #TIMER_INT SLICES=SLICES+1 if ((SLICES and PRIO1)=SLICES) and (TSK1=on) then gosub TASK1 if ((SLICES and PRIO2)=SLICES) and (TSK2=on) then gosub TASK2 if ((SLICES and PRIO3)=SLICES) and (TSK3=on) then gosub TASK3 if ((SLICES and PRIO4)=SLICES) and (TSK4=on) then gosub TASK4 if ((SLICES and PRIO5)=SLICES) and (TSK5=on) then gosub TASK5 return interrupt '----------------------------------------------------- #TASK1' 80ms TASTATURABFRAGE gosub KEYDECODE if KEYCODE=12 then TSK4=on 'UHRZEIT BEI F1 if KEYCODE=12 then TSK3=off ' if KEYCODE=13 then TSK4=off 'DATUM bei F2 if KEYCODE=13 then TSK3=on ' return '----------------------------------------------------- #TASK2' 320 ms Abfrage BENCHMARK Ergebnis print"#L101#";:print"BM= ";:print BM;:print" I/s "; return '------------------------------------------------------ #TASK3' 640ms ALTERNATIVBETRIEB DATUM 'TSK4=off print"#L201#"; 'CURSOR AUF ZEILE 1 POS 5 print" "; if DAY<10 then print"0"; 'FÜHRENDE NULL SCHREIBEN print DAY; 'STUNDEN AUSGEBEN print":"; 'TRENNZEICHEN SCHREIBEN if MONTH<10 then print"0"; 'FÜHRENDE NULL SCHREIBEN print MONTH; print":200"; 'TRENNZEICHEN SCHREIBEN print YEAR; print" "; return '------------------------------------------------------ #TASK4' 640ms NORMALBETRIEB - UHRZEIT 'TSK3=off print"#L201#"; 'CURSOR AUF ZEILE 1 POS 5 print" "; if HOUR<10 then print"0"; 'FÜHRENDE NULL SCHREIBEN print HOUR; 'STUNDEN AUSGEBEN print":"; 'TRENNZEICHEN SCHREIBEN if MINUTE<10 then print"0"; 'FÜHRENDE NULL SCHREIBEN print MINUTE; print":"; 'TRENNZEICHEN SCHREIBEN if SECOND<10 then print"0"; 'FÜHRENDE NULL SCHREIBEN print SECOND; print" "; return 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII #TASK5 '2560 ms if TSK3=on then goto RUN4 if TSK4=on then goto RUN3 return #RUN3 TSK4=off:TSK3=on:return #RUN4 TSK3=off:TSK4=on:return '--UMLEITUNG DER PRINT-FUNKTION AUF DAS CONFIG-MODULE - #SETCONFIG2 print"#ON_CONFIG2#"; 'UMGELEITET put 1 'TIMER INTERRUPT AKTIV print"#OFF#"; 'Umleitung abschalten return '------------------------------------------------------- #KEYDECODE KEYCODE=255:if ADC8<10 then return KEYCODE=0:if abs(17-ADC8)<5 then return KEYCODE=1:if abs(33-ADC8)<5 then return KEYCODE=2:if abs(50-ADC8)<5 then return KEYCODE=3:if abs(66-ADC8)<5 then return KEYCODE=4:if abs(82-ADC8)<5 then return KEYCODE=5:if abs(98-ADC8)<5 then return KEYCODE=6:if abs(114-ADC8)<5 then return KEYCODE=7:if abs(130-ADC8)<5 then return KEYCODE=8:if abs(147-ADC8)<5 then return KEYCODE=9:if abs(164-ADC8)<5 then return KEYCODE=10:if abs(181-ADC8)<5 then return'CLR KEYCODE=11:if abs(199-ADC8)<5 then return'ENTER KEYCODE=12:if abs(218-ADC8)<5 then return'F1 KEYCODE=13:if abs(236-ADC8)<5 then return'F2 KEYCODE=255:return |
| Antwort schreiben |