|
|
View previous topic :: View next topic |
Author |
Message |
boris
Joined: 29 Nov 2007 Posts: 15 Location: Hungary
|
16F88 PWM |
Posted: Fri Mar 14, 2008 6:10 am |
|
|
Hi!
I've encountered a problem with PIC16F88, and the PWM module.
I use compiler v4.068
The comiled program works fine in Proteus, but when I flash it on the real chip, it won't create a PWM.
I've set the PIN_B3 output in the code wizard.
The sample program I'm using is:
Code: |
#include "main.h"
void main()
{
setup_adc_ports(sAN2|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,99,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(200);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_INTRC);
}
|
The main file is:
Code: |
#include <16F88.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES CCPB3
#use delay(clock = 8000000)
|
If I take out the setup_ccp1(CCP_PWM); line and add a simple program like so:
Code: |
...
//setup_ccp1(CCP_PWM);
...
while(1)
{
output_high(PIN_B3);
delay_us(10);
output_low(PIN_B3);
delay_us(10);
}
|
The PIC generates signal on PIN_B3.
I'm using a simple breadboard, the only thing I use beside the PicKit2 connector is the 4k7 resistor and a 100nF capacitor. The PIC is powered through the PicKit2.
If I check the ASM generated by the CCS the CCP1 module and the PWM module configuration seems fine.
Code: |
.................... setup_ccp1(CCP_PWM);
0039: BCF 06.3
003A: BCF 03.5
003B: BCF 06.3
003C: MOVLW 0C
003D: MOVWF 17
|
The compiler moves 0C to 0x17, wich is 00001100 in binary.
This seems fine according to the 16F88's datasheet, page 83, because Bit3 and Bit2 has to be 1 to enable the PWM module.
The compiler also loads the duty cycle to the CCPR1L register.
Code: |
.................... set_pwm1_duty(200);
0042: MOVLW C8
0043: MOVWF 15
|
But the timer2 setup is strange.
Code: |
.................... setup_timer_2(T2_DIV_BY_1,99,1);
0032: MOVLW 00
0033: MOVWF 78
0034: IORLW 04
0035: MOVWF 12
0036: MOVLW 63
0037: BSF 03.5
0038: MOVWF 12
|
It initializes the timer2 alright, but it doesn't assign a value to the PR2 register (0x11)
The PWM setup procedure is written in section 9.3.3 (p.87) and the first thing is: Set the PWM period by writing to the PR2 register.
I don't see the PR2 writing in the code above.
I've been using PIC's for 4 years, but I've changed to CCS about 4 mounths ago, before that I've benn using another C compiler.
Thanks for your help! |
|
|
Matro Guest
|
|
Posted: Fri Mar 14, 2008 7:43 am |
|
|
Your timer2 is configures as follow:
setup_timer_2(T2_DIV_BY_1,99,1);
So the "set_pwm1_duty" should be between 0 (= 0%) and 100 (= 100%).
All values greater than 100 (as the 200 you choose) will give a duty cycle of 100% i.e. a static high output.
Try a "set_pwm1_duty(50)" and it should generate a 50% PWM signal.
Regards,
Matro |
|
|
boris
Joined: 29 Nov 2007 Posts: 15 Location: Hungary
|
|
Posted: Fri Mar 14, 2008 8:03 am |
|
|
HI Matro!
You ROCK!
I've would never think of it!!!
The joke is that the 200 was given by the code wizard, so I thought it was correct....
If I write 50 the PWM works like a charm!
Thanks again! |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Fri Mar 14, 2008 11:33 am |
|
|
The actual value used for the period is 4x the value in the setup function. If you use an int16 for the duty cycle then 0 to 400 would be correct. To use a constant you would need to add an "L" as a suffix to the constant: set_pwm1_duty(200L);.
This gives you the full resolution of 400.
Try this and let us know if it works for you. |
|
|
boris
Joined: 29 Nov 2007 Posts: 15 Location: Hungary
|
|
Posted: Mon Mar 17, 2008 1:54 am |
|
|
Hi Charlie U!
Thank You! The 200L works fine, and if I use int16 for the PWM value, it accepts values between 0 and 400. But where does the 400 come from? It's in the thatasheet, or in the CCS examples, or can be calculated? |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 17, 2008 3:19 am |
|
|
Basically, the timer runs off the processor clock/4, but the actual PWM generator, runs directly off the processor clock. The PWM generator, takes an extra two bits, to access this faster part of its counter. If you look at the data sheets, you will find that there is a main register (holding an 8bit value), and these extra two bits in another register. Now, the compiler, when the pwm_duty command is accessed with a normal 8bit integer, takes the 'quick' route, and writes the 8bit value directly to the 8bit PWM register, allowing counts up to the value selected for the timer (hence 0 to 100 in the example given). However if it is given a 'long' value, it realises you want to access the extra two bits, and extracts these, writing them to the extra bits in the control register, so you can then use 0 to timer*4 as a count value.
Best Wishes |
|
|
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Mon Mar 17, 2008 5:49 am |
|
|
HI.
I am strugling to understand what part of the PWM is 4 times faster than in the setup.
If you generate a PWM signal of say 5KHZ at 50% duty cycle in the setup function of the timer, does the actual generated PWM signal equal 5KHZ or 20 KHZ. I what scenario is the actual PWM freq and duty cycle different than what is setup in the timer setup? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|