Blog Archive

Thursday, March 13, 2008

Having fun with PWM

In the passion to learn how to handle and use USB, so that my PIC tiny computer can communicate in a more modern way with laptops, PCs, etc, I decided to make one dedicated board for the PIC18F4550 just for that purpose. I had some problems with the board at the start, but at the end all went well. After all, this is just a strip board. Then, I started thinking, that it would be pretty boring to make a whole board, just for a PIC and a PC can "chat" together. So I decided to add it some peripherals, and I chose LEDs at the start. But I wanted to control their light intensity, and I thought that PWM is the best way to do it. Since I didn't want to create individual software PWM for each of the pins, I decided to use the built in CCP2 module of the PIC, to control a 4x4 LED matrix. Here's the schematic below. I don't have any specific code for this, since I was only experimenting, but I can tell you the configurations. I used a CPU clock of 48 Mhz (12Mhz crystal resonator input, divided by 3 and multiplied by PLL to get 96 Mhz , then divided by 2 so we can have 48 mhz for USB and the MCU). The PWM ran at ~11,7 kHz with maximum resolution of 10bits(PR2 is set to 0xff) and timer 2 has a 1/4 prescaler(T2CON is set to 0x5). The matrix is controlled by PORTD bits RD<0:3>(the rows) and the coloumns are controlled by the decoder, which is controlled by pins RC2,RC6 and RC7. RC2 is the multiplexed CCP1 output, i.e. the PWM signal is used to turn the decoder on/off, thus controlling the intensity of the entire LED matrix, while RC<6:7> are the decoded signals of the microcontroller. It's a pretty neat idea in my opinion and saves me time to develop software PWM which is both hard to make and inaccurate. So I messed up with this for a while, until I got bored and decided to make something different. Then I thought of motor control. The 18F4550 has built in another CCP module with enhanced PWM(CCP1). That is, it can control a full H-bridge, or a brushed DC motor in both directions in that matter... However I got tired of controlling just one motor, and since there is only one H-bridge controller in this pic, I decided to apply, another really neat trick of mine. Since I got one more decoder of the 74HC139 circuit, I added another bridge and controlled it with it. Here's the schematic. As you can see, the decoder controls the P-MOS transistors, so if we look at a truth table, while RD4 is low, motor 2 won't spin regardless of the signals applied to the gates of Q6 and Q8(the PWMs), since Q2 and Q4 are "closed", and vice versa, if RD4 is high. A closer look, shows that RD4 is not part of the built in enhanced CCP1 module, it's an option I added to select the motors. RD6 or P1C of the PWM circuit, is low when the module is in forward mode(bit 7 of CCP1CON is 0), or only Q1 or Q2(with respect to the state of RD4) are "open" thus allow current to flow through the motor and spin it(while RD7 or P1D is the "forward" PWM signal). Same thing happens, when the MSB of CCP1CON is 1(reverse mode), but then Q1 or Q2 are closed and Q3 or Q4 are open and RD5 or P1B is the active PWM signal. So, what we get is, that with RD4 select the motor, and with CCP1CON[7] we control the direction and with PWM we control the speed. This interface however lacks 2 things. First it's very hard to control both motors at once at different speeds (or even at the same speeds), the second thing is, that originally full bridge PWM uses 4 pins(RC1/P1A,RD<5:7>) and my design excludes RC1. And while the module functions, this pin is useless. If you want to learn more about the enhanced PWM, and bidirection motor control, read here.