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 CCS Technical Support

sine PWM inverter code going crazy
Goto page Previous  1, 2, 3, 4, 5, 6
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Dec 21, 2012 6:58 am     Reply with quote

It's the difference between an 'original' 12F683, and the current ones. The data sheet from 2004, has this as a problem, the 2007 one doesn't.
I haven't seen any actual screenshots of, this problem. The earlier screen shots, were of the problem at the top of the cycle, rather that the short cycle a little later.
As you say, it is almost impossible to program round, if you use 100% duty.

Best Wishes
GOBER



Joined: 22 Jul 2010
Posts: 41

View user's profile Send private message

PostPosted: Sun Dec 23, 2012 3:23 am     Reply with quote

Hey guys and sorry for being late. I Was a little bit busy.

Here's what happens when i use T's code:

http://www.4shared.com/photo/i7OrhWns/new.html?

The fifth duty cycle gets smaller. AND, it is the fifth one Mike. I used Gpsmikey's point and checked out.

The complete Code is
Code:

#include <12F683.h>
#device adc=10

#FUSES NOWDT                 //No Watch Dog Timer
#FUSES INTRC_IO             //Internal RC Osc, no CLKOUT
#FUSES CPD                      //Data EEPROM Code Protected
#FUSES PROTECT              //Code protected from reads
#FUSES MCLR                     //Master Clear pin enabled
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT      //No brownout reset
#FUSES NOIESO                //Internal External Switch Over mode disabled
#FUSES NOFCMEN             //Fail-safe clock monitor disabled

#use delay(clock=8000000)


int16 i=0;
int16 fb;

const int16 duty_cycle[32]={0, 36, 71, 105, 138, 171, 201, 230, 257, 280, 302, 320, 335, 346, 355, 361, 365, 361, 355, 346, 335, 320, 302, 280, 257, 230, 201, 171, 138, 105, 71, 36};

#int_TIMER2
void  TIMER2_isr(void)
{
   
   static int1 toggle=0;
   int16 new_value;
   if(++i==32) {
       i=0;
       toggle^=1;
   }
   if (i==1)
   {
      output_low(PIN_A1);
      output_low(PIN_A5);
      if (toggle)
      {
        output_high(PIN_A5);
      }
      else
      {
      output_high(PIN_A1);
      }   
   }
   new_value=duty_cycle[i]; //all the slow work of the table lookup
   //has now been done
   while (get_timer2() >10) ;
   set_pwm1_duty(new_value);
}

void main()
{
   setup_adc_ports(sAN3|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_16);
   set_adc_channel(3);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,124,5);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(0);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ);

   output_high(PIN_A1);
   output_low(PIN_A5);
   
   while(1);
}

I'm just using a 32 point array and this is what's happening. I wonder what else will happen if the array gets bigger!!

Anyway, I looked back into Tahmid's blog. Tahmid did not have this problem as he used a resolution of 8 bits. And in my case, where the resolution is almost nine bits according to the formula, I am having troubles. So, i will check out at what duty cycle value the problem starts to appear, and then use this point as the maximum duty cycle allowed, not taking the resolution i got from the formula. OR, just use 8-bit resolution as T suggested. By this, i will have to rewind my transformer to maybe 7-0-7 to 250, just as Tahmid's one. Now this may not be the right solution but it is a solution. It's been long. This has taken a lot of time. I'm damn full of curiosity to know the real cause of my problem, but i really can't wait any more. I really appreciate what all of You have tried to do. At least you pointed me to how inversion is done and when to change the duty cycle values when feedback is implemented. Perhaps you will have time to figure out what was really causing the problem, and i hope so. For then, I thank You.

If any new troubles, well, i know where and who to ask

Regards guys
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Dec 23, 2012 3:46 am     Reply with quote

Hi GOBER,

I've got a horrible feeling that Ttelmah's hit the nail on the head.
Your problem only appears at high duty ratios (>~80%)
Do some tests over this range only, (forget everything else, attack the one issue).

If he's right then you could:-

1). Prepare say four sets of valid values to feed into the two registers CCP1CON, CCPR1L. (You need to be feeding four DIFFERENT values into each of the two registers.

2). Run your code as before, (i.e. ASAP after a timer2 overflow, whilst PWM O/P is still high) write the four valid values to the PWM registers in turn. If the Ttelmah's correct, the fault will still be there.
3). Run your code but disable the PWM, load the PWM registers, re-enable PWM. See what happens.

4). If fault goes away you have a solution:-
4a) Run both 2) & 3) in succession. That way you should be able to see everything at once.
4b) For >50% duty PWM's you wait for the PWM to go low before writing, for <50% you write ASAP after timer2 overflow.

5). If fault is still present, you need another solution.
5a) You're stuck with the problem
5b) You should be able to reduce the loading of the two PWM registers to ~10 machine cycles. That way you limit your PWM duty ratio to ~90%, if that's acceptable. In other words, prepare the values for the two PWM duty registers, wait for timer2 overflow, wait for PWM to be low, write to registers. It no longer matters that the PWM terminates early as it's already gone!
5c) Use a different chip, one without the PWM write problem.
5d) Check the date codes on your chips, make certain you've got the latest silicon.


Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Dec 23, 2012 3:49 am     Reply with quote

Whoa.
You don't have to rewind your transformer. The amplitude of the output will remain exactly the same.
All you need do is divide your PWM values by 4, and change the variable declarations to int8. This will then be automatically multiplied by 4 by the hardware!...
When you load an 8bit value, it is loaded, as the _high_ eight bits of the 10bit PWM value.

So only changes:
Code:

const int8 duty_cycle[32]={0, 9, 18, 26, 35, 43, 50, 58, 64, 70, 76, 80, 84, 87, 89, 90, 91, 90, 89, 87, 84, 80, 76, 70, 64, 58, 50, 43, 35, 26, 18, 9};

//and declare 'new_value' as int8


The key to understand is that if the set_pwmx_duty function, is given an int8, it automatically just stores it directly into the 8bit register that gives the high eight bits of the PWM. This means it takes just one cycle to load. Whereas with the ten bit value, the high eight bits are taken (two rotations needed), and put into this register, and then the two low bits are masked, and transferred into the two separate bits. Lots of time and work. Not to mention that reading the number in the first place takes twice as long.....

Best Wishes
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Dec 23, 2012 4:00 am     Reply with quote

GOBER

The question you still have to answer is:-

Is the silicon problem highlighted in the errata an issue in 8bit mode?

Mike
GOBER



Joined: 22 Jul 2010
Posts: 41

View user's profile Send private message

PostPosted: Sun Dec 23, 2012 12:52 pm     Reply with quote

hey guys

I did what mike suggested. The problem still exists at higher duty cycles. I also checked the chip. It's a 2009 one.
I will now move to eight bits and will feed you back if the problem persists.

regards
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Dec 24, 2012 4:19 pm     Reply with quote

GOBER

OK. I've found time to have go myself. (It is Xmas!)

I've:-

1) Used a PIC18F1320. I don't have any smaller devices.
2) Used the first 32 16bit entries of a 320 element array.
3) Included the extra delay to ensure setting PWM duty ahead of timer2 overflow.
4) Got exactly the expected pulse widths throughout.
5) Got no prematurely terminated pulses.
6) Used a spare pin to confirm the new PWM_duty is set within one PWM pulse.

My conclusion, the device I've used behaves just as you want.

Mike
GOBER



Joined: 22 Jul 2010
Posts: 41

View user's profile Send private message

PostPosted: Tue Dec 25, 2012 12:42 am     Reply with quote

Hey Mike

I've been trying now using 350 as the maximum value duty cycle. The array for now has 292 entreis. NO PREMATURE PULSES FOR NOW. I will continue adding entries and testing. The array will eventually have 640 entries. Will you post your program. Perhaps I was missing something

Regards
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Dec 25, 2012 2:53 am     Reply with quote

GOBER wrote:
Hey Mike

I've been trying now using 350 as the maximum value duty cycle. The array for now has 292 entreis. NO PREMATURE PULSES FOR NOW. I will continue adding entries and testing. The array will eventually have 640 entries. Will you post your program. Perhaps I was missing something

Regards
I was simply using yours with anything surplus removed.
As I see it you're missing nothing.
I'll tidy it up and post.

Merry christmas.

Mike
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Dec 26, 2012 3:55 am     Reply with quote

As promised, the code I used.

I've obviously played with your code.

I've forced a test pulse near the peak of the waveform, as that's where you were having problems
I've forced a test pulse around the set_duty() to check that it all happened within one timer2 period.
I've double checked with my DSO, (which I trust).
I'm making no other claims about the code, I've not done anything clever or special.

Mike

Code:

#include <18f1320.h>

#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
// #FUSES HS  // Use optional Xtal


#use delay(clock=8000000)

int16 i=0;

const int16 duty_cycle[320]={0, 49, 98, 145, 191, 236, 278, 317, //0
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //1 //Dummy data to fill array
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //2
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //3
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //4
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //5
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //6
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //7
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //8
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49,

                            0, 49, 98, 145, 191, 236, 278, 317, //9
                            354, 387, 416, 441, 462, 478, 490, 498,
                            500, 498, 490, 478, 462, 441, 416, 387,
                            354, 317, 278, 236, 191, 145, 98, 49};

#int_TIMER2
void TIMER2_isr(void)
{
++i;
if(i==32)
  {
   i=0;                     // Reset array index here
  }


if (i==16)                  // Force a sync pulse near peak
  {
  output_high(PIN_A0);
  output_low(PIN_A0);
  }

while (get_timer2() >10) {};
  output_high(PIN_A1);      // Pulse to see start of PWM write
  set_pwm1_duty(duty_cycle[i]);
  output_low(PIN_A1);       // Pulse to see end of PWM write
}

void main()
{
setup_oscillator(OSC_8MHZ);
setup_timer_2(T2_DIV_BY_1,124,5);
setup_ccp1(CCP_PWM);
set_pwm1_duty(0);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
SET_TRIS_B(0);               // Should not need, but my compiler does not handle TRIS_B correctly


while(1);
}
mytheen07



Joined: 09 Feb 2015
Posts: 4

View user's profile Send private message Send e-mail

Reply
PostPosted: Fri Jul 31, 2015 1:28 am     Reply with quote

Hi Gober,
Thanks for Your Code. Its works for me.

thanks lot & No words to explain. But i made some changes in Interrupt loop.
_________________
Mytheen Muhammed
thwcs



Joined: 09 Feb 2017
Posts: 1

View user's profile Send private message

PostPosted: Sun Feb 19, 2017 4:51 am     Reply with quote

GOBER wrote:
Hey guys and sorry for being late. I Was a little bit busy.

Here's what happens when i use T's code:

http://www.4shared.com/photo/i7OrhWns/new.html?

The fifth duty cycle gets smaller. AND, it is the fifth one Mike. I used Gpsmikey's point and checked out.
.
.
.

I do not know how to use the ADC in this project. Feedback signal? Can you help me connect diagrams ?
Thank you!
temtronic



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

View user's profile Send private message

PostPosted: Sun Feb 19, 2017 7:15 am     Reply with quote

OK, I've been lurking here, pondering 'this and that' and have to ask...

What happens if you run the program without the driver/transformer part of the circuit connected? Just the PIC and say a couple load resistors?

Then there's the other question ,what happens if the table is filled with different data (IE NOT a 'sine wave' set of values?)

Just trying to think 'outside the box' here.

Jay
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 Previous  1, 2, 3, 4, 5, 6
Page 6 of 6

 
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