----- Original Message ----- From: Tony Jurisic To: Sent: Tuesday, February 06, 2001 1:33 AM Subject: Re: [PIC]: Pulse Width Modulation on PIC16C84 > Thanks to everybody that helped me out on this problem. > I've decided to try this project on a new chip. The 16F87X series looks like > a good candidate. Looking at the microchip website it claims it has an > operating speed of 20Mhz. The website also claims that the 16X84 chips have > a speed of 10MHz however Bob said it can be used to 20MHz withour > overclocking. Am I right in assuming that microchip publishes half the value > of the chip in the datasheets implying I can use the 16F87X chips at up to > 40MHz ? NO, NO, NO, NO, NO! - stay away from overclocking! I am not sure about the 16C84, but the 16F84 _is_ specced to 20MHz, I just double checked the data sheet. If the 20MHz clock / 1024 samples per cycle = 19,531.25 Hz frequency will work for you, this will be almost simple on the F87X. If 19,531.25 Hz doesn't do it for you then I recommend using 9 bit at 39,062.5 Hz. If you really want the originally specified 24,000 Hz rate, you can calculate the needed crystal for 9 bit as follows: 24,000Hz * 512 samples/cyle = 12.288MHz clock rate. Actually, using the scaling technique described below, you should be able to generate a 9-and-a-fraction bit PWM at about 24,000 Hz. You do this by first computing the number of instruction times available for each cycle at 24,000Hz PWM frequency and 20MHz crystal: 20,000,000 / 4 / 24,000 = 208.333 Setting the PWM period to 208 instruction times gives us a PWM frequency error of: (208.333-208)/208.333 = 0.16% Not too shabby. This will give you an actual PWM frequency of about: 20,000,000 / 4 / 208 = 24,038.5 Hz Since we have 208 instruction times per sample, this gives us 208*4 == 832 possible PWM values. This is obviously more than 9 bit (512 values) and less than 10 bit (1024 values). In fact we can compute the number of bits as: LogBase2(832) == 9.7 bits. Now we are pretty close to our original spec which was 24,000 Hz (we get 24,038.5) at 10 bits (we get 9.7 bits). Now, how does one go about implementing this? It is rather easy: Sample the incoming 1KHz PWM using the CCP module. You'll have to deal with the special cases near 0% and and 100% PWM. For each cycle of the incoming PWM you will obtain 2 numbers, both expressed in 'clocks' or 1/20000000 second units. The first number will be the period (should be close to 1/1000 second = 2000 clocks), the other will be the duty cycle (will range from 0 to the current value for duty cycle). You now have to scale the duty cycle to the range 0..831. This can be done as follows: duty_cycle(output) = duty_cycle(input)*832 / period(input) This is, of course, a simple ratiometric computation. You will need 24-bit math to do this. (In fact, without looking it up, this could be the killer in his idea: you may not have time to do the math on each cycle!) Note that the multiply can be optimized to inline code because it is multiplication by a constant. Good luck, Bob Ammerman RAm Systems (contract development of high performance, high function, low-level software) -- http://www.piclist.com hint: PICList Posts must start with ONE topic: [PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads