Fast counter

The fast counter is available in hardware but not supported by firmware or by RoboPro.

Nevertheless it can be used with a small C program that initializes the counter and sends the values to RoboPro. The counter is Timer A3 of the M16C and its counter input (ZE) is available on the flatcable connector (pin 9). If this is inconvenient you could internally connect it to input E7. Input E8 is connected to the timer output which in some configurations (event counter) functions as another input to the counter. In one mode E8 is the direction input and ZE is the clock input, in the two phase mode both inputs are clock inputs and the count direction depends on the phase relationship of the two signals. This mode is interesting for applications with quadrature encoders such as the maxon motors.

In order to use the counter we first have to initialize it:

#define TWOPHASE

void initA3counter()
{//mode is event counter
#ifdef TWOPHASE
ta3mr = 0xD1; //mult by 4, free run
// ta3mr = 0x51; //normal, free run
udf |= 0x40;
#else
ta3mr = 0x51; //use ta3out pin as dir, falling edges, free run
udf &= ~0x40;
#endif
trgsr &= ~0x30;
pd7_6 = 0; //program pin as input
ta3 = 0x8000; //start in the middle
ta3s = 1; //start counting
ta3 = 0x8000; //start in the middle, free running => not sure that reload value ever gets loaded
//at present interrupt is not used, otherwise initialize it here
}

Once this has been executed, the timer is counting, now we have to read its value:

long A3count = 0L;
int readA3diff()
{ static unsigned old =0x8000;
unsigned val = ta3;
int diff = ta3 - old; //this is unambiguous as long as the absolute difference is less than half the maximum count (<0x8000)

/* proof:
if no underfow or overflow: trivial
if old value positive and new value overflows, the new value is 0x10000 too low which makes no difference.
example old=0x7000 and the increase = 0x3000, the new value will be 0xa000 which is negative.
new - old is 0xa000 - 0x7000 = 0xa000 + 0x9000 = 0x13000 which reduces to 0x3000 which is the correct increase
*/

old = val;
A3count += diff;
return diff;
}

As you can see a 32 bit count is kept in ‘A3count’ and the function returns only the difference between subsequent readings. The next problem is how to communicate the value to your RoboPro program. The easiest way is just to send it a message. So periodically (in your timer routine) you check whether the value has changed and if yes, you send a message (eg. ‘cnt’) with the value of the change. For instance:

//put this snippet in the 1ms timer routine
if (++time >= 100)
{ long val = readA3diff();
time = 0;
if (val != 0)
SendFtMessage(MSG_HWID_SELF, 9, A3msg|(val<<16), 0 /*ms*/, MSG_SEND_NORMAL);
}

Now in your ‘main’ do all necessary initializations and call your RoboPro program. Look at the wiki about combining C and RoboPro on how to do that.

static long A3msg;
long make_message(char far *id, int val)//scramble message name
{ long rv = 0;
int i;
if (id)
for (i=0; i<3 && id; i++)
{ rv *= 40;
if (id=='!')
rv += 39;
else if (id=='+')
rv += 37;
else if (id=='-')
rv += 38;
else if (id>='0' && id<='9')
rv += id-'0'+27;
else if (id>='A' && id<='Z')
rv += id-'A'+1;
else if (id>='a' && id<='z')
rv += id-'a'+1;
}

return ((long)val<<16)|rv;
}

UCHAR main(void)
{
A3msg = make_message("cnt", 0);
initA3counter();
SetFt1msTimerTickAddress((void far *())timerint);
//here call your RoboPro Program

return 0;
}

Thats all! Now in your RoboPro program, listen to broadcast messages with message ID ‘cnt’ and use the ‘+’ command to add the received value to a variable. Note that this only works in download mode!


Erstellt und hochgeladen von Ad.
Hochgeladen am 11.6.2009.

Hinweis: Wir vertrauen auf die Sachkunde und Sorgfalt unserer Nutzer. Trotzdem könnten sich Fehler eingeschlichen haben. Eine Haftung für die Richtigkeit der Inhalte können wir nicht übernehmen.