PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : CCPRO M128: Stopwatches (CompactC)



Dirk
24.05.2010, 17:30
Hallo Leute,

wenn man sich durch die Libraries des RP6 und der M32 an die Stopwatches (Stoppuhren) gewöhnt hatte, vermißt man die bei der Programmierung der RP6 CCPRO M128 unter CompactC.
Angeregt durch Fabian E.:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=54409
... habe ich eine kleine Stopwatches-Library für CompactC geschrieben, die man einbinden kann, wenn man so eine Funktion braucht. Natürlich kann man das auch durch Threads hinbekommen, wobei diese ja erstmal ungewohnt sind.

RP6Stopwatches.cc :
/************************************************** *****************************
* RP6 C-Control PRO M128 Erweiterungsmodul
* ----------------------------------------------------------------------------
* RP6_Stopwatches Testprogramm 1 - CompactC
* ----------------------------------------------------------------------------
* RP6_Stopwatches: Blinkende LEDs
* Diese Demo zeigt, wie man die Stopwatches, die in den Libraries der
* RP6Base und der RP6 Control M32 implementiert sind, auf die RP6 M128
* übertragen kann. Die Stopwatches sind eine hilfreiche Konstruktion,
* um mehrere Aufgaben zeitgesteuert abarbeiten zu können. Hierfür
* könnte man alternativ auch Threads einsetzen.
* erforderliche Library: IntFunc_Lib.cc und neue RP6StopwatchesCClib.cc
* (v. 1.xx).
*
* Diese Demo läßt alle 5 Status-LEDs mit 5 Stopwatches blinken,- jede
* mit einer eigenen Frequenz (0,2..1 Hz).
*
* Hinweis:
* Für allgemeine Programmierhinweise zur CCPRO schauen Sie sich bitte die
* CCPRO Dokumentation und die zugehörigen Beispielprogramme an!
* Es sei auch nochmals darauf hingewiesen, dass die normalen Beispielprogramme
* für die CCPRO nur zum Teil direkt auf dem RP6-CCPRO Modul laufen.
* Die Anschlussbelegung ist natürlich komplett anders als auf dem
* C-Control Application Board. Auch die LCD Ansteuerung ist leicht anders,
* da hier noch zusätzliche LEDs mit an dem Schieberegister angeschlossen sind.
* --> Die C-Control Beispielprogramme müssen ein klein wenig angepasst
* werden bevor sie auf diesem Modul laufen können!
*
* ************************************************** ***************************
* Der Roboter bewegt sich in diesem Beispielprogramm NICHT und kann
* am Rechner angeschlossen bleiben!
************************************************** ****************************/

// WICHTIG: Immer die RP6CCLib mit einbinden:
#include "../../RP6CCLib/RP6CCLib.cc"

// Die neue RP6StopwatchesCCLib einbinden:
#include "../../RP6CCLib/RP6StopwatchesCCLib.cc"

//------------------------------------------------------------------------------
// Variablen:

byte all_leds;
byte led1flag;
byte led2flag;
byte led3flag;
byte led4flag;
byte led5flag;

void main(void)
{
// WICHTIG! Immer als erstes aufrufen:
RP6_CCPRO_Init(); // Auf Startsignal warten, LCD und andere Dinge initialisieren !

// ------------------------------------------------------

// Zwei Zeilen Text mit dem LCD anzeigen:
showScreenLCD("RP6 CCPRO M128", "Stopwatches 1 ");

// Zweimal piepsen:
beep(200, 300, 100); // Format: beep (<tonhöhe>, <dauer>, <pause>)
beep(100, 100, 100);

// Text über serielle Schnittstelle ausgeben:
newline(); // Neue Zeile
println(" ________________________");
println(" \\| RP6 ROBOT SYSTEM |/");
println(" \\_-_-_-_-_-_-_-_-_-_/ ");
newline();
println(" Let's go! ");
newline();

// 2 Sekunden Pause:
AbsDelay(2000);

// ------------------------------------------------------
// Stopwatches-Hauptprogramm:

setLEDs(0); // Alle LEDs aus
clearLCD(); // Display löschen

initStopwatches(); // Initialisierung der Stopwatches

startStopwatch1(); // Starte Stopwatch 1
startStopwatch2(); // Starte Stopwatch 2
startStopwatch3(); // Starte Stopwatch 3
startStopwatch4(); // Starte Stopwatch 4
startStopwatch5(); // Starte Stopwatch 5
// Insgesamt gibt es 8 Stopwatches!

while (1) // Endlosschleife
{
if(getStopwatch1() > 1000) { // Jede Sekunde
if(led1flag) {
all_leds = all_leds | LED1;
setLEDs(all_leds); // LED1 an
led1flag = 0;
}
else {
all_leds = all_leds & ~LED1;
setLEDs(all_leds); // LED1 aus
led1flag = 1;
}
setStopwatch1(0); // Stopwatch 1 zurücksetzen
}
if(getStopwatch2() > 2000) { // Jede 2. Sekunde
if(led2flag) {
all_leds = all_leds | LED2;
setLEDs(all_leds); // LED2 an
led2flag = 0;
}
else {
all_leds = all_leds & ~LED2;
setLEDs(all_leds); // LED2 aus
led2flag = 1;
}
setStopwatch2(0); // Stopwatch 2 zurücksetzen
}
if(getStopwatch3() > 3000) { // Jede 3. Sekunde
if(led3flag) {
all_leds = all_leds | LED3;
setLEDs(all_leds); // LED3 an
led3flag = 0;
}
else {
all_leds = all_leds & ~LED3;
setLEDs(all_leds); // LED3 aus
led3flag = 1;
}
setStopwatch3(0); // Stopwatch 3 zurücksetzen
}
if(getStopwatch4() > 4000) { // Jede 4. Sekunde
if(led4flag) {
all_leds = all_leds | LED4;
setLEDs(all_leds); // LED4 an
led4flag = 0;
}
else {
all_leds = all_leds & ~LED4;
setLEDs(all_leds); // LED4 aus
led4flag = 1;
}
setStopwatch4(0); // Stopwatch 4 zurücksetzen
}
if(getStopwatch5() > 5000) { // Jede 5. Sekunde
if(led5flag) {
all_leds = all_leds | LED5;
setLEDs(all_leds); // LED5 an
led5flag = 0;
}
else {
all_leds = all_leds & ~LED5;
setLEDs(all_leds); // LED5 aus
led5flag = 1;
}
setStopwatch5(0); // Stopwatch 5 zurücksetzen
}
// Aufgaben in der Hauptschleife.
}
}

//------------------------------------------------------------------------------

RP6StopwatchesCClib.cc:
/* ************************************************** **************************
* _______________________
* \| RP6 ROBOT SYSTEM |/
* \_-_-_-_-_-_-_-_-_-_/ >>> CCPRO M128
* ----------------------------------------------------------------------------
* ----------------------------- [c]2010 - Dirk -------------------------------
* ************************************************** **************************
* File: RP6StopwatchesCClib.cc
* Version: 1.0 - CompactC
* Target: RP6 CCPRO M128 - C-Control PRO M128 @14.7456MHz
* Author(s): Dirk
* ************************************************** **************************
* Beschreibung:
* Dies ist meine Stopwatches Bibliothek für die RP6 CCPRO M128. Die acht
* Stopwatches funktionieren genau wie die Stopwatches, die mit den
* Bibliotheken der RP6Base und RP6 Control M32 benutzt werden können.
* Siehe Abschnitt 4.6.3. der RP6 Robot System Bedienungsanleitung!
*
* ************************************************** **************************
* CHANGELOG FINDEN SIE AM ENDE DIESER DATEI!
* ************************************************** **************************
*/

// Alles nur EINMAL einbinden!
#ifndef __RP6STOPWATCHESCCLIB__
#define __RP6STOPWATCHESCCLIB__


/************************************************** ****************************/
// Defines:

// Timer-Verwendung (nur EINE dieser drei Definitionen ist erlaubt!):

// #define USE_TIMER0
// #define USE_TIMER1
#define USE_TIMER3

// Stopwatches:

#define STOPWATCH1 1
#define STOPWATCH2 2
#define STOPWATCH3 4
#define STOPWATCH4 8
#define STOPWATCH5 16
#define STOPWATCH6 32
#define STOPWATCH7 64
#define STOPWATCH8 128

#define stopStopwatch1() watches = watches & ~STOPWATCH1
#define stopStopwatch2() watches = watches & ~STOPWATCH2
#define stopStopwatch3() watches = watches & ~STOPWATCH3
#define stopStopwatch4() watches = watches & ~STOPWATCH4
#define stopStopwatch5() watches = watches & ~STOPWATCH5
#define stopStopwatch6() watches = watches & ~STOPWATCH6
#define stopStopwatch7() watches = watches & ~STOPWATCH7
#define stopStopwatch8() watches = watches & ~STOPWATCH8

#define startStopwatch1() watches = watches | STOPWATCH1
#define startStopwatch2() watches = watches | STOPWATCH2
#define startStopwatch3() watches = watches | STOPWATCH3
#define startStopwatch4() watches = watches | STOPWATCH4
#define startStopwatch5() watches = watches | STOPWATCH5
#define startStopwatch6() watches = watches | STOPWATCH6
#define startStopwatch7() watches = watches | STOPWATCH7
#define startStopwatch8() watches = watches | STOPWATCH8

#define isStopwatch1Running() (watches & STOPWATCH1)
#define isStopwatch2Running() (watches & STOPWATCH2)
#define isStopwatch3Running() (watches & STOPWATCH3)
#define isStopwatch4Running() (watches & STOPWATCH4)
#define isStopwatch5Running() (watches & STOPWATCH5)
#define isStopwatch6Running() (watches & STOPWATCH6)
#define isStopwatch7Running() (watches & STOPWATCH7)
#define isStopwatch8Running() (watches & STOPWATCH8)

#define getStopwatch1() watch1
#define getStopwatch2() watch2
#define getStopwatch3() watch3
#define getStopwatch4() watch4
#define getStopwatch5() watch5
#define getStopwatch6() watch6
#define getStopwatch7() watch7
#define getStopwatch8() watch8

#define setStopwatch1(__VALUE__) watch1 = __VALUE__
#define setStopwatch2(__VALUE__) watch2 = __VALUE__
#define setStopwatch3(__VALUE__) watch3 = __VALUE__
#define setStopwatch4(__VALUE__) watch4 = __VALUE__
#define setStopwatch5(__VALUE__) watch5 = __VALUE__
#define setStopwatch6(__VALUE__) watch6 = __VALUE__
#define setStopwatch7(__VALUE__) watch7 = __VALUE__
#define setStopwatch8(__VALUE__) watch8 = __VALUE__

/************************************************** ****************************/
// Variablen:

// 16 Bit Stopwatches --> Maximalwert ist 65535 oder ~65,535 Sekunden!

byte watches;
unsigned int watch1;
unsigned int watch2;
unsigned int watch3;
unsigned int watch4;
unsigned int watch5;
unsigned int watch6;
unsigned int watch7;
unsigned int watch8;

/************************************************** ****************************/
// Funktionen:

/**
* INIT Stopwatches
*
* Unbedingt einmal aufrufen, bevor die Stopwatches benutzt werden!
*
* ANMERKUNG: Die Zeilen mit dem Kommentar "!!! Bugfix TimerX !!!"
* müssen entfernt werden, sobald der Fehler der Funktion
* Timer_TXTime() [X = 1 oder 3] in einer neuen Version
* der IDE beseitigt wurde!
*/
void initStopwatches(void)
{
watches = 0; // Alle Stopwatches aus
#ifdef USE_TIMER0
Irq_SetVect(INT_TIM0COMP, INT_1ms); // Timer0-ISR definieren
Timer_T0Time(230, PS0_64); // Timer0: 1ms Interrupt
#endif
#ifdef USE_TIMER1
Irq_SetVect(INT_TIM1CMPA, INT_1ms); // Timer1-ISR definieren
Timer_T1Time(14746, PS_1); // Timer1: 1ms Interrupt
DirAcc_Write(0x4e,8|PS_1); // !!! Bugfix Timer1 !!!
#endif
#ifdef USE_TIMER3
Irq_SetVect(INT_TIM3CMPA, INT_1ms); // Timer3-ISR definieren
Timer_T3Time(14746, PS_1); // Timer3: 1ms Interrupt
DirAcc_Write(0x8a,8|PS_1); // !!! Bugfix Timer3 !!!
#endif
}

/**
* Interrupt Routine
*
*/
void INT_1ms(void)
{
int irqcnt;
if(watches & STOPWATCH1) watch1++;
if(watches & STOPWATCH2) watch2++;
if(watches & STOPWATCH3) watch3++;
if(watches & STOPWATCH4) watch4++;
if(watches & STOPWATCH5) watch5++;
if(watches & STOPWATCH6) watch6++;
if(watches & STOPWATCH7) watch7++;
if(watches & STOPWATCH8) watch8++;
#ifdef USE_TIMER0
irqcnt = Irq_GetCount(INT_TIM0COMP);// Interrupt Request Counter
#endif
#ifdef USE_TIMER1
irqcnt = Irq_GetCount(INT_TIM1CMPA);
#endif
#ifdef USE_TIMER3
irqcnt = Irq_GetCount(INT_TIM3CMPA);
#endif
}

#endif

/************************************************** ****************************
* Info
* ************************************************** **************************
* Changelog:
* - v. 1.0 (initial release) 24.05.2010 by Dirk
*
* ************************************************** **************************
*/

/************************************************** ***************************/
// EOF

Viel Spaß!

Dirk

Fabian E.
24.05.2010, 19:49
Hey,
super, dass du dir die Arbeit gemacht hast =)
Leider funktioniert das ganze nicht so richtig bei mir...
Die Stopwatch-Zeiten scheinen falsch zu sein... Woran kann das liegen?
Im Debug Modus springt er immer wenn ich einen Einzelschritt mache in den Interupt rein (ohne Breakpoint dort), dann zählt er auch die Variablen hoch. Aber das geht alles viel zu langsam...
Ohne Debugger zählen die Variablen hoch, allerdings wie gesagt viel zu langsam...

Dirk
24.05.2010, 21:50
@Fabian E.:

Die Stopwatch-Zeiten scheinen falsch zu sein... Woran kann das liegen?
Wieviel liegen die denn daneben?
Ich habe es nicht mit dem Oszi kontrolliert, aber LED1 schien ca. 1 Sekunde an und aus zu sein. Damit dachte ich, es wäre alles ok ...

Gruß Dirk

Fabian E.
24.05.2010, 22:27
also die eingestellten 500ms dauern ungefähr ne Minute würde ich mal tippen... Also nichts Kleines sondern wirklich richtig heftig...

Aber grade habe ich herausgefunden, dass es an mir leigt, bzw an meinem Programm... In einem anderen Programm gehts...
Irgendeine Idee, was da schief laufen könnte...
Achja, nochwas... In meinem eigentlichen Programm kennt er die Funktionen Timer_T3FRQ(pitch, PS_64); und Timer_T3Stop(); nicht, d.h. beim kompilieren meckert er über nicht definierte Funktionen...
Was läuft da schief? Vielleicht hängt das ja zusammen...

Dirk
24.05.2010, 22:55
Keine Ahnung!
Eigentlich sollte er beide Funktionen kennen (vorausgesetzt, er geht nicht von einem M32 aus!).

Gruß Dirk

Fabian E.
24.05.2010, 23:06
Naja... Projekt nochmal komplett neu aufgesetzt und dabei beachtet, dass nicht jede Datei jede Datei "includen" muss deren Kram sie kennen muss -- die IDE bastelt da irgendwie auch mit rum, richtig verstanden habe ich es noch nicht -- und jetzt geht es. Zumindest die Stopwatches und die Timersachen da. =)

Eine Frage noch: Der Beeper benutzt ja auch Timer3... Kann es da zu Problemen kommen? Und was sind das für Bugs, die in den Kommentaren des Quelltextes stehen?

Ansonsten super Arbeit! =) Aber ich sehe schon, dass ich das später wohl nicht mehr so richtig brauchen werde, wenn man sich erst mal dran gewöhnt hat, dass hier echte Threads möglich sind. =)

Dirk
25.05.2010, 20:32
Eine Frage noch: Der Beeper benutzt ja auch Timer3... Kann es da zu Problemen kommen?
Ja, kann es. Du kannst dann für die Stopwatches den Timer0 oder 1 nehmen (In der Lib USE_TIMER0 oder USE_TIMER1 anstelle von USE_TIMER3 aktivieren).

Und was sind das für Bugs, die in den Kommentaren des Quelltextes stehen?
Die Funktionen Timer_T1Time() und Timer_T3Time() funktionieren nicht richtig: Egal, welchen Wert man für Time (1. Parameter) angibt, es wird immer 65535 verwendet. Somit wird dann alles sehr langsam ... und man kann keine sinnvolle Einstellung vornehmen. Der angegebene "Bugfix" ist eigentlich ein Workaround bis der Bug durch eine neue CCPRO-IDE Version (> 2.1) gefixt ist.

Gruß Dirk