Hallo,
ich möchte die Drehzahl von einem Förderband mit Hilfe einem
Optoelektronischen Sensor (Schaltfreq = 500 HZ, Ansprechzeit = 1ms)
messen.
Der Sensor ist mit dem Mikrocontroller c167 verbunden.
Erstmal möchte die Zahl der steigenden Flanke in einer bestimmten Zeit
zählen und danach die Drehzahl berechnen.
Wie funktioniert es?
sbit lauf = P3^6;
void main () {
DP2 = 0xffff;
P2 = 0;
T3CON = 0x0249; // load timer 3 control register
T3 = 0x0000; // load timer 3 register
while(lauf){
P2 = T3;
}
T3R = 0;
set_cursor(20,5);
printf("Counter = %4u", P2);
//Wie kann ich die Zahl vonm Zähöer auf Terminal ausgeben?
}
Vielen Dank.
MfG,
Ciek
> Wie kann ich die Zahl vonm Zähöer auf Terminal ausgeben?
Lies nach, wie du printf() auf die serielle Schnittstelle umbiegen
kannst. Üblicherweise geht das über putchar();
Allerdings habe ich den Verdacht, du steuerst mit dieser Funktion schon
ein Display an ( wegen set_cursor(); ).
Lothar Miller wrote:
> Ein Mikrocontroller-Programm hört niemals auf.
Sorry, ich habe nur ein Teil geschnitten.
Welche ist besser, nur ein Timer zählt, wieviele steigende Flanke gibt,
oder mit 2 Timer, ein anderer Timer als Counter.
Ich meinte T3 funktioniert als Timer, und T4(od. T2) funktioniert als
Counter und zählt die Flanke (Bit T3OTL als Zähltakt).
Vielen Dank.
MfG,
Ciek
0x000D ist in binär 00001101 (die letzten acht bit)
Ich gehe mal davon aus du hast irgendwo T2CON auf das GPT12E_T2CON
Register gemappt.
Aber:
Im Manual steht auch die letzten drei Bit sind T2I (Timer Tx Input
Parameter Selection).
Und im Countermode steht das für: "1XX Reserved. Do not use this
combination"
kann dein Fehler daher kommen.
Hallo,
Danke für die Antwort.
T2CON = 0x000D bedeutet:
Timer T2 funktioniert als Ereigniszähler (T2M = 001)
T2 wird inkrementiert, wenn steigende Flanke von T3OTL auftauchen (T2I =
101)
Es ist richtig so oder?
T2CON=0x000D;// 0 0 0 1|101 Counter, steigende Flanke von T30TL
5
T2IC=0x44;// T2IE=1 ILVL=1 GLVL=0
6
T3=0;
7
T2=0;
8
T3R=1;
9
IEN=1;
10
11
while(1){
12
13
set_cursor(13,5);
14
printf("Counter = %5u",T3);
15
set_cursor(14,5);
16
printf("Counter = %5u",T2);
17
}
18
}
Im Terminal sehe ich jetzt, dass T3 von 65536 bis 0 dekrementiert wird.
Wenn ich T2 starte (durch einen Tastendruck im Steuerungsrechner,
T2R=1),
wird der Wert von T2 immer gestiegen.
Wie kann man eigentlich genau mit dem Counter in 65536 Takt zählen?
Vielen Dank für die Hilfe.
MfG,
Ciek
Oh mir ist gerade aufgefallen, dass ich beim letzten mal das falsche
Derivat zugrunde gelegt hatte (habe beim XC167 geschaut). Dann ist mein
zu letzt gegebener Hinweis natürlich Quatsch gewesen.
Ich verstehe nun aber noch weniger was du vorhast. Durch deine
Einstellung, dass T2 incrementiert wenn das T3OTL toggelt, hast du dir
einen schönen 32bit großen Timer gebaut. Mit dem Format T2.T3 Ist auch
prima im Kapitel "Timer Concatenation" im C167 UM beschrieben.
Was willst du genau ermitteln? Die Drehzahl?
Wenn du weißt wieviele Zähne deine Sensorscheibe hat, brauchst du die
nicht zählen. Also benötigst du keinen Counter. Es sei denn du willst
wissen, wie weit sich das Rad/Band gedreht hat.
Zur Drehzahlermittlung benötigst du ein Capture-Interrupt. Das kannst du
beim C167 entweder über die GPT oder über die CapCom machen.
Die Zeit wird je nach Konfiguration automatisch gespeichert. Du brauchst
dann nur noch in der Interruptroutine den Zähler zurück setzen oder
jedesmal die Differenz ausrechnen (Überlauf beachten).
Wenn du T2 als richtigen Zähler benutzen willst, musst du als input die
T2IN auswählen, mit der gewünschten Flanke (T2I = 001, 010 oder 011).
Den Pin als Eingang schalten.
Hallo,
danke für die Antwort.
Ich habe auch den alten Thread gelesen und der Link, den Du gegeben
hast, hilft mir auch.
Die Bandscheibe hat insgesamt 16 Zähne (8 schwarz und 8 weiß). Die
weißen geben HIGH-Flanke aus, denke ich.
Über den Capture Interrupt muss ich noch mehr durchlesen.
Wird nur die Zeit automatisch gespeichert? Woher wissen wir, wenn das
Rad schon einmal umdreht?
Ich werde nachdem Durchlesen nochmal versuchen zu programmieren.
Vielen Dank für die Hilfe.
MfG,
Ciek
T2CON=0x002F;// 00|10 1|111 Capture Mode, beide Flanke von T30TL
13
T2IC=0x44;// T2IE=1 ILVL=1 GLVL=0
14
15
T3=0;
16
T2=0;
17
T3R=1;
18
IEN=1;
19
20
while(1){
21
22
set_cursor(13,5);
23
printf("Counter = %5u",T3);
24
set_cursor(14,5);
25
printf("Counter = %16u",T3IMAGE);
26
}
27
}
Der Timer T2 fängt die Zeit für beide Flanke von T3OTL ab.
Wenn die Scheibe hat insgesamt 16 Zähne, dann muss ich noch die
berechnete Zeit mit 8 multiplizieren.
Habe ich richtig verstanden?
Vielen Dank.
MfG,
Ciek
Hallo Ciek,
Da muss ich nun deinen Sourcecode etwas trennen:
1
WORDT3IMAGE;
2
3
voidT2_INT(void)interrupt0x22{
4
5
T3IMAGE=T2;
6
T3=0;
7
}
sieht richtig aus. Hast du Keil oder Tasking? Leider unterscheiden die
beiden sich im Syntax für die Interruptroutinen. Und da ich Tasking
nutze, kann ich jetzt nicht mit Bestimmtheit sagen, dass es richtig ist.
Ich denke aber du hast das schon irgend woher.
1
voidmain(){
2
3
T3CON=0x0001;// 0 0 0 0|001 Teiler 8*2=16
Kann sein. Der Teiler hat aber nix mit der Anzahl deiner Zähne/Flanken
oder so zu tun. Der bestimmt "nur" deine Auflösung, bzw maximale Dauer.
Dein Timer läuft schon nach 52.5 ms (bei 20MHz cpu Takt) über. Besser
für den Anfang ist eine längere Periode.
1
T2CON=0x002F;// 00|10 1|111 Capture Mode, beide Flanke von T30TL
Zitat aus dem Manual:
The two least significant bits of bit field TxI are used to select the
active transition (see Table 10-8), while the most significant bit TxI.2
is irrelevant for capture mode. It is recommended to keep this bit
cleared (TxI.2 = ‘0’).
also solltest du T2CON = 0x002B setzen.
Das Capture wird nicht durch T3OTL, sondern durch eine Flanke am
T2IN-Pin ausgelöst. Und daran musst du dann deinen Geber vom Band/Rad
anschließen.
1
T2IC=0x44;// T2IE=1 ILVL=1 GLVL=0
2
3
T3=0;
4
T2=0;
5
T3R=1;
6
IEN=1;
7
8
while(1){
9
10
set_cursor(13,5);
11
printf("Counter = %5u",T3);
12
set_cursor(14,5);
13
printf("Counter = %16u",T3IMAGE);
14
}
15
}
Der Rest passt. Sei dir aber bewusst dass deine Ausgabe von T3 asynchron
ist, dh du wirst nicht jeden Wert ausgeben und wenn der Timer sehr
schnell läuft, sieht es so aus als würde der Timer abwärts zählen obwohl
er aufwärts zählt.
>Wenn die Scheibe hat insgesamt 16 Zähne, dann muss ich noch die>berechnete Zeit mit 8 multiplizieren.
Deine Scheibe hat 16 Zähne (16 schwarze und 16 weiße Felder?) mit je
zwei Flanken, das sind dann also 32 Interrupts pro Umdrehung. Wenn du
die Umdrehungszeit pro Umdrehung ausrechnen möchtest, musst du also mal
32 rechnen. Wenn du aber Umdrehung pro Minute oder so Ausrechnen willst,
wird es etwas komplizierter (zu beschreiben).
An deinem Beispiel mit T3I = 001 entspricht ein "Zeitabschnitt" gleich
0,8us (bei 20MHz CPU Takt). Daher entspricht eine Sekunde gleich
1,25x10^6 (1250000) Einheiten. Also würde man die Umdrehung pro Sekunde
wie folgt ausrechnen:
n = 1250000 / (T3IMAGE x 32)
Bzw einwenig optimieren.
Gruß TManiac
Hallo,
> sieht richtig aus. Hast du Keil oder Tasking?
ich nutze Keil Software, also uVision2.
> Besser für den Anfang ist eine längere Periode.
Alles klar, jetzt setze ich T3I=110.
> Der Rest passt. Sei dir aber bewusst dass deine Ausgabe von T3 asynchron> ist, dh du wirst nicht jeden Wert ausgeben und wenn der Timer sehr> schnell läuft, sieht es so aus als würde der Timer abwärts zählen obwohl> er aufwärts zählt.
Ich würde später, die Drehzahl immer ausgeben, sobald die
Geschwindigkeit des Bands geändert wurde. Es könnte funktionieren oder?
> Deine Scheibe hat 16 Zähne (16 schwarze und 16 weiße Felder?) mit je> zwei Flanken, das sind dann also 32 Interrupts pro Umdrehung.
Sie hat insgesamt 16 Felder(Zähne?), 8 schwarze und 8 weiße.
Was ich nicht ganz verstehe, die Capture Mode fängt den Wert von T3 ab,
sobald beide Flanke auftreten. Der Wert ist zwischen 0-65535 (16 Bit).
Dieser Wert wird immer unterschiedlich sein, obwohl das Band mit einer
gleichen Geschwindigkeit läuft.
Vielen Dank.
MfG,
Ciek