CENG 412 Embedded Systems Lab 8 Period, Frequency, PulseWidth and Duty Cycle measurement Name ______________ Part A ___________ Part B _____________ Introduction In this lab you will use the Input Capture function of the HCS12 Timer system to measure the time between rising and falling edge events of a TTL waveform. Attention to register detail is a must in this kind of work. Equipment 1. HCS12 workstation, Standard bench equipment Procedure: Part A - Period and Frequency measurement 1. Look at the AD9S12D- H1 Pinouts diagram on the course web site – click on the HCS12 Board Layout and Connector Pins link. Determine what pin is connected to PT0/IOC0. By looking at the Demo Board Layout and Connector Pins link you can verify that Switch 8 connected to the same pin. PT0/IOC0 pin number ____________ Toggle Switch 8 until you are sure there a Logic High level at Switch 8. You can verify this with a scope or DVM. 2. Set the TTL/SYNC output of the function generator to 1 kHz at 50% duty cycle and verify using the scope. Connect the signal to the PORT T (PT0) pin and ground on the Demo Board Primary I/O connector. 3. Create a CodeWarrior project. The C and Assembler code are shown at the end of the lab. Copy/paste the code to the appropriate files. 4. You will need to add the termio.c file to the project in the Sources folder in order to use the printf function. In Codewarrior select project, AddFiles and then find and select the file. This file is found at C:\Program Files\Freescale\CodeWarrior for S12(X) V5.01\lib\hc12c\src. 5. “Make” the program in CodeWarrior. The Assembly code has an unusual bit of code with a loop that the program will never execute. What is the purpose of this code? BrkVal: 6. file. BRN BrkVal Determine the addresses of the labels edge1, edge2, and BrkVal from the Project.map edge1 address __________ edge2 address __________ BrkVal address _________ period address __________ 7. Open AsmIDE and download the .s19 file to your HCS12 workstation. Place a breakpoint at the address of the label Brkval. Run the program to this breakpoint. Type the T command twice (trace) until you have executed the instruction std period. 1 8. Examine the values in the memory locations edge1, edge2 and period. Record the values found at these locations. Subtract the edge2 and edge 1 values. Does the result agree with what you see in Register D and the memory location for period? edge1 value ___________ edge2 value_____________ edge2 – edge1 value __________ period value ____________ 9. The value for Period in memory should match what is in register D. Record the value in register D. Register D ____________ In the following paragraph you will do by hand what the C code is doing. The value in Register D or memory is the raw (unscaled) measure of period. Convert the value to decimal. Determine the scaled or actual period of the waveform by multiplying this value by 32 and divide by 24. The result is in µsec. Determine the frequency of the waveform in Hz by dividing the Timer Clock frequency of 750 kHz by the raw (unscaled) measure of period. What is the value of the period and frequency? Period ____________ Frequency ____________ 10. Remove the breakpoint. Run the program for input frequencies of 500 Hz, 1 khz and 2 kHz. Record the results. Case 1 2 3 Function Generator freq Measured freq Procedure: Part B - PulseWidth and Duty Cycle measurement 1. The code in Part A measured the period of a square wave. In this part of the lab you will write another assembly language function to measure the pulse width or high time (THIGH) between a rising and falling edge on the input waveform. This can be done in 1 of 2 ways. Do one or the other but not both. Method 1 Write a new function called readPW in the main.asm file. Copy/paste the code for the function readperiod in main.asm. Call the new function readPW Method 2 Create a new file using Notepad – give it a name such as pw.asm. Copy/paste the code from main.asm into this new file. Call the new function readPW Add this file to the sources folder in CodeWarrior. 11. For either method you will need to address the following issues: • Edit the new function called readPW 2 • • • Be sure that you put the correct XDEF statement, the function name and an rts at the appropriate places in the code Define memory locations for edge3, edge4 and pw (pulsewidth). Insert a new line of code (similar to movb #$xx,TCTL4) before the second instance of brclr TFLG1,C0F,* to configure the program to now capture a falling edge 12. In the C code declare new variables rawPW (unsigned int), scaledPW, and DC (unsigned long int). Use the existing C code to guide you. Make a call to each of the assembly methods (readPeriod and read PW). Scale the value of pulsewidth in the same manner as was done for period and then calculate the duty cycle of the signal by this relationship: duty cycle = (Pulse width*100) /Period Using printf display Period, Frequency, Pulse width, and Duty cycle with proper units. Use the existing C code to determine how to display these values. 13. Set the TTL/SYNC output of the signal generator to 2 kHz at 25% duty cycle. Verify that this is the correct waveform using the oscilloscope. Connect the signal generator to the HCS12 workstation to pin 13 and ground. 14. Repeat for 5 KHz at 75% duty cycle. Record the results. Demonstrate the Part B program to your instructor and have your lab sheet signed. Case Funct Gen freq 1 Funct Gen Duty Cycle Measured freq Measured Duty Cycle 2 C program ;********************************************** ;* Lab 8 - This lab measures the period of a TTL ;* waveform using the HCS12 Input Capture function ;* ;* A C program calls assembler code which returns a raw value ;* for period to the C program. The C code computes the scaled vales ;* of the period and frequency and prints them out. ;********************************************** #include <hidef.h> #include "derivative.h" #include <stdio.h> /* common defines and macros */ /* derivative-specific definitions */ int readPeriod(void); void main(void) { unsigned int RawPer,Freq; unsigned long int ScaledPer; RawPer = readPeriod(); RawPer = readPeriod(); ScaledPer = ((long)RawPer*32)/24; Freq = 750000/RawPer; /* /* /* /* 3 call assembler call assembler scale period – convert period function */ function */ pre-scale of 32*/ to freq */ printf("The period is %lu useconds \n\r", ScaledPer); printf("The frequency is %u Hz \n\r", Freq); /* \n=LF \r=CR */ asm("swi"); } Assembler Code XDEF readPeriod TIOS: TSCR1: TSCR2: TCTL4: TFLG1: TC0: IOS0: C0F: equ equ equ equ equ equ equ equ edge1: edge2: period: $40 $46 $4D $4B $4E $50 $01 $01 ds.b 2 ds.b 2 ds.b 2 ;memory to hold the first edge ;memory to hold the second edge ;memory to store the period readPeriod: movb #$90,TSCR1 bclr TIOS,IOS0 movb #$05,TSCR2 movb #$01,TCTL4 movb #C0F,TFLG1 brclr TFLG1,C0F,* ldd TC0 std edge1 brclr TFLG1,C0F,* ldd TC0 std edge2 subd edge1 BrkVal: BRN BrkVal std period rts ;enable timer counter and enable fast timer flags clear ;enable input-capture 0 ;disable TCNT overflow interrupt, set prescaler to 32 ;set to capture the rising edge of PT0 signal ;clear the C0F flag ;wait for the arrival of the first rising edge ;save the first edge and clear the C0F flag ;store first edge in memory ;wait for the arrival of the second edge ;save the second edge and clear the C0F flag ;store first edge in memory ;compute the period ; return to caller XDEF readPW edge3: edge4: pw : ds.b 2 ds.b 2 ds.b 2 ;memory to hold the first edge ;memory to hold the second edge ;memory to store the period readPeriod: movb #$90,TSCR1 bclr TIOS,IOS0 movb #$05,TSCR2 movb #$01,TCTL4 movb #C0F,TFLG1 brclr TFLG1,C0F,* ldd TC0 std edge3 movb #$02,TCTL4 brclr TFLG1,C0F,* ldd TC0 std edge4 subd edge3 std pw rts ;enable timer counter and enable fast timer flags clear ;enable input-capture 0 ;disable TCNT overflow interrupt, set prescaler to 32 ;set to capture the rising edge of PT0 signal ;clear the C0F flag ;wait for the arrival of the first rising edge ;save the first edge and clear the C0F flag ;store first edge in memory ;set to capture the falling edge of PT0 signal ;wait for the arrival of the second edge ;save the second edge and clear the C0F flag ;store first edge in memory ;compute the period ; return to caller 4