Help understanding setting PWM on 16F PIC

Thread Starter

wannaBinventor

Joined Apr 8, 2010
180
I'm working with a PIC16F818, though I've come to understand that setting up PWM in the registers is fairly universal.

First and foremost, I'm having a bit of trouble following what the variables mean in the PWM period formula:
PWM Period = [PR2 + 1] x 4 x TOSC x (TMR2 Prescale Value)

Questions on variables:
PR2: Is this just the decimal value of the binary bits in the PR2 register? (IE: b'00000111' = decimal 7 so the value of the term "PR2 + 1" = 8?

TOSC: Is this the value of the oscillator? IE: Internal Osc set to 4mhz means a TOSC value of 4 million? This seems much to high for the formula.

TMR2 Prescale Value: Okay, so the TMR2 prescale value is set by bits 1 and 0 in the TM2CON register. So if TM2CON bits one and zero are "01" this sets a prescale of 1:1. Does this mean I multiply by 1? If I set the prescaler to 1:16, does that mean this variable is "16" or "1/16"?

In the duty cycle formula, when the term "(CCPR1L:CCP1CON<5:4>)" is used, does this mean the term is the decimal value of the 10 bits from CCPR1L (8 MSB) and from CCP1CON bits 5 and 4 (2 LSB)?

My assumptions have to be wrong somewhere, because 1/Period (for frequency) would be extremely low for almost any setting.

Also, please see my attachment. I'm becoming familiar with the PICMultiCalc (thanks to SgtWooki for making me aware of it). At the bottom sections of the "PWM Calc" window labeled "Results." Is the "Duty Register" just the decimal value of CCPR1L and CCP1CON bits 5 and 4?

Thanks for the help!
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
Tosc is 1/oscillator frequency so for your 4MHz crystal it is1/4000000 = 0.00000025 seconds.
You would use 16, not 1/16 for the prescaler in the formula.
I think everything else is correct.
 

Thread Starter

wannaBinventor

Joined Apr 8, 2010
180
Thanks guys. Very helpful.

How should I be turning on and off the PWM?

Long story short, I'm using PWM to generate a 38KHz signal that I want to modulate within my code to send serial data to an IR receiver circuit, so I need to be able to turn this on and off constantly.

I thought I could use "BSF PORTB,2" to turn on the PWM on that pin and "BCF PORTB,2" to turn off the PWM, but this doesn't seem to work at all. MPLAB SIM shows the pin still toggling on and off.

I've noticed that completely clearing the CCPR1L register and CCP1CON bits 5 and 4 turns it off - which turns off PWM. Is this the standard way?

Also, I'm curious how this will work on the other side. If I want 40 cycles of 38KHz to represent a logic 1, when the receiver side is testing for this, how is that going to go? It doesn't seem like it's going to work properly if I set a Timer to counting and then test it for logic 1 or 0 by subtraction because as soon as it sees the 1st cycle of the 38KHz any "BTFSC........" command is going to be activated." I have a sample program that uses a 418Mhz radio receiver and it pretends like the carrier wave doesn't affect the receiver's PIC input pin going high and low.
 
Last edited:

Markd77

Joined Sep 7, 2009
2,806
Probably the best way is to clear CCP1CON.
What IR reciever are you using? If you are using something like the TSOP... then you won't be able to tell exactly how many cycles there are, just roughly how long the modulated signal is on. If you are using a plain photodiode you will need a bit more code and probably some circuitry to ignore ambient light.
 

Thread Starter

wannaBinventor

Joined Apr 8, 2010
180
I did get a simple "on/off" IR transmitter to work with PWM. Thanks for the help on that!

I am using a TSOP on the receiving end with a IR LED on the transmitting side.

In my head I think the receiving end should go like this:

The minimum "on" (with active low) on the TSOP that I'm using is 10 cycles, with a max of 70 continuous cycles.

So I'm thinking I need to send say, 50 cycles for a logic 1 and maybe 30 cycles for a logic 0.

On the receiving end, I'm thinking I'll prescale a timer so I can get decent resolution in the u.sec range and then figure out something like...
50 cycles transmitted (intended as logic 1) - 10 cycles minimum to come on = About 40 cycles received.

Then, if 40 cycles of 38Khz is 1.2 ms (pulling out of my head here) and if with certain prescaling the timer goes to decimal 100 in 1.2 ms then I need to set it up to test for something like "greater than decimal 85 = logic 1, else = logic 0"
 

Markd77

Joined Sep 7, 2009
2,806
Something like that should work. I wouldn't subtract the 10 cycles, there is a figure (4) in the Vishay datasheet where the on time is usually longer than the off time for a symmetrical pulse. Some experimentation may be needed.
 
Top