HC11 Programming Example

(This document uses the less than or equal to symbol # which may not be displayed properly.)

Consider the following situation. Primary cosmic rays are very high energy particles, mostly protons propagating in space. When such a primary collides with the earth's atmosphere it creates a shower of secondary particles which spread out from the point of impact and arrive at the earth's surface spread over an area, essentially simultaneously. A physicist sets up an array of Geiger counters (GM) to study the phenomenon. When a burst of secondaries arrives a set of Geiger counters are hit and each of these issues a pulse. The arrival is referred to as an event and the number of Geiger counters hit, n, varies from event to event. The aim of the experiment is to determine the probability function P(n). To achieve this aim the physicist decides to use the MC68HC11.


For simplicity, lets assume there are N=8 counters. Then n varies from 1 to 8. Notice that n = 0 is a non-event. Before launching into a software design, lets stand back and decide what must be done and how it can be related to the concepts relevant to a digital system. Each counter acts as a binary element so the set of GM outputs comprise an eight bit binary word, X. Each event therefore can be looked upon as generating a word X, which can be any one of the 255 members of the set in which the word of zero weight is excluded as a non-event. The quantity n associated with each event is the number of ones in the word, i.e. its weight, n = w(X).

For each event therefore the immediate task is to determine the weight of the word, n.

The next question is what do we do with it once we've got it? Recall the aim is to determine the probability. We could simply make some sort of a record of the values of n obtained over some period of time and present this information to the experimenter. It would then be up to the experimenter to tally up the number of events for which a specific n occurred and divide by the total number of events in the record. Since a digital system has computational power, this seems rather a waste of time. A computer can always be considered a form of digital function generator by setting up a correspondence between the independent variable and a memory address. The contents at this address are then set to the value of the function at the corresponding value of the independent variable. Here the independent variable is n. The required function can be written N(n) corresponding to the number of events in which n counters were hit during the recording period. After the end of the recording period the probability is calculated as N(n)/NT, where the denominator is the total number of events. If we make the relative address for n hits equal to n, then N(n) may be calculated by increasing the contents of this address by one every time an n-hit event is observed.

At this stage then a bare bones outline of the requirement would be:

Even without a flow diagram it is obvious at this stage that the structure represents an endless loop. Moreover at this stage only the quantities N(n) proportional to the probabilities are available. Finally, no provision has been made to provide the experimenter with access to the results. The above outline also indicates that a method of checking that an event has occurred must be found, and an algorithm for calculating the weight of the word must be developed.

Three possible mechanisms may be used for ending the loop problem. The first is manual - the experimenter must activate a switch. The second is on the basis of acquisition time. The third is based upon total event number. This last is most appropriate in this case, since it is most directly related to the statistical precision attained. It must be emphasized that this by no means implies that the option chosen is the "right answer". There could be other considerations which would make the either of the first two, or some other criterion altogether, more suitable. The three options listed are the most common and one might consider eventually designing the software so the experimenter could select any one of the three. The choice made here creates the structure

while NT#TOTAL do

following which the statements above are executed. Here TOTAL is the predefined total number of events. When the condition NT#TOTAL is not satisfied a different set of statements are executed.

With a loop-ending criterion established, the way is open to consider the next two deficiencies noted above. These can be addressed in the different set of statements to which control is passed at the end of the loop. The probabilities may be calculated by the required division and then output to a display peripheral. Again this is not the only solution. It may in fact not be the most desirable solution, because no provision is made for providing any indication of the progress of the experiment during acquisition. Nevertheless it does fulfill the basic requirements. While it is important to keep in mind the need for such an indicator, it is perhaps useful at least as a first task to make a paper design of the simplest system achieving the over-all goal.

The first two tasks of checking for an event and getting the data involve I/O interfacing. The details of the external system requires a hardware design which may assume varying degrees of sophistication. We will assume that the external system issues an event signal, which is generated from the OR of all GM tube outputs, followed by the binary word X. We will also assume that the processor is located locally so that parallel communications may be used.

When the event signal is received a logical variable called a flag is set to 1 signifying that data is available at the input port. In the simplest approach, the program may be structured so as to read the flag, if it is 1, then get the data and process it. This uses an if condition then structure.

We assume the hardware is designed so that once the condition flag = 1 occurs, the system is disabled. The program now takes the form:

* cosmic ray experiment control program

* eventno is the current no. of events analyzed

* nn is the current no. of n-hit events

* pn is the n-hit probability

* total is the number of events to be accumulated before stopping

start

dcount = 0

eventno = 0

while dcount < 8 do

begin

nn = 0

increment dcount

end

while eventnototal do

begin

read flag

if flag=1 then

read data

reset flag

increment eventno

calculate weight

increment nn

endif

end

dcount=0

while dcount < 8 do

begin

pn=nn/eventno

output pn

increment dcount

end

stop

As it is written the above program is generic, and not restricted to any particular system. This form is referred to as pseudocode. It is now possible to address the several aspects individually as applied to the MC68HC11. To begin one might consider the I/O subsystem. In so doing, the problem of flag checking, data input and external system control may be solved. The following registers will be used. First, the parallel I/O control register, PIOC is located at memory location $1002. The MSB of this register is the flag bit, corresponding to logical variable STAF. It is set when the external system sends a signal to the strobe pin STRA,. In this case STRA is connected to the event signal. The seventh bit (Bit 1, alternate labeling) corresponds to logical variable EGA. When EGA is set the flag is set on the rising edge of STRA. The data, corresponding to the word X is connected to port C. This word is captured in the latched register PORTCL located at $1005 by the STRA input. Since port C is bidirectional, it is necessary to define it as an input port by storing 0 in the data direction register for port C, DDRC. It is also necessary to communicate to the external system the fact that the input data has been received and a new event may be analyzed. This can be done using the STRB output, which is automatically generated whenever data is written to PORTB at $1004. It is convenient to use a header describing all the fixed registers, which can be added to any program as described by Spasov.

A simpler version including only the registers and memory addresses required takes the form:

DATA EQU $0000    
CODE EQU $F800    
REGBASE EQU $1000    
PIOC EQU $02    
PORTB EQU $04    
PORTCL EQU $05    
DDRC EQU $07    

The first step is to configure the I/O system. In this case, it will be assumed that response on the rising edge of STRA is appropriate. It is also necessary to define port C as input. Configuration may then be accomplished by the statements:

  ORG CODE    
         
  LDX #REGBAS    
  LDAA #$02    
  STAA PIOC,X    
  CLR DDRC,X    

The second and third instruction result in EGA=1, while clearing the remaining 7 bits. The fourth instruction puts $00 in DDRC defining port C to be input.

Initialization of values can be achieved by the following:

  ORG DATA  
DBASE RMB 16 ;base address for data, nn
       
      ;add the following code after
      ;the lines in the CODE segment above
  CLR EVENTNO  
  LDY #DBASE  
  LDAB #8  
SET CLR 1,Y  
  INY    
  DECB    
  BGT SET  


The set loop zeros the contents of locations DBASE+1 to DBASE+8.


The polling loop corresponding to the if .. then structure in which the status of the flag is checked may be constructed next. Ascertaining the value of a particular bit of the 8-bit word in the PIOC register is accomplished by masking. To select the most significant bit the mask must have MSB=1 while all other bits are zero, represented by $80. The structure is then achieved by the following statement.

CHECK BRCLR PIOC,X $80 CHECK    

This instruction reads the contents of PIOC and branches back to itself if the MSB=0. If the MSB=1, then the if structure is entered. In a sense this is the data processing section of the program, and requires the development of an algorithm to determine the weight of the word X latched into PORTCL. First think carefully how an individual would do this. Normally they would examine each bit one at a time reading from the MSB to the LSB. Each time a one was encountered they would increment a tally which was zero before the examination began. As mentioned previously, one way to ascertain the value of a specific bit is by performing the AND operation between the word and a suitable mask. While this could be done here, eight different masks would be required. An alternative method is to shift the word a specific number of times, isolating the corresponding specific bit in the one-bit carry register. In this case after each shift, a register initially cleared would be incremented if the carry bit, C=1. After 8 shifts the register would contain the weight of the word. To do this, the word will be copied into accumulator A. It should be noted that this automatically clears the flag. The Y index register will be used to accumulate the weight. An additional albeit straightforward task is to tally the event in EVENTNO. Thus we have:

  INC EVENTNO ;update number of events
  LDAA PORTCL,X ;get data
  LDY #DBASE ;set register Y
  LDAB #8 ;set loop counter
SHIFT ASLA    
  BCC TEST  
  INY   ;accumulate n in register Y
TEST DECB    
  BGT SHIFT ;do 8 bits
  INC 0,Y ;update nn

The sequence from SHIFT to BGT SHIFT forms a while number of shifts <8 do loop. At the end of the loop, the index register Y contains the weight, or number of hits, n, for the event. It then, when combined with DBASE acts as a pointer or vector, pointing to the memory location tallying the number of n-hit events. In fact, it is not really necessary to shift all eight bits in all cases. In the extreme case consider a one-hit event represented by the word with MSB=1, or $80. Then after the first shift, n is determined. The arithmetic shift left inserts 0 into the LSB, so the contents of the accumulator become 0. The loop can then be altered to while accumulator>0 do. The code now becomes:


SHIFT ASLA    
  BCC TEST  
  INY   ;accumulate n in register Y
TEST TSTA    
  BNE SHIFT ;do until all zeros
  INC 0,Y ;update nn

At this point it is necessary to inform the external system that it can again take data. This can be done by the statement

  STAA PORTB,X ;acknowledge ready

since a write to port B generates an output signal at STRB.

A review of the pseudocode outline shows that we are now at the repeat check position of the while EVENTNOTOTAL do loop. It is necessary to check this condition and branch back to the polling loop at CHECK if the condition is true.

  LDAA EVENTNO  
  CMPA TOTAL  
  BLE CHECK ;do while EVENTNO is less than
      ;or equal to TOTAL

The statements following this point correspond to calculating the probabilities and outputting the results. In the simple approach used here, division would require converting the data from 8-bit words to 16-bit words.

  LDAA #8  
  STAA COUNT ;set loop counter
  LDY #DBASE ;get data pointer
STORE CLRA    
  LDAB EVENTNO  
  XDGX    
  CLRA    
  LDAB 1,Y  
  IDIV    
  XDGX   ;n-hit probability in D register
  JSR OUT  
  INY    
  DEC COUNT  
  BGT STORE ;while COUNT is less than or equal to 8
  STOP    

The above coding would achieve the stated objective. Since the objective was poorly defined, a little thought reveals that the program has a major limitation in addition to the shortcomings mentioned previously. The variable EVENTNO, representing NT, is represented by an eight-bit word as an unsigned integer. The maximum integer which may be represented uniquely is 255. All larger integers are represented mod 256. Thus TOTAL is restricted to 255 events which are distributed in some manner over 8-bins according to hit number. On average then, each bin corresponding to the quantity N(n) would contain roughly 32 events, so the average precision attainable would be about 16%. A full description of the objective should have mentioned the desired precision. Note that unless the distribution were known beforehand, it is not possible to define this requirement rigorously-low probability bins could always contain far fewer than the average number of events per bin. In any event the potential precision can be improved enormously if the word length is increased to 16. The average number of events per bin would now be limited to about 8000 giving roughly 1% precision. It is therefore useful to consider modifying the above to 16 bit arithmetic.

Consider first the initialization preamble. This will now take the form:

  LDD #0  
  STD EVENTNO  
  LDY #DBASE ;get data pointer
  LDAB #16  
SET CLR 2,Y  
  INY    
  DECB    
  BGT SET  

The variable EVENTNO is now created as a 16 bit word by using the D accumulator, which is itself a concatenation of the A and B accumulators. Also 16 contiguous memory locations from $02 to $12 above offset DBASE are cleared to initialize the 8 bins of 16-bit words representing N(n). Notice that the relationship between the independent variable n and the address containing the functional value N(n) is no longer the simple equality that obtained previously, but is now addresses=2n,2n+1.

To accommodate this the data processing code must be changed. The weight must be multiplied by 2. For this reason, the weight is accumulated in accumulator B and then shifted left. It is then transferred to the Y index register, to form a pointer to the correct data location. Also, in order touse 16 bit arithmetic the data is updated by adding 1 in the D accumulator rather than a direct increment, which only operates on 1byte. The modified code then becomes:

  LDD EVENTNO ;update number of events
  ADDD #1  
  STD EVENTNO  
  LDAA PORTCL,X ;get data
  CLRB    
SHIFT ASLA    
  BCC TEST  
  INCB    
TEST TSTA    
  BGT SHIFT  
  ASLB    
  XGDY   ;works only if DBASE is $0000
  LDD 0,Y  
  ADDD #1  
  STD 0,Y  


The calculation of the probabilities and the output which follow the end of the major

while EVENTNO # TOTAL do loop is now simpler, since the division process is designed for 16-bit arithmetic.

  LDAA #8  
  STAA COUNT ;set loop counter
  LDX EVENTNO  
  LDY #DBASE ;get data pointer
STORE LDD 2,Y  
  IDIV    
  XDGX    
  JSR OUT  
  INY    
  INY    
  DEC COUNT  
  BGT STORE  
  STOP    

It should be noted that the quantity TOTAL has been treated as a variable. Again this indicates a vagueness in the original program specification. The most flexible approach would be a design in which the experimenter could set the value at will. This would require that the processor also be interfaced to an input device, such as a numeric keypad. An input subroutine would then be necessary. In the absence of such a peripheral, the value would have to be initialized in the code.

To change it would require re-coding and re-assembling the program.

If this approach is adopted, there are two possible initialization procedures. If the quantity were left as a variable, so that the value of TOTAL was actually the address of the memory location containing the required total number, say $abcd, then the initialization would take the form

  LDD #abcd  
  STD TOTAL  

The criterion for ending the while NT # TOTAL takes the form

  LDD EVENTNO  
  CPD TOTAL  
  BLE CHECK  

An alternative is to declare TOTAL as a constant using the EQU pseudo-instruction and the code for this becomes:

TOTAL EQU abcd  
       
  LDD EVENTNO  
  CPD #TOTAL  
  BLE CHECK  

Other aspects may be considered without at this time developing any coding. As it has been described the number of GM tubes in the array is limited to 8. This is certainly not necessary. However, with an 8-bit port, inputting words of greater length requires that the words be presented in one byte segments, and in general, reassembled. In this case however, re-assembly is not required, since we are only interested in the weight. A simple approach would be to modify the weight algorithm so that at the end of each 8-bit analysis, a new byte was read and the accumulation continued. Of course allowance for the larger number of memory locations required would have to be made in the initialization, and in the appropriate loop counting.

As mentioned previously, the approach developed here does not provide the experimenter with any information during data acquisition. Thus there is no way of knowing whether the system is working or not. The type of information which could be provided and the approach taken is varied. A simple hardware approach that does not involve the processor at all is to drive a lamp by the event signal. This is probably the minimum amount of information. The same effect could be achieved by driving a lamp by toggling a pin on port B. This would provide more information since ti would show that the processor was looping. More complex information displays could be considered, and these would likely require a change in the I/O approach. In the new approach, the program would run the display program as a loop, with the data acquisition and processing in an interrupt service routine. In this approach, computer control would pass from the display subprogram to the data acquisition program upon receiving the event signal, which becomes an interrupt request signal. Control would return to the display loop when the data processing of the event was complete. The display loop could take various forms. For example, it could output EVENTNO to an LED display in decimal. It could send N(n) out to a DAC, and the function could be displayed on a monitor.

Finally, one might consider a much more grandiose situation. The experimenter might wish to set up many such arrays at different graphical locations around the world. In this case it would be necessary to consider serial communication. Because the microprocessors are so inexpensive, it would make sense to include one at each site. The information would then have to be transmitted to the central site serially.

2000.09.07