16
RabbitCore RCM2000
#define DS2 0
// predefine for LED DS2
#define DS3 1
// predefine for LED DS3
//
This cofunction flashes LED on for ontime, then off for offtime
cofunc flashled[4](int led, int ontime, int offtime) {
for(;;) {
waitfor(DelayMs(ontime));
// on delay
WrPortI(PADR,&PADRShadow,(1<<led)|PADR);
// turn LED off
waitfor(DelayMs(offtime);
// off delay
WrPortI(PADR,&PADRShadow,(1<<led)^0xff&PADR);
// turn LED on
}
main {
// Initialize ports
WrPortI(SPCR,&SPCRShadow,0x84);
// Set Port A all outputs, LEDs on
WrPortI(PEFR,&PEFRShadow,0x00);
// Set Port E normal I/O
WrPortI(PEDDR,&PEDDRShadow,0x01);
// Set Port E bits 7…1 input, 0 output
WrPortI(PECR,&PECRShadow,0x00);
// Set transfer clock as pclk/2
for(;;) {
// run forever
costate {
// start costatement
wfd {
// use wfd (waitfordone) with cofunctions
flashled[0](DS2,200,200);
// flash DS2 on 200 ms, off 200 ms
flashled[1](DS3,1000,500);
// flash DS3 on 1000 ms, off 500 ms
}
// end costatement
}
// end for loop
}
// end of main, never come here
The flashing of the LEDs is performed by the costatement. Costatements need to be exe-
cuted regularly, often at least every 25 ms. To accomplish this, the costatements are
enclosed in a while loop or a for loop. The term while loop is used as a handy way to
describe a style of real-time programming in which most operations are done in one loop.
The costatement is executed on each pass through the big loop. When a waitfor or a wfd
condition is encountered the first time, the current value of MS_TIMER is saved and then
on each subsequent pass the saved value is compared to the current value. If a waitfor
condition is not encountered, then a jump is made to the end of the costatement, and on the
next pass of the loop, when the execution thread reaches the beginning of the costatement,
execution passes directly to the waitfor statement. The costatement has the property that
it can wait for long periods of time, but not use a lot of execution time. Each costatement
is a little program with its own statement pointer that advances in response to conditions.
On each pass through the big loop, as little as one statement in the costatement is exe-
cuted, starting at the current position of the costatement’s statement pointer. Consult the
Dynamic C User’s Manual for more details.
This program also illustrates a use for a shadow register. A shadow register is used to keep
track of the contents of an I/O port that is write only—it can’t be read back. If every time a
write is made to the port the same bits are set in the shadow register, then the shadow reg-
ister has the same data as the port register.