263/317
9 - A Carrier-current System for domestIc Remote Control
The
ICF1
flag is first tested to know whether the interrupt was caused by a Capture 1 event. If
yes, the first block is executed; if not, the second block is executed.
In the first case, the two bytes of Compare register 2 are set to the value held in the global var-
iable
TimerPeriod
. Since this is a word value, its two bytes are extracted using two simple ex-
pressions. Please note that the high byte must be written first, or the compare function would
be inhibited, as specified in the data sheet.
To clear the interrupt request, the data sheet indicates that the Status Register must be read,
then the low byte of the capture register must be accessed. Here, the Status Register is al-
ready read by the test that determines the interrupt cause. Then, we have chosen to read the
TAIC1LR
register. To perform a read in C, its value must be assigned to a variable that is used
later, or the optimization by the compiler would remove this apparently useless access. Thus,
the simplest way to read that register is an in-line assembly statement:
asm
{
ld a, TAIC1LR ;
/* Dummy read to clear interrupt request */
}
The value read in the accumulator will be ignored by the rest of the process, but the read from
TAIC1LR
is ensured.
Then, a counter is incremented so as to count three interrupt services; the
SendOneFrameEle-
ment
function is called every third interrupt. This is because the X -10 standard requires that
each pulse be sent three times for each half-period, so that receivers connected to other
phases of the power line, and thus synchronized 120 or 240 degrees away from the trans-
mitter, find the pulses anyway.
If the interrupt cause is a Capture 2 event, the
PhaseLockedLoop
function is called.
The
SendOneFrameElement
function.
This function is relatively long, but actually it is very simple. Its behavior is driven by the global
variable
CycleNumber
that selects one of 50 cases. It is incremented each time, so that each
case is executed once for each interrupt service. Since interrupts occur twice per line cycle,
each bit to send is processed twice, by two consecutive interrupts.
The first four bits are the prefix, or synchronization, bits. They must always be 1110.
The next four pairs of bits carry the House Code. In each pair, the second bit is the comple-
ment of the first one. This is why the values 5, 7, 9, and 11 of
CycleNumber
are processed by
the same block of code, as are the values 6, 8, 10, and 12, but with another block of code that
produces the complementary result. This block also shifts the
HouseCode
variable right by one
bit, so that the next bit will be used in the next interrupt.