Forum: Mikrocontroller und Digitale Elektronik PIC 16F688 Timereinstellung / Timerstart


von Stefan F. (stefan84)



Lesenswert?

Hallo zusammen,

ich möchte gerne die Häuser meiner Modelleisenbahn in mehrere Zimmer
unterteilen und dann z.B. wie im beigefügten Code 4 Zimmer in
unterschiedlichen Abständen beleuchten.

Leider bin ich in der Programmierung des PIC 16F688 noch nicht so tief
eingedrungen, dass ich die Einstellungen für den Timer0 vernünftig
hinbekomme. Ich habe mir das Datenblatt schon mehrfach angesehen, aber
ich verstehe den Teil nicht richtig und habe auch schon nach anderen
Erläuterungen im Internet gesucht, aber leider gefunden, die ich
entsprechend in meinem Programm umsetzen kann.

Das Ziel ist, dass immer nach einer bestimmten Anzahl von Sekunden (die
ich in den Code entsprechend eingepflegt habe) ein neuer Status erreicht
werden soll, d.h. das weitere LEDs leuchten bzw. bisherige LEDs nicht
mehr leuchten.

Den Teil bzgl. des Timers habe ich aus einem Programm eines anderen PICs
übernommen und probiert auf meinen PIC 16F688 umzuschreiben, leider aber
anscheinend ohen Erfolg. Das Probelm ist, dass mir keine Fehlermeldungen
beim Simulieren/Brennen angezeigt werden, aber der Aufbau auf dem
Steckboard nicht funktioniert.


Könnt ihr mir bei den Einstellungen für den Timer bitte helfen:


Ich habe euch meinen kompletten Code als Anlage beigefügt.


Probleme habe ich in diesem nachfolgenden Bereich:
1
//Initialisiert den Timer 0 für einen Sekundentakt
2
void initTimer0( void ) {
3
      //Timer 0 ist ein 16-bit-Timer
4
            //Prescaler = 1:256
5
OPTION_REG = 0b00000111;
6
TMR1H = 0x00;
7
TMR1L = 0x00;
8
INTCONbits.GIE = 0;  //Interruptflag zurücksetzen
9
return;  
10
}
11
12
13
//Startet den Timer neu
14
void restartTimer0( void ) {
15
  int timerValue=0;
16
      //mit einem Prescaler von 1:256 ensteht nach einer Sekunde
17
           //ein Überlauf (4 MHz / 256 = 15625 Hz)
18
INTCONbits.GIE = 0;    //Interruptflag zurücksetzen
19
           //Timer Wert für 1s = 65535 - 15625 = 49910 = 0xC2F6
20
TMR1H = 0xC2;          //Das Highbyte muss zuerst
21
           //geschrieben werden.
22
TMR1L = 0xF6;         //Wenn das Lowbyte geschrieben wird,
23
      //wird das Highbyte aktuallisiert.
24
      //Dadurch wird es ermöglicht alle
25
      //16 bit auf einmal zu beschreiben
26
      //TMR0 = 0xC2F6; funktioniert an
27
      //Stelle nicht, da zuerst das
28
      //Lowbyte und dann das Highbyte
29
      //geschrieben wird.
30
INTCONbits.GIE = 1;  //Timer starten
31
return;
32
}
33
34
//wartet für die angegebene Anzahl von Sekunden
35
void wait( int seconds ) {
36
  int i=0;
37
  
38
        //prüft, ob der Timer übergelaufen ist
39
  for( i=0; i<seconds; i++ ) {
40
    restartTimer0();
41
        //warten, bis der Timer übergelaufen ist
42
    while( INTCONbits.GIE == 0 );      
43
  }
44
  return;
45
}

Vielen Dank und viele Grüße
Stefan

von fop (Gast)


Lesenswert?

Du wirfst hier glaube ich 2 Dinge in einen Topf. Genauer gesagt 2 Bits 
bzw. Flags.
Eines sagt aus, ob das Ereignis für einen Interrupt aufgetreten ist und 
das andere legt fest, ob dieses Ereignis auch zu einem Interrupt führen 
soll.
Der große Unterschied für Dein Programm ist also : ersteres wird 
ungefragt gesetzt. Das zweite bleibt so, wie Dein Programm es setzt.
Einen echten Interrupt willst Du ja nicht, denn dann müsstest Du eine 
Routine dafür bereit stellen. Er bringt Dich auch nicht weiter, da Du 
die Zeit bis dahin eh vertrödelst. Also wird das Interrupt Freigabe 
Flag auf 0 gesetzt.
Meist hat es ein E wie enable im Namen.
Das worauf Du warten willst ist das Andere. Meist hat es ein F wie Flag 
im Namen.
Kommen wir zur letzten Hürde : ohne Interrupt wird dieses Flag nur beim 
Überlauf gesetzt. Und dann sitzt es....
Doof, wenn nach einmal einer Sekunde warten alles in einem Rutsch 
abläuft.
Also muss Dein Programm, dieses Flag löschen. Entweder gleich nachdem es 
gesehen hat, dass das Flag gesetzt ist oder bei Deiner Software böte 
sich die Funktion restartTimer0() dafür an.
Damit das nicht so einfach wird, löscht man so Flags oft nicht intuitiv, 
in dem man eine 0 auf sie schreibt. Es soll verhindert werden, dass man 
andere Flags im selben Register mitlöscht. Also gibt es so lustige 
Mechanismen, die Flags löschen, auf die man eine 1 schreibt und dafür 
die, auf die man eine 0 schreibt unangetastet lassen.
Merke Dein PIC kann immer nur 8 Bit auf einmal schreiben. Befehle, die 
Dir vorgaukeln ein Bit zu ändern, ziehen sich 8 Bit rein, beackern eines 
davon und schreiben alle 8 zurück.

von McMix (Gast)


Lesenswert?

Du vermischt Timer0 und Timer1.
Timer 0 ist ein 8 Bit-Timer für den der Prescaler eingestellt werden 
kann.
Dieser Timer wird über Register TMR0 geladen.
Du schreibst aber immer nach TMR1L und TMR1H. Das sind jedoch die 
Register für Timer1. Der kann aber nicht über den Prescaler angesteuert 
werden.
Ausserdem fehlt die Initialiserung für die Timer.
Und wie oben schon beschrieben, mit dem GIE Flag gibst du den Interrupt 
global frei - du kannst dort aber nicht den Überlauf eines Timers 
abfragen.
Das ginge über T0IF bzw. TMR1IF in den entsprechenden Registern.
Ich glaube nicht, dass du das ans fliegen kriegst, ohne dir das 
Datenblatt mal genauer anzuschauen :-)

von Stefan F. (stefan84)


Lesenswert?

Hallo ihr beiden,

vielen Dank für eure beiden Antworten.

Wenn ich euch richtig verstanden habe, dann muss ich mich auf jeden Fall 
mit dem Timer 0 auseinandersetzen, da ich mit Hilfe des Prescaler die 
Sekunden bis zum nächsten Wechsel des Status festlegen möchte. Das ist 
doch so korrekt oder?

Im Datenblatt des PIC 16F688 muss ich mich dann mit den Seiten 45 - 47 
auseinandesetzen oder? Dort ist der Timer 0 beschrieben.

@McMix: Wie genau initialisiere ich den Timer?

Sorry, dass es sich noch um so absolute Anfänger fragen handelt, aber in 
dem PIC-Mikrocontroller Buch, welches ich mir besorgt habe, ist dieses 
leider alles mit einem anderen PIC beschrieben und ich bin in der 
Materie wirklich ein absoluter Neuling.

von Stefan (Gast)


Lesenswert?

Für 10ms sieht es so aus:

void InitTimer0(){
  OPTION_REG   = 0x86;
  TMR0     = 100;
  INTCON   = 0xA0;
}

void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit   = 0;
    TMR0     = 100;
    //Enter your code here
  }
}

von Stefan (Gast)


Lesenswert?

Bei 8MHz sind es ca. 10ms

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefan F. schrieb:
> Leider bin ich in der Programmierung des PIC 16F688 noch nicht so tief
> eingedrungen,

... ich würde mal den simulator im mplab benutzen!
dann kannst du alles im trail and error ausprobieren, da du ja die recht 
einfache beschreibung im data sheet nicht verstehst und auch alles 
andere durcheinander bringst.

von deinem code und der hilflosen beschreibeung ist erkennbar, dass du 
beim programmieren eher auch bei ground zero startest.
daher solltest du mal mehr zeit investieren um dir grundsätzliches 
klarzumachen bevor du den nächsten hilfeschrei hier abgibst.


mt

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefan schrieb:
> Bei 8MHz sind es ca. 10ms

höre auf mit dem klippschule frage-antwort-spiel und erarbeite dir das 
selber!
im simulator kannst du dir auch das timing anschauen und musst hier dann 
nicht jeden mist posten.

das wird so nichts, was du in kurzer zeit zusammen basteln kannst. weil 
du erstmal grundsätzliche funktionen des pic's dir erarbeiten musst.


mt

: Bearbeitet durch User
von Stefan F. (stefan84)


Lesenswert?

Apollo M. schrieb:
> Stefan schrieb:
>> Bei 8MHz sind es ca. 10ms
>
> höre auf mit dem klippschule frage-antwort-spiel und erarbeite dir das
> selber!

Die Frage habe ich gar nicht gestellt, sondern der vorherige Autor hat 
dieses ergänzt. Aber vielen Dank für die Belehrung.

Wie gesagt, fange ich mit der ganzen Thematik gerade erst an.

Leider hat der Simulator von MPLAB keinerlei Fehler ausgewiesen, anhand 
derer ich dann auch meine Einstellungen testen und verbessern könnte.

von fop (Gast)


Lesenswert?

Prinzipiell kann ein 8-bit Timer maximal 256 Mal zählen bevor er 
überläuft, ein 16-bit Timer maximal 65536 Mal.
Wie oft er zählen muss, bis eine Sekunde um ist, hängt von seinem Takt 
ab. Und damit bist Du bei dem IMHO am verwirrendsten in Datenblättern 
beschriebenen Teil : oft über mehrere Kapitel und mit inkonsistenten 
Bezeichnungen.
Wenn der Vorteiler des 8-bit Timers nicht höher als :256 einstellbar 
ist, kommst Du nicht auf längere Zeiten als mit dem 16-bit Timer ohne 
Vorteiler.
Der 8-bit Timer ist dann einfacher bedienbar, die Zeit bis zum Überlauf 
aber nicht so fein abstufbar.
Wenn der Timer alleine nicht auf eine Sekunde kommt, musst Du halt in 
Software mehrere Überläufe abwarten. Nach dem Motto 16 * 61,5 ms + 16 ms 
sind auch eine Sekunde. Die Software hat ja sonst nix zu tun.

von fop (Gast)


Lesenswert?

So, habe mir mal das Datenblatt zu Deinem PIC reingezogen. Würde Dir 
jetzt doch den 16-bit Timer empfehlen. Der 8-bit Timer ist mit dem 
Watchdog verkäkelt.
Die gute Nachricht : Das Flag, ob ein Überlauf des Timers stattgefunden 
hat lässt sich doch ganz intuitiv durch Schreiben einer 0 löschen. Es 
heißt TMR1IF und ist Bit 0 von PIR1.
Das Initialisieren des Timers beschränkt sich fast auf das Setzen des 
T1CON Registers.
Bis ca. 2 MHz Systemtakt sollte der Timer eine Dauer von einer Sekunde 
auf einmal schaffen.
Und da wäre das Problem : welchen Takt nutzt Du ? Hast Du einen Quarz 
angeschlossen ? Wie hast Du die Configuration Bits gesetzt ?

von ... (Gast)


Lesenswert?

> in
> dem PIC-Mikrocontroller Buch, welches ich mir besorgt habe, ist dieses
> leider alles mit einem anderen PIC beschrieben

Die Timer 0, 1 und 2, sind bei den 14 bit PICs nahezu identisch.
Mitunter ist fuer Extrafunktionen noch etwas dazugehaekelt.

Du solltest also das Buch wohl noch mal lesen.

Ob ein Timer zaehlt, sieht man im Simulator, am Stand
des entsprechenden Registerinhalts im Einzelschrittbetrieb.

von fop (Gast)


Lesenswert?

Na, noch am Lesen ? Hier ein ungetesteter Vorschlag von mir :
1
#include "config.h"
2
#include <xc.h>
3
#include <pic16f688.h>
4
/* Zimmerbeleuchtung fuer das Haus */
5
#define RAUM_1a  PORTAbits.RA0
6
/* 1. LED fuer Raum 1 liegt an Port A RA0 */
7
#define RAUM_1b  PORTAbits.RA1
8
/* 2. LED fuer Raum 1 liegt an Port A RA1 */
9
#define RAUM_2a  PORTCbits.RC1
10
/* 1. LED fuer Raum 2 liegt an Port C RC1 */
11
#define RAUM_2b  PORTCbits.RC2
12
/* 2. LED fuer Raum 2 liegt an Port C RC2 */
13
#define RAUM_3a  PORTCbits.RC3
14
/* 1. LED fuer Raum 3 liegt an Port C RC3 */
15
#define RAUM_3b  PORTCbits.RC4
16
/* 2. LED fuer Raum 3 liegt an Port C RC4 */
17
#define DGa      PORTAbits.RA3
18
/* 1. LED fuer DG liegt an Port A RA3 */
19
#define DGb      PORTCbits.RC5
20
/* 2. LED fuer DG liegt an Port C RC5 */
21
/* Status der Beleuchtung der Zimmer */
22
#define EINGANG  0
23
#define EINGANG_KUECHE 1
24
#define EINGANG_KUECHE_AUSGANG 2
25
#define KUECHE_AUSGANG 3
26
#define KUECHE 4
27
#define KUECHE_DG 5
28
#define DG_ABEND 6
29
#define NACHT 7
30
#define DG_MORGEN 8
31
#define KUECHE_DG_MORGEN 9
32
#define KUECHE_MORGEN 10
33
#define KUECHE_EINGANG_MORGEN 11
34
#define KUECHE_EINGANG_AUSGANG_MORGEN 12
35
#define KUECHE_EINGANG_ZWEI 13
36
#define EINGANG_MORGEN 14
37
#define ARBEIT 15
38
/* PROTOTYPES */
39
void allLEDoff(void);
40
void initTimer0(void);
41
void restartTimer0(void);
42
void wait(int seconds);
43
/* HAUPTPROGRAMM */
44
void main(void)     /* hier faengt das Programm an */
45
{
46
    char state = EINGANG;
47
    allLEDoff(); /* alle LED's ausschalten */
48
    TRISA = 0x00;
49
    TRISC = 0x00;
50
    initTimer0(); /* initialisiert den Timer */
51
    while (1)
52
    {
53
        /* Hauptschleife */
54
        switch (state)
55
        {
56
            case EINGANG:
57
                RAUM_1a = 1;
58
                RAUM_1b = 1;
59
                RAUM_2a = 0;
60
                RAUM_2b = 0;
61
                RAUM_3a = 0;
62
                RAUM_3b = 0;
63
                DGa = 0;
64
                DGb = 0;
65
                wait(5);
66
                state = EINGANG_KUECHE;        /* naechster Zustand ist Eingangszimmer und Kueche */
67
                break;
68
            case EINGANG_KUECHE:
69
                RAUM_1a = 1;
70
                RAUM_1b = 1;
71
                RAUM_2a = 1;
72
                RAUM_2b = 1;
73
                RAUM_3a = 0;
74
                RAUM_3b = 0;
75
                DGa = 0;
76
                DGb = 0;
77
                wait(5);
78
                state = EINGANG_KUECHE_AUSGANG;        /* naechster Zustand ist ALLE Zimmer im EG */
79
                break;
80
            case EINGANG_KUECHE_AUSGANG:
81
                RAUM_1a = 1;
82
                RAUM_1b = 1;
83
                RAUM_2a = 1;
84
                RAUM_2b = 1;
85
                RAUM_3a = 1;
86
                RAUM_3b = 1;
87
                DGa = 0;
88
                DGb = 0;
89
                wait(5);
90
                state = KUECHE_AUSGANG;        /* naechster Zustand ist Kueche und Ausgang */
91
                break;
92
            case KUECHE_AUSGANG:
93
                RAUM_1a = 0;
94
                RAUM_1b = 0;
95
                RAUM_2a = 1;
96
                RAUM_2b = 1;
97
                RAUM_3a = 1;
98
                RAUM_3b = 1;
99
                DGa = 0;
100
                DGb = 0;
101
                wait(5);
102
                state = KUECHE;        /* naechster Zustand ist Kueche */
103
                break;
104
            case KUECHE:
105
                RAUM_1a = 0;
106
                RAUM_1b = 0;
107
                RAUM_2a = 1;
108
                RAUM_2b = 1;
109
                RAUM_3a = 0;
110
                RAUM_3b = 0;
111
                DGa = 0;
112
                DGb = 0;
113
                wait(5);
114
                state = KUECHE_DG;        /* naechster Zustand ist Kueche und DG */
115
                break;
116
            case KUECHE_DG:
117
                RAUM_1a = 0;
118
                RAUM_1b = 0;
119
                RAUM_2a = 1;
120
                RAUM_2b = 1;
121
                RAUM_3a = 0;
122
                RAUM_3b = 0;
123
                DGa = 1;
124
                DGb = 1;
125
                wait(5);
126
                state = DG_ABEND;        /* naechster Zustand ist DG abends */
127
                break;
128
            case DG_ABEND:
129
                RAUM_1a = 0;
130
                RAUM_1b = 0;
131
                RAUM_2a = 0;
132
                RAUM_2b = 0;
133
                RAUM_3a = 0;
134
                RAUM_3b = 0;
135
                DGa = 1;
136
                DGb = 1;
137
                wait(10);
138
                state = NACHT;        /* naechster Zustand ist Nacht - alle schlafen */
139
                break;
140
            case NACHT:
141
                RAUM_1a = 0;
142
                RAUM_1b = 0;
143
                RAUM_2a = 0;
144
                RAUM_2b = 0;
145
                RAUM_3a = 0;
146
                RAUM_3b = 0;
147
                DGa = 0;
148
                DGb = 0;
149
                wait(20);
150
                state = DG_MORGEN;        /* naechster Zustand ist DG Morgens */
151
                break;
152
            case DG_MORGEN:
153
                RAUM_1a = 0;
154
                RAUM_1b = 0;
155
                RAUM_2a = 0;
156
                RAUM_2b = 0;
157
                RAUM_3a = 0;
158
                RAUM_3b = 0;
159
                DGa = 1;
160
                DGb = 1;
161
                wait(7);
162
                state = KUECHE_DG_MORGEN; /* naechster Zustand ist DG + Kueche Morgens */
163
                break;
164
            case KUECHE_DG_MORGEN:
165
                RAUM_1a = 0;
166
                RAUM_1b = 0;
167
                RAUM_2a = 1;
168
                RAUM_2b = 1;
169
                RAUM_3a = 0;
170
                RAUM_3b = 0;
171
                DGa = 1;
172
                DGb = 1;
173
                wait(3);
174
                state = KUECHE_MORGEN; /* naechster Zustand ist nur Kueche Morgens */
175
                break;
176
            case KUECHE_MORGEN:
177
                RAUM_1a = 0;
178
                RAUM_1b = 0;
179
                RAUM_2a = 1;
180
                RAUM_2b = 1;
181
                RAUM_3a = 0;
182
                RAUM_3b = 0;
183
                DGa = 0;
184
                DGb = 0;
185
                wait(7);
186
                state = KUECHE_EINGANG_MORGEN; /* naechster Zustand ist Kueche und Eingang Morgens */
187
                break;
188
            case KUECHE_EINGANG_MORGEN:
189
                RAUM_1a = 1;
190
                RAUM_1b = 1;
191
                RAUM_2a = 1;
192
                RAUM_2b = 1;
193
                RAUM_3a = 0;
194
                RAUM_3b = 0;
195
                DGa = 0;
196
                DGb = 0;
197
                wait(5);
198
                state = KUECHE_EINGANG_AUSGANG_MORGEN;        /* naechster Zustand ist alle EG Morgens */
199
                break;
200
            case KUECHE_EINGANG_AUSGANG_MORGEN:
201
                RAUM_1a = 1;
202
                RAUM_1b = 1;
203
                RAUM_2a = 1;
204
                RAUM_2b = 1;
205
                RAUM_3a = 1;
206
                RAUM_3b = 1;
207
                DGa = 0;
208
                DGb = 0;
209
                wait(3);
210
                state = KUECHE_EINGANG_ZWEI;        /* naechster Zustand ist Kueche und Eingang Zwei */
211
                break;
212
            case KUECHE_EINGANG_ZWEI:
213
                RAUM_1a = 1;
214
                RAUM_1b = 1;
215
                RAUM_2a = 1;
216
                RAUM_2b = 1;
217
                RAUM_3a = 0;
218
                RAUM_3b = 0;
219
                DGa = 0;
220
                DGb = 0;
221
                wait(5);
222
                state = EINGANG_MORGEN;        /* naechster Zustand ist Eingangszimmer Morgens */
223
                break;
224
            case EINGANG_MORGEN:
225
                RAUM_1a = 1;
226
                RAUM_1b = 1;
227
                RAUM_2a = 0;
228
                RAUM_2b = 0;
229
                RAUM_3a = 0;
230
                RAUM_3b = 0;
231
                DGa = 0;
232
                DGb = 0;
233
                wait(3);
234
                state = ARBEIT;        /* naechster Zustand ist Arbeit */
235
                break;
236
            case ARBEIT:
237
                RAUM_1a = 0;
238
                RAUM_1b = 0;
239
                RAUM_2a = 0;
240
                RAUM_2b = 0;
241
                RAUM_3a = 0;
242
                RAUM_3b = 0;
243
                DGa = 0;
244
                DGb = 0;
245
                wait(30);
246
                state = EINGANG;        /* naechster Zustand ist Eingangszimmer */
247
                break;
248
            default:
249
                /* sollte nie vorkommen */
250
                RAUM_1a = 1;
251
                RAUM_1b = 1;
252
                RAUM_2a = 0;
253
                RAUM_2b = 0;
254
                RAUM_3a = 0;
255
                RAUM_3b = 0;
256
                DGa = 0;
257
                DGb = 0;
258
                state = EINGANG;
259
                break;
260
        }
261
    }
262
}
263
264
void allLEDoff(void)
265
{
266
    PORTA = 0x00; /* LED's an Port A ausschalten */
267
    PORTC = 0x00; /* LED's an Port C ausschalten */
268
}
269
270
/* Initialisiert den Timer 1 fuer einen Sekundentakt */
271
void initTimer0(void)
272
{
273
    PIE1bits.TMR1IE = 0;    /* Timer Interrupt aus */
274
    T1CONbits.TMR1ON = 0;   /* Timer aus zum Verstellen */
275
    OSCCON = 0b01010001;    /* Takt 2 MHz aus internem Oszillator */
276
    /* Timer 1 ist ein 16-bit-Timer */
277
    T1CON = 0b00110100;
278
    /* Prescaler = 1:8  -> 62,5 kHz */
279
}
280
281
/* Startet den Timer neu */
282
void restartTimer0(void)
283
{
284
    /* Timer Wert fuer 1s ist 65536 - 62500 = 3036 */
285
    T1CONbits.TMR1ON = 0;   /* Timer aus zum Verstellen */
286
    TMR1 = 3036;
287
    T1CONbits.TMR1ON = 1;
288
    PIR1bits.TMR1IF = 0; /* Flag loeschen */
289
}
290
291
/* wartet fuer die angegebene Anzahl von Sekunden */
292
void wait(int seconds)
293
{
294
    int i;
295
    /* prueft, ob der Timer uebergelaufen ist */
296
    for (i = 0; i < seconds; i++)
297
    {
298
        restartTimer0();
299
        /* warten, bis der Timer uebergelaufen ist */
300
        while (PIR1bits.TMR1IF == 0);
301
    }
302
}

von Tobi P. (Gast)


Lesenswert?

https://www.mikroe.com/timer-calculator


"Timer Calculator is a lightweight software which creates timer 
interrupts code for mikroC™, mikroBasic™ and mikroPascal™. ... Pick from 
over 1000 presets or set the desired parameters manually and hit 
“Calculate”."


Ist ganz praktisch und funzt gut, auch mit anderen Conpilern.

von Stefan F. (stefan84)


Lesenswert?

Hallo fop, Hallo Tobi,

vielen Dank für den Quellcode und den Tipp mit dem Timer Calculater. Ich 
werde heute Abend mal den Code testen und mir die Tage dann auch die 
Webseite ansehen.

von Stefan F. (stefan84)


Lesenswert?

Hallo fop,

ich habe den Code getestet. Er war super. Ich habe noch eine kleine 
Ergänzung
1
ANSEL = 0x00;
 vornehmen müssen und seit dem läuft es super. Es funktionieren nur zwei 
I/O Ports nicht, aber das werde ich entsprechend durchtesten und dann 
anpassen.

Noch einmal vielen Dank für deine Hilfe :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.