Hallo,
ich benutze einen Mica2dot Mote von Crossbow, der mit dem Atmega 128L
bestückt ist. Der Prozessor wird mit 4MHz getaktet. Als
Programmierplattform nehme ich tinyOS. Ich möchte eine Frequenzmessung
eines Rechtecksignals vornehmen, das am INT0 angeschlossen ist und bei
jeder aufsteigender Flanke einen HardwareInterrupt auslöst. Die
aufsteigenden Flanken sollen jeweils 15ms lang gezählt werden (ich
brauche das resultat nicht in Hz). Die Zählwerte werden zunächst im
Speicher gehalten und am Ende gemeinsam über UART ausgegeben.
Das Problem, das ich habe, ist, dass das Ganze nur bis ~30kHz
funktioniert, ich möchte aber bis 100kHz messen.
Laut Datenblatt können die I/O-Pins des ATmegas Impulse mit bis zu 50ns
Dauer detektieren, daher nehme ich an, dass rein physikalisch 2MHz die
Grenzfrequenz für den Hardwareintzerrupt wäre. Liege ich mit der
Überlegung richtig oder habe ich da noch einen denkfehler gemacht ?
Kann mir jemand sagen, ob ich den Chip überfordere? Oder liegt es daran,
dass ich tinyOS verwende und ich käme mit Assembler hin?
... Hier ist der Sourcecode in nesC:
1
#include<printf.h>
2
3
moduleUltraMicP{
4
uses{
5
interfaceBoot;
6
interfaceHplAtm128InterruptasSignalRead;
7
interfaceTimer<TMilli>asTimer;
8
interfaceTimer<TMilli>asTimer2;
9
}
10
}
11
12
implementation{
13
14
uint32_tzaehler[255];
15
uint8_tindex;
16
17
eventvoidBoot.booted(){
18
/* legt ein array an, in dem die zählwerte gespeichert sind */
19
for(index=0;index<255;index++)
20
zaehler[index]=0;
21
index=0;
22
/* Initialiserung vom Hardware-Interrupt */
23
callSignalRead.edge(TRUE);
24
callSignalRead.enable();
25
/* Timer starten */
26
callTimer.startPeriodic(15);
27
}
28
29
asynceventvoidSignalRead.fired(){
30
/* Zählt die Flanke an der aktuellen Speicherstelle*/
>Der Prozessor wird mit 4MHz getaktet>Ganze nur bis ~30kHz> ich möchte aber bis 100kHz messen.
Rechne mal nach, wieviele ASM-Befehle du so dazwischen bearbeiten
kannst!
Zu deinem Code kann ich nichts sagen. Ist das C?
>können die I/O-Pins des ATmegas Impulse mit bis zu 50ns>Dauer detektieren
Ja, ABER
Die Software muss bis zum nächsten eingehenden Impuls geeignet darauf
reagieren können! Ein Interrupteinsprung dauert mindestens 4Takte, also
bei 4MHz mindestens 1µs. Dann bist du in der ISR, hast aber noch nichts
gemacht..
/* Zählt die Flanke an der aktuellen Speicherstelle*/
3
zaehler[index]++;
4
}
Da gibt es einiges zu berechnen:
1) Erstmal die Adresse vom Zähler holen
2) den Offset (Index) draufaddieren
3) den Inhalt dieser Speicherzelle holen
4) Eins dazuaddieren
5) wieder in die Speicherzelle zurückschreiben
und das Ganze mit longs bei einem langsam getakteten 8-Bit Prozessor.
Das kann dauern :-/
Mein Tipp:
Überleg dir, ob du tatsächlich 32Bit-Zähler brauchst.
@ lippy:
>Rechne mal nach, wieviele ASM-Befehle du so dazwischen bearbeiten>kannst!
Im Datenblatt steht "Most Single Clock Cycle Execution" - dann rechne
ich bei 100kHZ vs 4 MHz mit 40 Befehlen ... eigentlich genug Zeit, oder?
>Zu deinem Code kann ich nichts sagen. Ist das C?
das ist nesC. Damit programmiert man in tinyOS. Außer dem Initialisieren
mit diesen interface-Zeux ist es C-ähnlich, finde ich, drum hab' ich es
gepostet.
>Ein Interrupteinsprung dauert mindestens 4Takte
oops! das hatte ich schon mal nicht beachtet ...
@lkmiller:
OK. Ist natürlich blöd, wenn man nicht genau weiss, in wie viele
Einzelbefehle der nesC-Code übersetzt wird ... ich hatte schon
befürchtet, dass ich das in Assembler machen muss. Da das ganze im
Moment nur ein Geschwindigkeitstest ist und ich den Rest des Programms
gerne in nesC weiter verwenden würde - kann mir jemand hier im Forum
sagen, wie ich Assembler Code in tinyOS einbinden kann?
> Überleg dir, ob du tatsächlich 32Bit-Zähler brauchst.
Stimmt. Das maximale Zählergebnis kann ja nur 1500 werden. Da geht auch
noch was.
... danke schon mal an euch beide, das hat mich schon ein bisschen
weiter gebracht!
thx
gast wrote:
> Im Datenblatt steht "Most Single Clock Cycle Execution" - dann rechne> ich bei 100kHZ vs 4 MHz mit 40 Befehlen ... eigentlich genug Zeit, oder?
max 40 Assembler Befehle. In C sind das wesentlich weniger
'Hochsprachenbefehle'
>>Ein Interrupteinsprung dauert mindestens 4Takte>> oops! das hatte ich schon mal nicht beachtet ...
mach dich auch mal auf die Suche, ob dein TinyOs da auch noch einen
Overhead mit einbringt. Bei 40 Takten Zeit zählt jede Anweisung.
@gast (Gast)
>ich benutze einen Mica2dot Mote von Crossbow, der mit dem Atmega 128L>bestückt ist. Der Prozessor wird mit 4MHz getaktet. Als>Programmierplattform nehme ich tinyOS. Ich möchte eine Frequenzmessung>eines Rechtecksignals vornehmen, das am INT0 angeschlossen ist und bei>jeder aufsteigender Flanke einen HardwareInterrupt auslöst. Die>aufsteigenden Flanken sollen jeweils 15ms lang gezählt werden (ich>brauche das resultat nicht in Hz).
Soll das ein Aprilscherz sein?
Betriebssysdtem auf nem AVR, C++? und dann einen Frequenzzähler REIN in
Software bauen? Du raust zu viel. Und das Falsche.
> Die Zählwerte werden zunächst im>Speicher gehalten und am Ende gemeinsam über UART ausgegeben.>Das Problem, das ich habe, ist, dass das Ganze nur bis ~30kHz>funktioniert, ich möchte aber bis 100kHz messen.
Na dann mach dich mal mit dem Timer und dess Fähigkeit, externe Pulse zu
zählen vertraut. Das erzeugt keine 100 kHz Interrupts.
Leute gibts.
>Kann mir jemand sagen, ob ich den Chip überfordere? Oder liegt es daran,>dass ich tinyOS verwende und ich käme mit Assembler hin?
Ich empfehle wie immer Brain 2.0. Fürs erste reicht auch Datenblattlesen
1.2.
MFg
Falk