![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
PWM and 16F1509 |
Posted: Mon Feb 17, 2014 2:24 pm |
|
|
There is no output from the PWM pin5 of the 16F1509
The relevant code is
Code: | setup_oscillator(OSC_31KHZ); // Set PIC to internal oscillator
set_tris_c (0xD5);
setup_PWM1 (PWM_ENABLED);
setup_timer_2 (T2_DIV_BY_1,254, 1); // 50 Hz
// setup_ccp1 (CCP_PWM);
set_pwm1_duty (i); // i = 25 to 56 |
The only setup I see in the .h is as above. The setup_ccp1 (CCP_PWM); that is commented out gives a compile error. It is what I usually use but is not in the .h.
The PWM output stays low. Any help appreciated.
I'm not sure if I use 31kHz or 4X that to calculate PR2 |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Feb 17, 2014 2:29 pm |
|
|
Read forum guidelines.
Provide SHORT complete compilable code we can test, rather than guess.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Feb 17, 2014 2:51 pm |
|
|
Sorry, I thought all relevant code was there.
Code: | /* Pre-processor directives */
#include <16F1509.H>
#fuses NOWDT, PUT, NOPROTECT, NOBROWNOUT
#device ADC = 8
#use delay (clock=31 KHZ) // PIC runs at 31 KHZ
/* The main function */
void main()
{
// setup the oscillator
setup_oscillator(OSC_31KHZ); // Set PIC to internal oscillator
// declare variables
long i = 0;
// initialize port directions
set_tris_a (0xFB); // set Port A2 output, the rest inputs
set_tris_c (0xD5); // set Port C all inputs except PWMs to OPs
// setup for PWM
setup_PWM1 (PWM_ENABLED);
setup_timer_2 (T2_DIV_BY_4, 155, 1); // 50 Hz
// setup ADC
setup_adc (ADC_CLOCK_DIV_32); // configures ADC, 2-6 us reqd in .h
setup_adc_ports (sAN3); // to read pot
// main loop
while (1) // loop endlessly
{
// run pulse width modulator
for (i=25; i<=56; i++) // increment posn for min to max
{
set_pwm1_duty (i); // from 0.8 to 1.8 msec
delay_ms (500);
}
for (i=56; i>=25; i--) // decrement posn for max to min
{
set_pwm1_duty (i);
delay_ms (500);
}
} // end of endless while loo
} // end of main function
// end |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Mon Feb 17, 2014 3:18 pm |
|
|
First, you are not selecting an oscillator. You need either to tell the compiler to use the internal oscillator with the fuses, or using the clock statement (INTERNAL, rather than CLOCK). Without an oscillator, the chip won't run. This is why we always tell people to start with a simple 'flash an LED' program, and verify that the chip is running, and at the expected speed, _before_ anything else...
Then your PWM speed is wrong. The timer is fed of Fosc/4. You then divide this by 4 again, then by 156 -> output at 31000/(4*4*156) = 12.4Hz. Not 50Hz.
Then you are clocking the ADC at 31000/(4*32) = 242Hz. 4.12mSec/cycle. Given the recommended speed is 2-6uSec, the result is going to be terrible... |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Feb 17, 2014 4:22 pm |
|
|
I have asked this question before on how to set the clock on the 16F1509 but got no reply.
There is no INTOSC in the .h and everything I try gives a compile error.
#fuse INTRC_IO gives an error and I don't know what that is anyway.
I believe LP,XT,HS, and RC are for external oscillators.
The setup_oscillator(OSC_xxx) is all I could find and it did work in another program that I was adapting for this one (different PIC and clock hence the ADC error you mentioned). However that was with 8MHz specified, but it worked for two other projects.
If I set RA4 as O/P should I not see the clock there? I do suspect the oscillator, I just don't know what to use or how to check it.
Is the timer really fed by Fosc/4 if the clock is internal?
I believe my first code was correct for the setup_timer_2, but thats the least of my problems.
What does "or using the clock statement (INTERNAL, rather than CLOCK)" mean? Am I missing a resource? I checked the CCS manual, the .h file, the data sheet, and PIC C. |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Mon Feb 17, 2014 6:19 pm |
|
|
Another rock to look under - in the install directory for the compiler is a text file called fuses.txt that is (I think) a list of known fuses (not just for one processor). snoop through there and you may find what you are looking for. Hope that helps.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Feb 17, 2014 6:34 pm |
|
|
Looking at other examples I see:
Code: | #include <16F1509.H>
#fuses INTRC_IO, NOWDT, PUT, NOPROTECT, NOBROWNOUT
#device ADC = 8
#use delay (internal=31KHZ) // PIC runs at 31 KHZ |
They used another frequency, but the above does not work for me.
Perhaps it's time to update my CCS C, I hate to do that and add another variable to the problem. My version is 4.134. |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Mon Feb 17, 2014 7:12 pm |
|
|
This is a verified working program in V5.019
//
Code: | #include <16F1509.H>
#fuses NOMCLR, NOWDT, PUT, NOPROTECT, NOBROWNOUT
#device ADC = 8
#use delay (clock=31khz) // PIC runs at 31 KHZ
/* The main function */
void main()
{
setup_oscillator(OSC_31khz);
setup_pwm1(PWM_ENABLED | PWM_OUTPUT | PWM_ACTIVE_HIGH);
setup_timer_2(T2_DIV_BY_1, 249, 1);
set_pwm1_duty(500L);
// main loop
while (1) // loop endlessly
{
output_toggle(pin_c3);
delay_ms(500);
} // end of endless while loop
} // end of main function
|
_________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Feb 17, 2014 8:11 pm |
|
|
Thank you all for your help.
dyeatman, I copied your program and compiled and burnt it and there is nothing on C5 or C3 ('scope). It appears that the oscillator is not working.
I used the same chip and burnt a different program (8 MHz) and the PIC works. It seems my version of CCS C has a glitch for this frequency. I updated to ver 4.140 which was the last I saved before my CCS expired but it does not work either.
I will renew my subscription and try again tomorrow. |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Mon Feb 17, 2014 8:18 pm |
|
|
I tested the program at 31khz AND 8mhz so if it is an osc freq problem just
change the two lines and try that.
The fact that the C3 led output does not work is definitely the issue that must be resolved first. _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Tue Feb 18, 2014 1:48 am |
|
|
Compiler version difference.
As I've already said, use 'internal', rather than clock.
Compiling dyeatman's code on 4.135 (nearest I have to 4.134), it defaults to ECH for the oscillator. Compiling the code with the setup changed to:
Code: |
#fuses NOMCLR, NOWDT, PUT, NOPROTECT, NOBROWNOUT
#device ADC = 8
#use delay (internal=31khz) // PIC runs at 31 KHZ
|
It correctly sets up the oscillator.
As a comment, you have got a pullup on pin 4. It won't run without this, unless you specify NOMCLR. I'd also have NOLVP. |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue Feb 18, 2014 8:19 am |
|
|
Thanks Ttelmah, that worked. So to summarize:
I cannot set the clock in Fuses
I must use #use delay (internal=31khz)
setup_oscillator(OSC_31khz); seems to be useless
No one has explained what #fuses INTRC_IO does
I don't know how to get the oscillator to output to pin 3. I have set it to O/P in Tris (this chip has several functions for each pin)
If the internal clock is 31 kHz then what is the Timer clock? 31kHz or 31/4 kHz.
What does "or using the clock statement (INTERNAL, rather than CLOCK)" mean? Am I missing a resource? I checked the CCS manual, the .h file, the data sheet, and PIC C.
What happened to setup_ccp1(CCP_PWM)? It doesn't make code very transportable if commands keep vanishing.
I guess the vertical lines in setup_PWM1 (PWM_ENABLED|PWM_OUTPUT|PWM_ACTIVE_HIGH); are separators, not bitwise inclusive OR
Am I missing a resource? Where do I look this stuff up? |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9178 Location: Greensville,Ontario
|
|
Posted: Tue Feb 18, 2014 8:44 am |
|
|
Some comments...
1) Pressing F11 while your project is open, will open the CCS Help manual.To learn about 99% of CCS C, simply scroll and click.
ie: use delay(...) has a LOT of easy to understand info about configuring the PIC speed,several examples as well.
2) INTRC_IO is the 'fuse' that says.... use the INTernal RC oscillator AND allow IO on the shared clock/i/o pins(RA4,RA5).Using this fuse allows you an extra I/O pin. Read the datasheet for more info.
3)The '31 KHz' oscillator is NOT a precise clock! Priamarily used for WDT,PWRT,etc.
4) This PIC has a nice HFOSC in it,common to a lot of newer PICs. Good from 31.25KHz to 16MHz and is a PRECISE clock.So I have to ask WHY are you using the inferior clock?
5) 'clock' can be internal(you have a choice, good and bad) or external( a quartz xtal or canned oscillator).Which you use, is up to you.It really depends on the project.SOmething that needs high accuracy, perfect timing, etc. I'd spend the extra 50c and put an external crystal and 2 caps.Any other projects should be fine with the internal HFOSC.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Tue Feb 18, 2014 8:49 am |
|
|
Several comments:
1) Data sheet. This would answer your question about the timer input (it is Fosc/4)
2) Key thing is chip differences. The chip doesn't have a CCP module, it has a separate dedicated PWM module. Hence different instructions to set this up. setup_ccpx, is still the instruction to use, on a chip with a CCP.....'.
This is why it is different, because the _chip_ is.
3) Internal=value says to use the internal oscillator, and set it (if possible) to the selected frequency. In your particular case, there are two internal oscillators. The 'primary', that gives 32KHz to 16MHz, and a separate oscillator at 31KHz. The setups are slightly different, and on your compiler, INTRC with clock=31KHz, does not correctly configure this. Internal=31Khz, does.
4) The vertical bar is bitwise OR. If you look in the header file, you will find a lot of lines telling you to OR together the parameters for each function.
5) Read in order:
Data sheet
Header file for chip
CCS downloadable manual for the compiler version (this is more up to date than the version with the compiler) - unfortunately the version now available will be for a much later compiler. |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue Feb 18, 2014 4:57 pm |
|
|
Thank you Ttelmar & Temtronic,
I connected a frequency counter to the PWM output but cannot see a difference between #use_delay(internal=31000) and #use_delay(internal=31250) which is the lowest frequency for HFINTOSC.
It is possible that LFINTOSC is very close to HFINTOSC and that I really am switching between the two oscillators but I'm not convinced. I need to see the osc O/P to make a more accurae measurement.
PR2 is calculated to be 156.25 (I used 156) which gives 52 Hz for the PWM frequency. PR2=161 gives 50 Hz so I guess it's not an exact science.
Using setup_oscillator (OSC_31250); as well as #use_delay(internal=31250) changes the frequency slightly (down 2 Hz). I don't understand that one. setup_oscillator (OSC_31000); does not work even if #use_delay is the same frequency. I don't trust it but will try again when my latest CCS version is loaded.
Incidently #use_delay accepts 31000, 31250, 32000, 33000, but not 34000. I was just curious.
I switched between OSCON=0x02 and 0x12 to make sure that I'm using LFINTOSC or HFINTOSC using #byte OSCON = 0x02 after the #use_delay. The frequency did not change but the resolution is only 1% with a 10 second timebase on the counter.
OSC1/CLKOUT pin function is determined by the /CLKOUTEN bit 11 in config word 1. I need to clear it to see the oscillator on this pin (pin 3 RA4/AN3). Does CCS C have an easy way to get at these registers or do I have to resort to Assembly? I could use #byte but it's getting a bit tricky. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|