ETEC 421 - Digital Controls PIC Lab 10 Pulse Width Modulation Program Definition: Write a program to control the speed of a dc motor using pulse width modulation. Discussion: The speed of a dc motor is proportional to the applied voltage, the current, and the torque requirements of the load. Torque is directly proportional to speed. The trick with speed control is to achieve a reasonable torque as the motor speed is varied. This can be done by supplying full voltage pulses to the motor while varying the duty cycle. Pulse width modulation is accomplished by establishing a constant period for a square wave and allowing the pulse width during that period to vary in length as a percentage of the period. The diagram below shows pulse width modulation for three different percentages of the period. We will construct a program for the PIC and an h-bridge driver circuit to demonstrate pulse width modulation techniques using a small dc motor. Two different methods of generating the pulse will be used. Procedure: Figure 1 Pulse Width Modulation Assemble the H-Bridge motor driver circuit as shown in Fig. 2 on a protoboard.
Figure 2 H-Bridge Schematic Now we will write two programs for the PIC to generate the pulses and direction signal to drive the dc motor utilizing the above circuit. In both programs, you will use the RC2 output for the pulse signal to the h-bridge, and an output pin of your choice for the direction. Program 1: Using the PIC Timer Interrupts with CCP1 in Compare Mode We will generate a pulse train that can be changed by pushing one of 3 buttons on the LabX1 board. The program starts out with the pulse width set at 50%. Select a row of buttons on the LabX1 board to act as signals to change the pulse width. Use the left-most button to decrease the speed by one count, the next button to reset the speed to 50%, the next button to increase the speed by one count, and the right-most button to change directions. The process of generating the pulse train is as follows: CCP1 is set to compare mode so that it will generate a software interrupt (sets CCP1IF to 1) when the value stored in its data registers (CCPR1H and CCPR1L) match the count of a free-running timer Timer1. Timer 1 is allowed to count until it rolls-over (65536) at which time it generates an interrupt (sets TMR1IF to 1). An interrupt routine traps each interrupt as it happens. When TMR1IF is trapped, set RC2 to 1 and clear the flag. When CCP1IF is trapped, Set RC2 to 0 and clear the flag. The length of the period (1 / frequency) is determined by setting bits 5 and 4 in the T1CON register. The pulse width is varied by changing the values in CCPR1H and CCPR1L. Note that 50% duty cycle is accomplished by setting CCPR1H to 128 with CCPR1L = 0.
This program will use the interrupts generated by Timer1 and CCP1 to set or clear pin 17 of the PIC (RC2) to give the output pulse train. See Table 8-4 below. Here are some tips to get you going: 1. Be sure to enable all of the appropriate interrupts (GIE, the peripherals, the port B interrupt on change feature, port B0 interrupt, timer 1, and the capture and compare module CCP1). 2. Enable the pull-up resistors for port B, set RC2 as an output, and set the TRISA and TRISB registers to utilize the pushbuttons on the LabX1 board. This is the same as in a previous lab. 3. Set up the LCD to display the value stored in CCPR1H so that we can see how long the pulse is high. 4. Re-use some of the code from a previous lab to utilize the interrupt routine to detect when one of the buttons is pushed and take the appropriate action based upon which one is pushed. 5. In the main program, establish a while() loop that runs forever and displays the value of CCPR1H. 6. The interrupt routine does three things: a) Test for TMR1IF, b) Tests for CCP1IF, and c) Tests for RBIF. 7. Refer to the diagram below to get an idea of how the waveform looks and when the interrupts are generated:
Program 2: Using the PIC PWM Feature The PIC has a built-in Pulse Width Modulation feature that uses Timer2 with CCP1 set in PWM mode which makes it very easy and efficient to generate the pulse train. You will set up the new program as above (re-use most of its code) to generate a variable width pulse on the same pin (RC2). However, you will need to use the registers and timer as shown in the table below. The process of generating a PWM signal is outlined in the PIC Data Sheet (Section 8.3) but listed below are some salient points from the set-up procedure Section 8.8.3: 1. Set the PWM period by writing to the PR2 register (a good initial value is 255 its max value) 2. Set the PWM duty cycle by writing to the CCPR1L register (a good initial value is 128 which will set it to a 50% duty cycle) Also you may want to set CCP1CON bits 5 and 4 to 1 s since these are the two least significant bits of the duty cycle. (Note that the duty cycle is a 10 bit number) 3. Make CCP1 and output by clearing the TRISC register bit 2. 4. Set the TMR2 prescale value and enable Timer2 by writing to T2CON. 5. Configure the CCP1 module for PWM operation. 6. Be sure to enable Timer2, set its prescale value to 1:1, and make it listen to the internal oscillator. 7. This time, the interrupt routine is used only to trap the button pushes since we do not need to be involved with the timer or compare module interrupts. 8. Display the value of CCPR1L on the LCD.