CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PWM from the data sheet
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PWM from the data sheet
PostPosted: Tue Feb 23, 2016 1:25 pm     Reply with quote

I cannot get the proper duty cycle out. The period, as calculated by (PR+1)/Clock = 16384/32,000,000 = 512uS is correct on the scope. (I am trying to get 14 bits resolution at 2KHz.)

However, if I try any DC greater than 255, no output. At 255 it's about 8%.

Compiler v5.055


Code:

#include <16f1765.h>
#define RAND_MAX 63
#include <stdlib.h>
#fuses INTRC_IO,NOWDT,PUT,MCLR,PROTECT,NOBROWNOUT, PLLEN,NODEBUG,NOLVP,
#use delay(clock = 32000000)

#byte PWM5PRH       = 0xD96
#byte PWM5PRL       = 0xD95
#byte PWM5DCH       = 0xD94
#byte PWM5DCL       = 0xD93
#byte PWM5CON       = 0xD9B
#byte PWM5CLKCON    = 0xD9E
#byte RC2PPS        = 0xEA2
#byte PWM5PHL       = 0xD91
#byte PWM5PHH       = 0xD92

void main(void)
{
   int X;
   port_a_pullups(TRUE);
   port_c_pullups(TRUE);
   set_tris_c(0);
PWM5PRH       = 0x3F;
PWM5PRL       = 0xFF;

PWM5DCH       = 0x1F;  // 1FFF ----> 50% DC
PWM5DCL       = 0xFF;   // (doesn't work - low output)

PWM5CON       = 0x80;
PWM5CLKCON     = 0x0;    // Fosc source

RC2PPS          = 0x10;   //PWM5 out on C2
PWM5PHL        = 0x0;
PWM5PHH        = 0x0;
  while(1)
  {   
   output_toggle(PIN_C3);  //chip is alive. Instruction clock = 8 MHz
                                      //verified on scope
   delay_cycles(250);    delay_cycles(250);
   delay_cycles(250);    delay_cycles(250);     
  }
 
   
   
}
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 23, 2016 3:22 pm     Reply with quote

Have to ask why not use the CCS functions for this ??

Jay
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Tue Feb 23, 2016 3:29 pm     Reply with quote

temtronic wrote:
Have to ask why not use the CCS functions for this ??

Jay


I have to say I couldn't get them to work. I intended my post to ask how to go from the working code from the registers to the CCS functions, but apparently I didn't get that far!

I did not see how to read the data sheet, read the include file, read the CCS manual and make the logical connections. For example, the include file only has a couple of parameter defines for the #use PWM directive. There was no answer there on how to set it up.
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 23, 2016 4:06 pm     Reply with quote

When you have your program open, pressing F11 should open and display the CCS manual. Usually there's enough info to figure it out. There are a few examples in the 'example's folders, though I can't specifically say which one.

Jay
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Tue Feb 23, 2016 4:23 pm     Reply with quote

I did give the manual a try. I think part of the problem is that there are 2 PWM modules on this chip: a 10 bit and a 16 bit. I'm trying to get the 16 bit to work. I believe it is a fairly new chip, so I didn't run across any good examples.

If I could find out what is wrong with my register approach, it might be easier to use the functions.

Thanks.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Feb 23, 2016 5:14 pm     Reply with quote

i am quite anxious about fuse "PLLEN,"
combined withh your use_delay at 32mhz -
does your .LST file show the right setup ?......


as to the 10 vs 16 bit PWM
10 bit pwm should be possible at up to 40khz or so
also be sure to CAST your values passed to the CCS set_pwm() function
as int16 or LONG else an 8 bit quantity may be all you CAN set in 10 bit space.

you need to READ and think about the 16F1765.h header file under
heading SETUP_PWM ()

i think it will get you farther along than the quasi assembler you attempt.

also consider that the part in question is very NEW and CCS support could be less than robust.
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 1:57 am     Reply with quote

Some general comments:

First, much easier and safer to write to 16bit registers, by using #word, and writing 16bit values, than trying to write to the bytes separately. Then use the getenv function to get the register addresses. They look right, but far too easy for one to be wrong. So:

#word PWM5PR=getenv("SFR:PWM5PRL")

gives you a 16bit register PWM5PR that can be written to with 16bit values.

The PPS register is much easier controlled just using #pin_select. Look at the top of the processor include file (33 lines down), and you will find a little table giving the pins that can be used, and the peripherals that can be fed to them.

#PIN_SELECT PWM5=PIN_C2

or whatever pin you want.

Then the key is that the higher PWM's do not use the standard PWM functions. They are not CCP based, and have different capabilities and values (including things like phase control), so have their own suite of functions to control them:

setup_pwm5(PWM_STANDARD | PWM_CLK_FOSC | PWM_CLK_DIV_BY_1);

To give a basic PWM without special abilities (except for the larger counter used).

set_pwm5_period() then sets the period register, and
set_pwm5_duty() the duty register.

As has been said before, you have to treat the processor include file, as 'part of the documentation'. It gives the pin select details, and also the syntax and values available for the pwm controls.

One other comment added. port_x_pullups(TRUE) is wrong.

There are two versions of this function, depending on the chip. Chips that only allow the pullups to be on/off, use TRUE/FALSE to enable them. Chips that have individual pullups require a mask value for the pullups.

As a further comment, always debug, with protection _off_. Only enable it once you have working code. With it enabled, the programmer has to perform a full erase of the chip (which uses an extra life on the EEPROM), every time you change anything.
Also you want NOPPS1WAY.

You code to write to the PPS register won't be working at all. To change the PPS, you have to perform an unlock sequence first. The compiler knows to do this.
Code:

#include <stdlib.h>
#fuses INTRC_IO,NOWDT, PUT, MCLR, NOPROTECT,NOBROWNOUT, NODEBUG, NOLVP
#fuses NOPPS1WAY
#use delay(INTERNAL = 32000000)
#PIN_SELECT PWM5=PIN_C2 //select the PWM 5 pin

void main(void)
{
   port_a_pullups(0xFF); //8 bit mask required
   port_c_pullups(0xFF);
   set_tris_c(0);
   setup_pwm5(PWM_STANDARD | PWM_CLK_FOSC | PWM_CLK_DIV_BY_1);
   set_pwm5_period(0x3FFF);
   set_pwm5_duty(0x1FFF);
   while(TRUE)
   {   
      output_toggle(PIN_C3);  //chip is alive. Instruction clock = 8 MHz     
      delay_us(125);   
   }
}
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 9:59 am     Reply with quote

Thank you, Ttelmah (and asmboy.)

As mentioned, my thinking was to work with the registers directly at first (to learn about the PWM module) and then use the CCS functions.

Actually there was something flaky about writing the duty cycle registers directly, as you pointed out in general for writing 16 bit values. When I used the duty cycle function, set_pwm5_duty(7000); everything worked.

However, I tried
#word PWM5DC = getenv("SFR:PWM5DCL")

then PWM5DC = 7000;

but that did not work.


Ttelmah, thank you for all your valuable comments, which I will go over.

One question:

Why doesn't the PLLEN fuse need to be set or is it better to use #delay like you did?
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 10:25 am     Reply with quote

Quite a few of the similar chips, don't allow the PLL fuse to enable the PLL, when in INTOSC mode. It has to be enabled in software after the code starts. This one does accept the fuse, so it doesn't matter. However using the INTOSC=xx form, the compiler knows which method has to be used, and automatically handles this if necessary... Smile
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 11:36 am     Reply with quote

Something is still flaky.

First time I compiled your code (after putting in the #include <16f1765.h> line), it worked perfectly.

However, now it doesn't. I still get the square wave out of C3, but the PWM output is solid low. Tried changing chips and also the PWM output pin.

Once in a while reprogramming it works, but not often. I'm new to MPLABX, so maybe I'm overlooking something. Any ideas?

Code:
//Source "B"
#include <16f1765.h>
#include <stdlib.h>
#fuses INTRC_IO,NOWDT, PUT, MCLR, NOPROTECT,NOBROWNOUT, NODEBUG, NOLVP
#fuses NOPPS1WAY
#use delay(INTERNAL = 32000000)
#PIN_SELECT PWM5=PIN_C2 //select the PWM 5 pin

void main(void)
{
   port_a_pullups(0xFF); //8 bit mask required
   port_c_pullups(0xFF);
   set_tris_c(0);
   setup_pwm5(PWM_STANDARD | PWM_CLK_FOSC | PWM_CLK_DIV_BY_1);
   set_pwm5_period(0x3FFF);
   set_pwm5_duty(0x1FFF);
   while(TRUE)
   {   
      output_toggle(PIN_C3);  //chip is alive. Instruction clock = 8 MHz     
      delay_us(125); 
   }
}


Last edited by johnl on Wed Feb 24, 2016 2:24 pm; edited 1 time in total
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 1:15 pm     Reply with quote

I just restarted MPLABX, programmed a chip and the PWM worked as expected. Reprogrammed the same chip and PWM stopped outputting, though the toggling on pin C3 always works.

Switched to the following code which worked 5 times in a row on three different chips. Compiler bug?

Code:
//Source "A"
#include <16f1765.h>
#define RAND_MAX 63
#include <stdlib.h>
#fuses INTRC_IO,NOWDT,PUT,MCLR,NOPROTECT,NOBROWNOUT, PLLEN,NODEBUG,NOLVP,
#use delay(clock = 32000000)


#byte PWM5PRH       = 0xD96
#byte PWM5PRL       = 0xD95
#byte PWM5DCH       = 0xD94
#byte PWM5DCL       = 0xD93
#byte PWM5CON       = 0xD9B
#byte PWM5CLKCON    = 0xD9E
#byte RC2PPS        = 0xEA2
#byte PWM5PHL       = 0xD91
#byte PWM5PHH       = 0xD92

#word PWM5DC = getenv("SFR:PWM5DCL")

////#use pwm(pwm5, output=PIN_C2, period=32000000,pwm_on)
///
void main(void)
{
   int X;
   port_a_pullups(0b11111);
   port_c_pullups(0b11111);
   set_tris_c(0);
   setup_adc(ADC_OFF);
PWM5PRH       = 0x3F;
PWM5PRL       = 0xFF;

PWM5DCH       = 0; //0x1F;  // 1FFF ----> 50% DC
PWM5DCL       = 0xFF;

PWM5CON       = 0x80;
PWM5CLKCON    = 0x0;    // Fosc source

RC2PPS        = 0x10;   //PWM5 out on C2
PWM5PHL       = 0x0;
PWM5PHH       = 0x0;

set_pwm5_duty(7000);
//

  while(1)
  {   
   output_toggle(PIN_C3);  //chip is alive. Instruction clock = 8 MHz
   delay_cycles(250);   
   delay_cycles(250);    delay_cycles(250);    delay_cycles(250); 

  }
 
   
   
}


Last edited by johnl on Wed Feb 24, 2016 2:23 pm; edited 2 times in total
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 1:32 pm     Reply with quote

OK I don't use that PIC or MPLABX but
when you reprogram the PIC do you also recompile? If so, dump the listing.Recompiling the same code MUST give you the SAME listing. If it doesn't something is wrong.
Now if the listings are identical, maybe it's an MPLABX bug?
You should be able to read back the PIC hex code into MPLAB and compare with the original. They should be the same, if not MPLABX is altering it.
Maybe an environmental issue? How's the humidity, dry ?? static could be a problem. What programmer are you using ? That may have PSU issues ? 'erratic' or 'random' running problems are hard to debug. I see....
1) source code : if this never changes then compiled code shouldn't
2) compiled code : see 1
3) PIC : if PICs are all same batch, all should be the same
4) compiler :dump listing to see if code is correct
5) IDE MPLABX : might be setup wrong for that PIC
6) programmer : same as 5
7) operating setup : static, power, ???
maybe a few other 'things' to consider

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 1:35 pm     Reply with quote

You can't have a period of 32MHz from the PWM.
Use a possible value.

Then your PPS code still won't actually be working. The PPS register has to be unlocked before you can write to it.

Remember MPLAB defaults to debug mode and this will override some settings.

More likely an MPLAB problem....
johnl



Joined: 30 Sep 2003
Posts: 120

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 2:57 pm     Reply with quote

I just built and programmed 3 chips in a row using "Source A" above. All 3 chips ran as expected.

Then I did the same for 3 chips with 'Source B" above. Only 1 of the 3 worked.

I made sure MPLABX was not compiling for debug mode, however, I see both a .COF and .HEX files in the output folder, both with the same timestamp. I am not sure which file is getting programmed. MPLABX seems to have taken a lot of control away and has automated tasks more.

temtronic, what do you or others use for the programmer and environment? I am not fond of MPLABX at this point.

Ttelmah, The period is 3FFF which is 2^14-1. If I want 14 bit resolution, don't I need that? From the datasheet, the period is (PR+1)/CLK = 16384/32,000,000 = 512uS which is what I see on the scope. The duty cycle is the DC register/ (PR+1). So I need to be able to specify a 14 bit number in the numerator. I don't understand what you mean by 32MHz period.
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 3:36 pm     Reply with quote

You'd tried to use #use PWM. With a period of 32MHz...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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