You are on page 1of 30

DEPARTMENT OF ELECTRICAL AND COMPUTER ENGINEERING

UNIVERSITY OF VICTORIA

CENG 355 – MICROPROCESSOR-BASED SYSTEMS


LABORATORY REPORT

Experiment: Project

Title: Signal Monitoring System

Date of Experiment: Nov 16, 2010

Report Submitted on: November 30 , 2010

To: Tony

Names:

Ryan Key V00482077

Cameron Smith V00482018

1
Table of Contents

Objective ......................................................................................................................................... 4
1 Design Solution ....................................................................................................................... 4
1.1 Square Wave Frequency Measurement ............................................................................ 4
1.1.1 Rising Edge Detection Using Edge Port ................................................................... 5
1.1.2 Timer Using the Programmable Interrupt Timer ...................................................... 7
1.2 Resistance Measurement .................................................................................................. 8
1.2.1 Initialization of the ADC .......................................................................................... 9
1.2.2 Displaying the Resistance ....................................................................................... 11
1.3 Saw-tooth Waveform ..................................................................................................... 12
1.3.1 External DAC.......................................................................................................... 12
1.3.2 Configuring the QSPI ............................................................................................. 13
1.4 Saw-tooth Waveform Frequency Update ....................................................................... 15
1.4.1 Detecting the Button Press ...................................................................................... 15
2 Discussion .............................................................................................................................. 17
2.1 Square Wave Frequency Measurement .......................................................................... 17
2.2 Resistance Measurement ................................................................................................ 18
2.3 Saw-tooth Waveform ..................................................................................................... 20
2.4 Improvements to the Saw-Tooth Waveform .................................................................. 21
3 Final Design Specifications Limitations and Errors .............................................................. 22
3.1 Specifications ................................................................................................................. 22
3.2 Limitations ..................................................................................................................... 23
3.3 Errors .............................................................................................................................. 23
4 Conclusions ........................................................................................................................... 24
5 References ............................................................................................................................. 24
6 Appendix ............................................................................................................................... 25
6.1 Pictures ........................................................................................................................... 25
6.2 Code ............................................................................................................................... 26

2
Table of Figures

Figure 1-1 IRQ1_INIT .................................................................................................................... 5


Figure 1-2 IRQ1_handler ................................................................................................................ 6
Figure 1-3 PIT0_Init ....................................................................................................................... 7
Figure 1-4 PIT0_handler ................................................................................................................. 7
Figure 1-5 ADC Result Registers ................................................................................................... 8
Figure 1-6 ADC Initialisation Function ........................................................................................ 10
Figure 1-7 Polling In Main Function ............................................................................................ 11
Figure 1-8 External DAC Wiring ................................................................................................. 12
Figure 1-9 QSPI Initialisation Function ........................................................................................ 14
Figure 1-10 IRQ7_Init .................................................................................................................. 15
Figure 1-11 IRQ7_handler ............................................................................................................ 16
Figure 2-1 Graph of Frequency Measurements ............................................................................ 18
Figure 2-2 Graph of High and Low Resistance Measurements .................................................... 19
Figure 2-3 Graph of Saw-Tooth Frequency .................................................................................. 20
Figure 2-4 Output Filtering ........................................................................................................... 22
Figure 6-1 Lower Limit of saw-Tooth Frequency ........................................................................ 25
Figure 6-2 Upper Limit of Saw-Tooth Frequency ........................................................................ 25

Tables
Table 2-1Square Wave Frequency ................................................................................................ 17
Table 2-2 Resistance Measurements ............................................................................................. 19
Table 2-3 Resistance Accuracy and Uncertainty .......................................................................... 19
Table 2-4 Saw-Tooth Frequency Predictions ............................................................................... 20

3
Objective

To design and implement a system that:

 Measures the frequency of square wave signal from an external function generator.
 Measures the resistance of an on board potentiometer 5k thumb turn potentiometer via
the potential difference between the reference ground and input value measured from the
adjustable terminal.
 Generates a saw-tooth waveform using the Queued Serial Peripheral Interface (QSPI) to
control a 12 bit Digital to Analog Converter (DAC).
 Modifies the frequency of the saw-tooth wave form as the resistance value of a 5k
potentiometer on the MCU Project Board Student Learning Kit is changed

1 Design Solution

1.1 Square Wave Frequency Measurement

To measure the frequency of a square wave it is necessary to detect either the rising or falling
edges of the waveform. To do this the edge port was configured to detect the rising edge of the
square wave signal applied to IRQ7 (PORT NQ). To determine frequency of the square wave it
is necessary to measure the time between two consecutive rising edges. To do this a
Programmable Interrupt Timer (PIT0) was used to count the number of internal clock cycles
between the rising edges. PIT0 counted down from 0xFFFF, starting when the first edge was
detected, until either the second edge was detected or the counter reached zero. If the counter
reached zero an interrupt was generated. The interrupt causes an overflow counter to be
incremented and the counter to restart counting down from 0xFFFF. Upon the second edge of
the square wave the total number of clock cycles that occurred between the two edges was
calculated. Then the square wave frequency was calculated according to the following equation:

1
𝐶𝑜𝑟𝑒 𝐹𝑟𝑒𝑞𝑢𝑒𝑛𝑐𝑒𝑦
𝑆𝑞𝑢𝑎𝑟𝑒 𝑊𝑎𝑣𝑒 𝐹𝑟𝑒𝑞𝑢𝑒𝑛𝑐𝑒𝑦 = 2
𝑇𝑜𝑡𝑎𝑙 𝐶𝑜𝑢𝑛𝑡

4
1.1.1 Rising Edge Detection Using Edge Port

First the edge port was initialized in the function named “IRQ_Init()”. Initializing the edge port
required first disabling all interrupts. Next the corresponding interrupt for pin 1 of port NQ
(IRQ1) was unmasked. The priority and level were set to a value of 3 which was chosen
arbitrarily as being lower than SW1 interrupt and higher than 1. The interrupt enable register
was set to allow interrupts for EP0 pin1. The Data Direction Register (DDR) was marked to
allow all pins on Edge port 0 to input. It is advisable to set pins as inputs even if not being used
because this sets them as high impedance and reduces the risk of damage if an accidental short
occurs. The edge port was set as rising edge sensitive. The ISR location in memory was marked
and interrupts were re-enabled resuming regular program execution.

/*
=======================================================================
* INTERRUPT CONTROLLER INITIALIZATION FUNCTION
=======================================================================
*/
VOID IRQ1_INIT(VOID)
{
MCF5XXX_IRQ_DISABLE(); //DISABLE INTERRUPTS
MCF_INTC0_IMRL &=~ (MCF_INTC_IMRL_INT_MASK1|0X1); //UNMASK (IRQ1) INTERRUPT
MCF_INTC0_ICR01 |= 0B00011011; //INTERRUPT LEVEL 3 PRIORITY 3
MCF_EPORT_EPIER0 = 0B00000010; //ENABLED INTERRUPT FOR EPORT0
PIN 1
MCF_EPORT_EPDDR0 = 0X0; //DATA DIRECTION (INPUT)
MCF_EPORT_EPPAR0 = 0B0000000000000100; //RISING EDGE SENSITIVE
MCF5XXX_SET_HANDLER(64+1,(UINT32) &IRQ1_HANDLER); //LOCATING ISR
MCF5XXX_IRQ_ENABLE(); //ENABLE INTERRUPTS
}

Figure 1-1 IRQ1_INIT

Next the interrupt service routine for rising edge detection was written. Upon a rising edge of the
square wave signal EP0 generates an interrupt. The ISR checks if the timer is running already or
not. If the timer is not already running the ISR starts the timer assuming this is the first rising
edge. If the timer is already running the ISR stops the timer and adds [(0xfff) – (value of the
counter)] to the overflow counter. The frequency is then calculated by dividing the reference
frequency by the number of clock cycles counted. The flag for the EP0 is reset until the next
rising edge occurs.

5
/*
=======================================================================
* IRQ1 Handler
=======================================================================
*/
__interrupt__ void IRQ1_handler ()
{
int count;
int delay;
mcf5xxx_irq_disable(); // Mask all IRQs

if(MCF_PIT0_PCSR & 0x0001) // Is this the first edge?


{ // 2nd Edge
count = 0xffff-MCF_PIT0_PCNTR; // temporary variable
MCF_PIT0_PCSR &=~MCF_PIT_PCSR_EN; // Disable Counter
timer_pulses += count; // Calculate Total Pulses
MCF_PIT0_PMR = 0xffff; // Reset the counter
for(delay=1000000;delay>0;delay--){} // Delay to prevent overflow of buffer
printf("Frequency = %d Hz\n\r",(int)(FREQ_Hz/timer_pulses)); // Calc & Display Frequency
printf("ADC: %d ohms\n",(5000*(MCF_ADC_ADRSLT0/8)/4095)); // Calc & Display Resistance

} else // 1st Edge


{
MCF_PIT0_PCSR |=MCF_PIT_PCSR_EN; // Start Timer
timer_pulses =0; // Reset the Overflow Counter
}

MCF_EPORT0_EPFR = 0xff; // Clear Interrupt Flags


mcf5xxx_irq_enable(); // Un-Mask All IRQs
}

Figure 1-2 IRQ1_handler

6
1.1.2 Timer Using the Programmable Interrupt Timer

Configuring the programmable interrupt timer required enabling the overwrite enable bit and
enabling interrupt generation when the counter reached zero. The initial value was set to the
maximum of 0xFFFF. The corresponding interrupt for overflow was unmasked. The priority
was set to level 2 and the location of the ISR in memory was marked.

/*
=======================================================================
* Timer Initialization Function
=======================================================================
*/
void PIT0_Init(void)
{
mcf5xxx_irq_disable(); // Mask all IRQs

MCF_INTC0_IMRH &=~ MCF_INTC_IMRH_INT_MASK55; //Unmask PIT Interrupt


MCF_INTC0_ICR55 |= 0b00010010; //interrupt level 2 priority 2
mcf5xxx_set_handler(64+55,(uint32) &PIT0_handler); // Set the location of the overflow ISR
MCF_PIT0_PCSR = 0x0
|MCF_PIT_PCSR_OVW //Automatic Overwrite enable
|MCF_PIT_PCSR_PIE; //Enable PIT interrupts

MCF_PIT0_PMR = 0xffff; //start count value at max


mcf5xxx_irq_enable(); // Un-Mask All IRQs
}

Figure 1-3 PIT0_Init

When the Programmable interrupt timer overflowed an interrupt was generated. Then the
corresponding ISR was run which incremented the counter value by 0xFFFF. Then the interrupt
flag in the PCSR for the PIT was cleared by writing a 1 to it. The PIT is already set to loop
around so the timing sequence continues automatically.

/*
=======================================================================
* Timer Overflow Interrupt Handler
=======================================================================
*/
__interrupt__ void PIT0_handler ()
{
timer_pulses += 0xffff; // Increment Overflow Counter by 0xFFFF

MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF; // Clear the Overflow Interrupt Flag by Writing 1 to it


}

Figure 1-4 PIT0_handler

7
1.2 Resistance Measurement

The second objective was to measure the resistance of a 5kΩ potentiometer. This was
accomplished by measuring the voltage at the wiper of the potentiometer with the processors’ 12
bit analog to digital converter. The voltage measured is proportional to the resistance between
the wiper and ground (or the voltage supply). The relationship is given by:

𝑉𝑤𝑖𝑝𝑒𝑟 𝑉𝑤𝑖𝑝𝑒𝑟
𝑅𝑒𝑠𝑖𝑠𝑡𝑎𝑛𝑐𝑒 = ∗ 𝑅𝑡𝑜𝑡𝑎𝑙 = ∗ 5𝑘𝛺
𝑉𝑠𝑝𝑝𝑙𝑦 3.3 𝑉𝑜𝑙𝑡𝑠

Because the analog to digital converters on the processor are 12 bit the voltage is readable as a
number from 0x000 to 0xFFF corresponding to VRef_Low to VRef_High. In this program the lower
reference voltage was set to 0 volts and the upper reference voltage 3.3 volts. The result from an
analog to digital conversion is reported in a 16 bit result register were bits 0-2 are all zero and
bits 3-14 are the result and bit 15 is the extension of the results sign where 0 indicated a positive
result and 1 is negative.

BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Sign Extend Result 0 0 0
Figure 1-5 ADC Result Registers

Because the result reported in bits 3-14 it is shifted up by 3 bits effectively multiplying it by 8.
Also because we will never have a negative number the 15th bit will always be 0. To obtain the
16 bit result the value in the 16 bit result register simply needs to be shifted down by 3 bits or
equivalently divided by 8. This results in the following equation to convert the reported number
to a voltage.

𝑅𝑒𝑠𝑢𝑙𝑡𝑅𝑒𝑔𝑖𝑠𝑡𝑜𝑟 8
𝑉 = 3.3 ∗
0𝑥𝐹𝐹𝐹

Then the resistance is given by the combination of the previous two equations as:

𝑅𝑒𝑠𝑢𝑙𝑡𝑅𝑒𝑔𝑖𝑠𝑡𝑜𝑟 8
0𝑥𝐹𝐹𝐹
𝑅 = 3.3 𝑉𝑜𝑙𝑡𝑠 ∗ 5𝑘𝛺
3.3 𝑉𝑜𝑙𝑡𝑠
𝑅𝑒𝑠𝑢𝑙𝑡𝑅𝑒𝑔𝑖𝑠𝑡𝑜𝑟 8
𝑅= ∗ 5𝑘𝛺
0𝑥𝐹𝐹𝐹

8
1.2.1 Initialization of the ADC

First the analog to digital converter needed to be initialized. This was accomplished by writing
another dedicated initialization function. The first line of the ADC initialization function declares
a new variable used by a for-loop which provides a delay to ensure the ADC successfully starts.
Next the power configuration register is configured so that the ADC can be started and will not
automatically power down. Next the loop sequential mode of operation was selected. Then the
ADC clock was set by setting the system clock divider such that the ADC operated at less than 5
MHz. Then zero crossing detection was disabled as we do not need it. Next the sampling order
was selected such that AN0, then AN1, AN2, …,AN7 were sampled in order. All samples above
AN1 were disabled as we only needed to sample 2 different analog voltages. Next the lower
limits and higher limits were set to the minimum and maximum values, effectively disabling
them. Then the offset was set to zero for both ADCs. The calibration register was set to zero
because the standard high and low reference voltages were used. Then a delay was added
because there must be a delay after power up before the ADCs can be started. We found that at
the low clock frequency of the boards in the lab this delay was not necessary. However if the
clock frequency was increased, or there were less operations between the modification of the
power register and the starting of the ADCs this delay would be necessary. An alternative is to
poll the status bits in the power register until the ADCs are powered up before starting the first
scan.

9
/*
=======================================================================
* ADC Initialization
=======================================================================
*/
void ADC_init()
{
int n=0;
MCF_GPIO_PANPAR = 0xFF; //sets port AN to primary function (ADC)
MCF_ADC_POWER = 0b0000000011010100; //turns on the ADC and prevents auto power down
MCF_ADC_CTRL1 = 0b0000000000000010; //loop sequential everything else disabled
MCF_ADC_CTRL2 = 0b0000000000000100; //set divisor system clock/2(4+1)
MCF_ADC_ADZCC = 0; //zero crossing disabled
MCF_ADC_ADLST1 = 0b0011001000010000; //sampling each input value in order
MCF_ADC_ADLST2 = 0b0111011001010100; //same thing for converter b
MCF_ADC_ADSDIS = 0x0004; // Disable AN2…AN7
MCF_ADC_ADLLMT0 = 0; //lower limits=0
MCF_ADC_ADLLMT1 = 0; //
MCF_ADC_ADHLMT0 = 0x7FF8; //higher limits = max
MCF_ADC_ADHLMT1 = 0x7FF8; //
MCF_ADC_ADOFS0 = 0; //offset to 0
MCF_ADC_ADOFS1 = 0; //ditto
MCF_ADC_CAL = 0; //used Vref low and Vref high
For(n=0;n<1000;n++){} //If the clock Freq is high a delay is necessary
MCF_ADC_CTRL1 = 0b0010000000000010; //enable ADC

Figure 1-6 ADC Initialisation Function

10
1.2.2 Displaying the Resistance

Polling was used to display the current resistance of the potentiometer. This was accomplished
by a printf() statement that was added to the frequency measurement edgeport ISR to display the
resistance value at the same time as the frequency is displayed. This makes it easier to read for
the user when higher frequencies were being measured. High frequency resulted in several print
statements being executed every second and a resistance value would not have enough time to be
displayed due to the constant interrupts from the frequency measurement system. The resistance
was calculated using the previously explained formula, where the ADC result register value is
divided by 8 and 0xFFF and then multiplied by 5000.

/*
=======================================================================
* Main Function
=======================================================================
*/
int main()
{
int i;
IRQ1_Init(); //Call Initialization Functions
IRQ7_Init(); //
PIT0_Init(); //
ADC_init(); // Initialize ADC
QSPI_Init(); //

while(1) //Inf Loop


{
for(i=0;i<FREQ_Hz/7;i++){} // Delay
printf("ADC: %d ohms\n",(5000*(MCF_ADC_ADRSLT0/8)/4095)); //Display Resistance
}

return 0;
}

Figure 1-7 Polling In Main Function

11
1.3 Saw-tooth Waveform

Generating a saw-tooth waveform required both the correct configuration of the on chip queued
serial peripheral interface and the external 12-Bit DAC.

1.3.1 External DAC

The wiring diagram for the external DAC is shown in Error! Reference source not found.. The
supply voltage for the DAC was 3.3 Volts and the analog ground the same as that used for the
microcontroller. Connections were made from the chip select, serial clock and serial output data
pins from the header on the PBMCUSLK board to the corresponding chip select, serial clock and
serial data inputs on the DAC. The reference voltage pin for converter A on the DAC was
connected to the 3.3 supply voltage. The /LDAC latch pin was connected to ground, so that the
serial data would be loaded and converted on the rising edge of the chip select signal. The
hardware shutdown pin /SHDN was connected to 3.3 volts (Vdd) so that the DACs would not
enter their low-power standby mode.

Figure 1-8 External DAC Wiring

12
1.3.2 Configuring the QSPI

First the QSPI mode register was set so that master mode is enabled, the QSPI is actively driven
between transfers, the transfer size is 16 bits, the inactive state of the QSPI clock is zero and data
is captured on the leading edge of the QSPI clock. The Baud rate divider was set to the minimum
by setting the baud rate divider to 255.

Then the QSPI delay register was changed so that there is the default delay between the assertion
of the chip select and the first valid QSPI clock transition. Also the delay after transfer was set to
the default value. The QSPI enable bit is not set.

Next the QSPI wrap register was modified so that halt was disabled, and wraparound enabled.
The wrap around location was set to RAM entry Zero. The QSPI chip select was set to an
inactive state of one. This was chosen because the chip select for the external DAC is active low.

All QSPI interrupts were disabled by writing zero to the QSPI Interrupt Register. All Port QS
pins were configured as outputs and assigned their QSPI functions.

Next a for-loop was used to load the serial data into the Transmit RAM to be sent to the external
DAC. In the same loop the Command RAM was loaded. The command RAM was loaded with
the same value of 0x4800 in all locations. This configures: the chip select to toggle on every
word transfer, a transfer length of 16 bits, the default delay after transfer, a delay of one half
clock cycle between chip select and the first clock transition. Chip select 0 (CS0) was made
active.

In the second to last instruction the QSPI mode register was updated so that the baud rate divisor
was the minimum value of 2, resulting in the maximum baud rate. The final instruction changes
the QSPI delay register, and setting the SPE bit which enables the QSPI.

13
/*
=======================================================================
* QSPI Initialization Function
=======================================================================
*/
void QSPI_Init(void)
{

int i;

//set baud rate to fsys/2*255 inactive low and capture on leading and change on following
MCF_QSPI_QMR = 0b1000000011111111;
MCF_QSPI_QDLYR = 0x0404; //set delay to 0x4 before and after
MCF_QSPI_QWR = 0b0101111100000000; // wrap enabled, wrap to zero, chip select active low
MCF_QSPI_QIR = 0; //disabled all interrupts

MCF_GPIO_PQSPAR = 0x5555; // Assigning pins to the QSPI


MCF_GPIO_DDRQS=0xFFFF; // Setting the pins to the QSPI as outputs

//RAM loading code

for(i=0; i<16;i++)
{
MCF_QSPI_QAR = i; //Set Ram address to 0,1,2,3,4,5..E,F
MCF_QSPI_QDR=0x7000+i*(0x111); // Write Data 0x7111, 0x7222…0x7FFF
MCF_QSPI_QAR = 0x20+i; // Set Ram address to 0x20,0x21, …0x2F
MCF_QSPI_QDR=0x4800; // Write Instruction 0x4800 to all locations
}

MCF_QSPI_QMR = 0b1000000000000010; //baud rate set to fastest value (divisor = 2)


MCF_QSPI_QDLYR = 0x8808; //delays
}

Figure 1-9 QSPI Initialisation Function

14
1.4 Saw-tooth Waveform Frequency Update

The frequency of the saw-tooth waveform needed to be updated when switch number one was
pressed. The frequency was selected by changing the resistance of a second potentiometer. The
ADCs were previously configured so that the second potentiometer was read from pin AN1.

1.4.1 Detecting the Button Press

First the edge port was initialized in the function named “IRQ7_Init()”. Initializing the edge port
required first disabling all interrupts. Next the corresponding interrupt for pin 7 of port NQ
(IRQ7) was unmasked. The priority and level were set to a value of 5 which was chosen
arbitrarily as being higher than anything else in the program but not at the highest level of 7. The
interrupt enable register was set to allow interrupts for EP0 pin7. The Data Direction Register
(DDR) was marked to allow all pins on Edge port 0 to input. This was already done in the other
edge port initialisation function; however by repeating it ensures proper configuration. The edge
port was set as rising edge sensitive. The ISR location in memory was marked and interrupts
were re-enabled resuming regular program execution.

/*
=======================================================================
* Interrupt Controller Initialization Function
=======================================================================
*/
void IRQ7_Init(void)
{
mcf5xxx_irq_disable(); // Mask all IRQs

MCF_INTC0_IMRL &=~ (MCF_INTC_IMRL_INT_MASK7|0x1); // Unmask (IRQ1) interrupt


MCF_INTC0_ICR7 = 0b00101101; //interrupt level 5 priority 5
MCF_EPORT_EPIER0 |= 0b10000000; // enabled interrupt for pin 7
MCF_EPORT_EPDDR0 = 0x0; // data direction (input)
MCF_EPORT_EPPAR0 |= 0b0100000000000000; // port 4 rising edge sensitive
mcf5xxx_set_handler(64+7,(uint32) &IRQ7_handler); // locating ISR

mcf5xxx_irq_enable(); // Un-Mask All IRQs


}

Figure 1-10 IRQ7_Init

15
On a rising edge of a switch one (SW1) press, the edge port generates an interrupt and runs the
following ISR. The ISR first disables interrupts and then updates the baud rate divider between 2
and 255 corresponding to the value of the analog voltage of the second potentiometer. This
voltage is read as a 12 bit value stored in the 16 bit result register for AN1.The flag for the
interrupt is reset then all interrupts are un-masked.

/*
=======================================================================
* IRQ7 Handler
=======================================================================
*/
__interrupt__ void IRQ7_handler ()
{
mcf5xxx_irq_disable();

// Set the baud Rate divisor between 2 and the maximum of 255

MCF_QSPI_QMR = 0b1000000000000010 + (253*MCF_ADC_ADRSLT1/8/0xfff);


MCF_EPORT0_EPFR = 0xff; //Clear EPORt Flag

mcf5xxx_irq_enable();
}

Figure 1-11 IRQ7_handler

16
2 Discussion

2.1 Square Wave Frequency Measurement

A series of frequencies were generated using the function generator and then measured
frequency was compared with the generated frequency.
Table 2-1Square Wave Frequency

Freq Measured
1 1
10 9
100 100
1000 1000
10000 10100
20000 20400
30000 30900
40000 41666
50000 52700
60000 64100
70000 75500
80000 87000
90000 99000
100000 110000
110000 125000
120000 126000
130000 126000
140000 75000

As seen in table 3.1 the results are within a 10-15% (or less) range of the actual frequency until
approximately 110 kHz, and then the values hit a clear maximum and start to fall as the input
signal becomes too high frequency to process properly. This is caused by a very small number of
cycles occurring between rising edges of the input signal as well as the set up time in initializing
the timer. 110 kHz is approximately the maximum useful range of this system. The minimum
range chosen was 1Hz and although smaller frequencies are measurable this would require
scaling of the clock frequency and a more complicated design solution. This range was
determined to be sufficient for the purposes of this design. As seen in Figure 3.1 the measured
frequency on average is 9% greater than the actual frequency but this error is much less for lower
frequencies and can get higher for higher frequencies. The error for the initialization of the
counter become a larger factor with smaller time between rising edges of the input signal.

17
Comparison of Measured vs Actual
Frequency of Square Wave Signal
100000

10000
Measured Frequency

1000
y = 1.0966x
100

10

1
1 10 100 1000 10000 100000
Actual Frequency

Figure 2-1 Graph of Frequency Measurements

2.2 Resistance Measurement

The testing process for resistance involved measuring the input voltage with a DMM and
calculating its resistance based of the same calculations done in the program. As is to be
expected the accuracy of an analog voltage input is not nearly as good as that of a DMM over a
range of voltages. In general the measured value fluctuated with an uncertainty of about +/-
0.3%. Unfortunately due to the location of the resistor and the nature of the measurements being
made measuring the actual resistance with an ohmmeter was not possible. Since the system was
calculating resistance based on the potential measured by the ADC a comparison of voltages was
more appropriate. The minor offsets found between the measured vales and the theoretical values
are likely caused by ADC conversion process leading to a slightly different value than that found
by the DMM. There are limits on the accuracy of the measured resistance involve the lack of
ability to measure current as well so the model is assumed linear compared to the potential
change which is not necessarily true.

18
Potentiometer Theoretical Measured Resistance Average
Voltage Resistance Min Max
0.001 1.515152 0 2 1
0.109 165.1515 130 141 135.5
0.54 818.1818 775 790 782.5
0.93 1409.091 1379 1389 1384
1.2 1818.182 1790 1800 1795
2 3030.303 3020 3028 3024
2.56 3878.788 3869 3878 3873.5
2.97 4500 4480 4490 4485
3.3 5000 4993 5000 4996.5
Table 2-2 Resistance Measurements

Resistance Range Uncertainty Accuracy Relative


Measurement Of Measurements To DMM
1.0 2 0.04% -34.00%
135.5 11 0.22% -17.95%
782.5 15 0.30% -4.36%
1384 10 0.20% -1.78%
1795 10 0.20% -1.28%
3024 8 0.16% -0.21%
3873.5 9 0.18% -0.14%
4485 10 0.20% -0.33%
4996.5 7 0.14% -0.07%
Table 2-3 Resistance Accuracy and Uncertainty

6000

5000
Measured Resistance

4000

3000
Low
2000
High
1000

0
0 1000 2000 3000 4000 5000 6000
Actual Resistance

Figure 2-2 Graph of High and Low Resistance Measurements

19
2.3 Saw-tooth Waveform

The testing done on the saw-tooth waveform again consisted of comparing the actual
values measured with the oscilloscope with that of the predicted frequency being generated. The
limits found in this system were partially due to the limits of the resistance measurement system
which can be seen in section 3.2. The maximum and minimum values were determined by the
maximum and minimum allowable baud rates on the QSPI. The rate at which the signals were
sent was scaled by a value from 2-255. This being a scaled value of the bus clock frequency.
There was no specific accuracy or range required so these maximums and minimums are the
limits of the QSPI and the DEMO board. The predicted frequency measurement attempts to
estimate the rate at which the data is being transferred but cannot predict the internal error
margins from each signal. As can be seen in Figure 2-3 and Table 2-4 the results are typically
within about 1% of the actual value.

Actual Predicted
Frequency Frequency
18800 18600
4499 5000
2300 2367
806 832
441 453
350 360
215 221
185 191
Table 2-4 Saw-Tooth Frequency Predictions

10000
Measured Frequencey

1000

100
100 1000 10000
Actual Frequencey

Figure 2-3 Graph of Saw-Tooth Frequency

20
The frequency of the saw-tooth waveform is dependent on the rate that the DAC is updated. For
each cycle of the waveform there are 16 different equally spaced voltage levels between 0 and
3.3 volts. For each of these sixteen levels one 16 bit word needed to be sent to the DAC. Each bit
takes one SPI clock cycle to send to the DAC. The baud rate of the QSPI sets the duration or rate
of this clock. From this the frequency of the saw-tooth waveform could be predicted according to
the following equation:

1
𝑓𝑠𝑎𝑤𝑡𝑜𝑜𝑡 𝑕 = 2 𝑓𝑐𝑜𝑟𝑒
16 ∗ 16 ∗ 𝐵𝑎𝑢𝑑𝑒 𝑅𝑎𝑡𝑒 𝐷𝑖𝑣𝑖𝑠𝑜𝑟 + 𝐷𝑒𝑙𝑎𝑦𝑠

Where the baud rate divisor is a number between 2 and 255 and is stored in the register referred
to as MCF_QSPI_QMR in the project code. Because this is a relatively simple formula it was
added to the code such that the current saw-tooth waveform frequency was displayed every time
the resistance value was. This was accomplished by adding the following piece of code to the
main function and the interrupt service routine for edge port pin 1.

printf("Sawtooth frequency: %d Hz\n",(FREQ_Hz/(16*16*(0xff&MCF_QSPI_QMR)+160)));

2.4 Improvements to the Saw-Tooth Waveform

The saw-tooth waveform produced by the DAC, had very noticeable discreet steps in the rising
portion of the waveform. This was a limitation introduced due to the limited QSPI buffer size.
However this could be improved slightly by adding a low pass output filter on the output of the
DAC. Unfortunately the low pass output filter will only provide satisfactory smoothing of the
output waveform for sufficiently high output frequencies. Also for very high frequencies the
output filter will severely distort the waveform by rounding the sharp peaks.

The worst distortion was noticed at the lower peaks of the filtered waveform, because the section
of the waveform with the highest frequency components is the falling edge. To counter this
effect, it is preferable if the signal is only filtered on the rising edge and does not filter the steep
falling edge. To partially accomplish this a diode can be placed in parallel with the low pas
filter’s resistor, then the only noticeable distortion occurs when the wave form is less than 0.6
volts, the turn on voltage of the diode. The resulting output wave is shown in Figure 2-4.

21
Figure 2-4 Output Filtering

3 Final Design Specifications Limitations and Errors

3.1 Specifications

The design specifications were for a system that sensed the frequency of a square wave
signal from 0.0V to 3.3V of a function generator. The system measured the resistance of two on
board potentiometer via an analog voltage signal. The second potentiometer's measured value
for resistance was used to calculate the desired frequency of a saw-tooth wave form to be
generated. This was to be done using a 12 bit D/A converter and a QSPI module. The system is
expected to recognize the event of a push button being triggered to update the QSPI output
according to the value of the resistor and result in a new saw-tooth waveform being generated.
This is fairly close to the specification in the manual with only a few minor changes. These
changes included a function that approximated the frequency of the saw-tooth waveform
according to signal from the potentiometer. The print statements were slightly modified in that
they printed the resistance value, the frequency of the incoming signal and the current saw-tooth
frequency with every new input frequency measurement. This avoided issues with the resistance
measurement of the first potentiometer as for high frequency input signals the value of the
resistor was almost never displayed and the saw-tooth waveforms frequency only appeared when
SW1 was pressed causing it to be quickly wiped off the output screen by following statements.

22
3.2 Limitations

The limitations of the design for the frequency measurement included the limit due to the
internal clock frequency of the hardware. This limited the maximum and minimum frequencies
measurable as for low frequencies the clock would eventually overflow both the counter and the
overflow buffer which caused the limit of the lower frequency to be around 1 Hz. The higher
frequencies only allowed for a small number of clock cycles between rising edges of the
measured frequency leading to less accurate measurement. These measurements were also
affected by the overhead of the counting setup such as resetting the counter, starting the counter,
interrupt processing time, and various other time constraints that are expected but cannot be
compensated for perfectly.

Limitations of the resistance measurement systems included the sensitivity to voltage


difference by the M52233 DEMO board as well as the quality of the potentiometers used. The
resistance had a uncertainty of about 0.3% for the actual value of resistance although the error
found for values nearing zero tended to be less accurate as there is a small amount of noise that
greatly effects the signal at very low voltages.

Limitations of the saw-tooth generator included the number of points along the waveform
that could be sent using the QSPI as well as the number of bits used to describe each point. The
QSPI could only store 16 values in its Transmit ram so as the baud rate decrease the signal began
to look more and more like a digital signal and less like an analog one due to discrete voltages
for each point. A smoother curve was created using rectifiers as mentioned in section 3.4

3.3 Errors

Some errors and issues encountered included unexpected hardware malfunctions such as,
what we believe to have been a damaged DAC chip. There was an error in the lab manual that
caused a bit of a setback. This was a switch marked as being configured to a different IO port
than its actual configuration. The lab website corrected this mistake but it was still a little
frustrating. In choosing the appropriate configuration for the operation of the QSPI module
features such as chip select edge sensitivity are not immediately apparent in the design
specifications and were adjusted accordingly during the design process which required a lot of
guess and check testing. The majority of the issues found were in configuration of the registers
for the QSPI as we basically went through each register used bit by bit determining the
appropriate values. Similar issues occurred with the design of the frequency measurement
system but this was much more straightforward as a template was already laid out online with
some convenient hints and tips.

23
4 Conclusions

This Lab offered an opportunity to become familiar with the various systems at work in
microcontrollers as well as interfacing with peripherals and other external devices.

5 References

1. A. Morgan, D. Rakhmatov and K Jones, CENG 355: Microprocessor-Based Systems


Laboratory Manual, 1st ed., University of Victoria, Victoria, BC, 2009

2. MCF52235 ColdFire® Integrated Microcontroller Reference Manual, 5th ed., Freescal


Semiconductor, Arizona, 2006, pp. 11-24, 205-246, 427-442, 493-530

3. MCF52233 DEMO Reference Manual, 5th ed., Freescal Semiconductor, Arizona, 2006

4. Microchip Technology Inc., (2007), MCF4921/4922 Data Sheet [Online]. Available:


http://ww1.microchip.com/downloads/en/DeviceDoc/21897B.pdf

24
6 Appendix
6.1 Pictures

Figure 6-1 Lower Limit of saw-Tooth Frequency

Figure 6-2 Upper Limit of Saw-Tooth Frequency

25
6.2 Code

//#include "support_common.h" /* include peripheral declarations and more */


#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
/* Standard IO is only possible if Console or UART support is enabled. */
#include <stdio.h>
#endif

/*
=======================================================================
* File: main.c.
* Purpose: Using PIT0 timer to measure the frequency of a square wave
signal.
* Notes: The timer is configured in the free-running operation mode.
The square wave is to be connected to IRQ1 (pin 33 of the
M52233DEMO board I/O connector). The interrupt handler for
IRQ1 measures the number of timer pulses within the square
wave period, calculates the period and the frequency of the
square wave, and sends them to the console screen. The
timer’s overflow interrupt handler increases the number of
timer pulses by 0xFFFF.
=======================================================================
*/
#include <stdio.h>
#include "common.h"

#define MCF_INTC_IMRH_INT_MASK55 (0x800000)


#define MCF_INTC_IMRL_INT_MASK1 (0x2)
#define MCF_INTC_IMRL_INT_MASK7 (0b10000000)
#define MCF_EPORT0_EPFR (*(volatile unsigned char
*)(&__IPSBAR[0x130006]))

#define FREQ_Hz 12500000


#define H char 'H'

uint32 timer_pulses = 0;
uint16 previous;
uint16 current;
uint32 period, frequency;

__interrupt__ void PIT0_handler ();


__interrupt__ void IRQ1_handler ();
__interrupt__ void IRQ7_handler ();

/*

26
=======================================================================
* ADC Initialization
=======================================================================
*/
void ADC_init()
{
int n=0;
MCF_GPIO_PANPAR = 0xFF; //sets port AN to primary function (ADC)
MCF_ADC_POWER = 0b0000000011010100; //turns on the ADC and prevents auto power down
MCF_ADC_CTRL1 = 0b0000000000000010; //loop sequential everything else disabled
MCF_ADC_CTRL2 = 0b0000000000000100; //set divisor system clock/2(4+1)
MCF_ADC_ADZCC = 0; //zero crossing disabled
MCF_ADC_ADLST1 = 0b0011001000010000; //sampling each input value in order
MCF_ADC_ADLST2 = 0b0111011001010100; //same thing for converter b
MCF_ADC_ADSDIS = 0x0004; // Disable AN2…AN7
MCF_ADC_ADLLMT0 = 0; //lower limits=0
MCF_ADC_ADLLMT1 = 0; //
MCF_ADC_ADHLMT0 = 0x7FF8; //higher limits = max
MCF_ADC_ADHLMT1 = 0x7FF8; //
MCF_ADC_ADOFS0 = 0; //offset to 0
MCF_ADC_ADOFS1 = 0; //ditto
MCF_ADC_CAL = 0; //used Vref low and Vref high
For(n=0;n<1000;n++){} //If the clock Freq is high a delay is necessary
MCF_ADC_CTRL1 = 0b0010000000000010; //enable ADC

/*
=======================================================================
* Timer Initialization Function
=======================================================================
*/
void PIT0_Init(void)
{
mcf5xxx_irq_disable(); // Mask all IRQs

MCF_INTC0_IMRH &=~ MCF_INTC_IMRH_INT_MASK55; //Unmask PIT Interrupt


MCF_INTC0_ICR55 |= 0b00010010; //interrupt level 2 priority 2
mcf5xxx_set_handler(64+55,(uint32) &PIT0_handler); // Set the location of the overflow ISR
MCF_PIT0_PCSR = 0x0
|MCF_PIT_PCSR_OVW //Automatic Overwrite enable
|MCF_PIT_PCSR_PIE; //Enable PIT interrupts

MCF_PIT0_PMR = 0xffff; //start count value at max


mcf5xxx_irq_enable(); // Un-Mask All IRQs
}

/*
=======================================================================
* QSPI Initialization Function
=======================================================================
*/
void QSPI_Init(void)
{

27
int i;

//set baud rate to fsys/2*255 inactive low and capture on leading and change on following
MCF_QSPI_QMR = 0b1000000011111111;
MCF_QSPI_QDLYR = 0x0404; //set delay to 0x4 before and after
MCF_QSPI_QWR = 0b0101111100000000; // wrap enabled, wrap to zero, chip select active low
MCF_QSPI_QIR = 0; //disabled all interrupts

MCF_GPIO_PQSPAR = 0x5555; // Assigning pins to the QSPI


MCF_GPIO_DDRQS=0xFFFF; // Setting the pins to the QSPI as outputs

//RAM loading code

for(i=0; i<16;i++)
{
MCF_QSPI_QAR = i; //Set Ram address to 0,1,2,3,4,5..E,F
MCF_QSPI_QDR=0x7000+i*(0x111); // Write Data 0x7111, 0x7222…0x7FFF
MCF_QSPI_QAR = 0x20+i; // Set Ram address to 0x20,0x21, …0x2F
MCF_QSPI_QDR=0x4800; // Write Instruction 0x4800 to all locations
}

MCF_QSPI_QMR = 0b1000000000000010; //baud rate set to fastest value (divisor = 2)


MCF_QSPI_QDLYR = 0x8808; //delays
}

/*
=======================================================================
* INTERRUPT CONTROLLER INITIALIZATION FUNCTION
=======================================================================
*/
VOID IRQ1_INIT(VOID)
{
MCF5XXX_IRQ_DISABLE(); //DISABLE INTERRUPTS
MCF_INTC0_IMRL &=~ (MCF_INTC_IMRL_INT_MASK1|0X1); //UNMASK (IRQ1) INTERRUPT
MCF_INTC0_ICR01 |= 0B00011011; //INTERRUPT LEVEL 3 PRIORITY 3
MCF_EPORT_EPIER0 = 0B00000010; //ENABLED INTERRUPT FOR EPORT0 PIN 1
MCF_EPORT_EPDDR0 = 0X0; //DATA DIRECTION (INPUT)
MCF_EPORT_EPPAR0 = 0B0000000000000100; //RISING EDGE SENSITIVE
MCF5XXX_SET_HANDLER(64+1,(UINT32) &IRQ1_HANDLER); //LOCATING ISR
MCF5XXX_IRQ_ENABLE(); //ENABLE INTERRUPTS
}

/*
=======================================================================
* Interrupt Controller Initialization Function
=======================================================================
*/
void IRQ7_Init(void)
{
mcf5xxx_irq_disable(); // Mask all IRQs

MCF_INTC0_IMRL &=~ (MCF_INTC_IMRL_INT_MASK7|0x1); // Unmask (IRQ1) interrupt


MCF_INTC0_ICR7 = 0b00101101; //interrupt level 5 priority 5
MCF_EPORT_EPIER0 |= 0b10000000; // enabled interrupt for pin 7
MCF_EPORT_EPDDR0 = 0x0; // data direction (input)
MCF_EPORT_EPPAR0 |= 0b0100000000000000; // port 4 rising edge sensitive

28
mcf5xxx_set_handler(64+7,(uint32) &IRQ7_handler); // locating ISR

mcf5xxx_irq_enable(); // Un-Mask All IRQs


}

/*
=======================================================================
* Timer Overflow Interrupt Handler
=======================================================================
*/
__interrupt__ void PIT0_handler ()
{
timer_pulses += 0xffff; // Increment Overflow Counter by 0xFFFF

MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF; // Clear the Overflow Interrupt Flag by Writing 1 to it


}

/*
=======================================================================
* IRQ1 Handler
=======================================================================
*/
__interrupt__ void IRQ1_handler ()
{
int count;
int delay;
mcf5xxx_irq_disable(); // Mask all IRQs

if(MCF_PIT0_PCSR & 0x0001) // Is this the first edge?


{ // 2nd Edge
count = 0xffff-MCF_PIT0_PCNTR; // temporary variable
MCF_PIT0_PCSR &=~MCF_PIT_PCSR_EN; // Disable Counter
timer_pulses += count; // Calculate Total Pulses
MCF_PIT0_PMR = 0xffff; // Reset the counter
for(delay=1000000;delay>0;delay--){} // Delay to prevent overflow of buffer
printf("Frequency = %d Hz\n\r",(int)(FREQ_Hz/timer_pulses)); // Calc & Display Frequency
printf("ADC: %d ohms\n",(5000*(MCF_ADC_ADRSLT0/8)/4095)); // Calc & Display Resistance
printf("Sawtooth frequency: %d Hz\n",(FREQ_Hz/(16*16*(0xff&MCF_QSPI_QMR)+160)));

} else // 1st Edge


{
MCF_PIT0_PCSR |=MCF_PIT_PCSR_EN; // Start Timer
timer_pulses =0; // Reset the Overflow Counter
}

MCF_EPORT0_EPFR = 0xff; // Clear Interrupt Flags


mcf5xxx_irq_enable(); // Un-Mask All IRQs
}

/*
=======================================================================
* IRQ7 Handler
=======================================================================
*/
__interrupt__ void IRQ7_handler ()
{

29
mcf5xxx_irq_disable();

// Set the baud Rate divisor between 2 and the maximum of 255

MCF_QSPI_QMR = 0b1000000000000010 + (253*MCF_ADC_ADRSLT1/8/0xfff);


MCF_EPORT0_EPFR = 0xff; //Clear EPORt Flag

mcf5xxx_irq_enable();
}

/*
=======================================================================
* Main Function
=======================================================================
*/
int main()
{
int i;
IRQ1_Init(); //Call Initialization Functions
IRQ7_Init(); //
PIT0_Init(); //
ADC_init(); // Initialize ADC
QSPI_Init(); //

while(1) //Inf Loop


{
for(i=0;i<FREQ_Hz/7;i++){} // Delay
printf("ADC: %d ohms\n",(5000*(MCF_ADC_ADRSLT0/8)/4095)); //Display Resistance
//Dissplay the sawtooth frequencey
printf("Sawtooth frequency: %d Hz\n",(FREQ_Hz/(16*16*(0xff&MCF_QSPI_QMR)+160)));

return 0;
}

30

You might also like