Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Soft Start PWM With PIC16F886

Status
Not open for further replies.

mcmsat13

Member level 5
Joined
Apr 24, 2013
Messages
94
Helped
4
Reputation
8
Reaction score
4
Trophy points
1,288
Activity points
2,287
I am experimenting with this 28Pins PIC PIC16F886 as a beginner and got confused somewhere.
If a start the PWM module , in this case CPP1, the device will get hanged and will not work again. Initially I thought it is software simulation issue but to my surprise I found out that it is the same thing on the Hardware Simulation.
If I compile the code with PWM settings and without the interrupt Timer Delays, it will work and I compile without the PWM it will also work. So now I need help regarding the relationship between the CPP PWM and Interrupt Timer Delay. Are there things I am missing in the code please?
I work with CCS C and I will post the circuit and the Code below.



Code:
#include <16F886.h>
#device ADC = 10
#FUSES NOWDT,HS,PUT,NOPROTECT,NOMCLR,NOCPD NOBROWNOUT,NOIESO,FCMEN, 
#FUSES NOLVP,NOWRT,
#use delay(clock = 8000000)

#define HIGH_START 0xFF -250 //500us INT_RTCC


#define SYS       PIN_B2
#define MS_ON     PIN_B4
#define RL1       PIN_C6
#define MOK       PIN_C7
#define BEEPER    PIN_B6
#define CHG_CTR   PIN_B7

short TabPos,ResetFlag;

short DL2_5s,SDL2_5s;

long MS,CDL2_5s,Counter_sys_1s,Counter_1s,Counter_5s;

const unsigned char PW_Tab[71]= {
0,10,20,30,41,51,61,71,82,92,102,112,123,133,143,153,164,174,184,194,205,
215,225,235,246,256,266,276,286,297,307,317,327,338,348,358,368,379,
389,399,409,420,430,440,450,461,471,481,491,502,512,522,532,543,553,
563,573,584,594,604,614,624,635,645,655,665,676,686,696,706};//70%

void init(void)                                  // Hardware initialization
{
  
  ResetFlag=0;
  setup_oscillator(OSC_8MHZ | OSC_INTRC);
  setup_adc(ADC_CLOCK_DIV_32);                // 8Tosc ADC conversion time
  setup_adc_ports(sAN9);                 // Select Analog Inputs
  setup_ccp1(CCP_PWM);                   // Configure CCP1 as standard PWM
  setup_timer_2(T2_DIV_BY_16,255,1);      // Set PWM frequency to 488Hz?
  set_pwm1_duty(0L);
  setup_comparator(NC_NC_NC_NC);         // disable comparator module

  set_rtcc(HIGH_START);
  setup_counters(RTCC_INTERNAL, RTCC_DIV_4); 
  enable_interrupts(INT_RTCC); 
  enable_interrupts(global); 
  
  SDL2_5s=false;  
  DL2_5s=false;  


}

//   the timer is incremented (8000000/4)/4 or 500000 times a sond (2 us).
//   250 x 2us = 500us

#INT_RTCC

void clock_isr(void)
  {  
    

    {

      
if (SDL2_5s)
        {
        if (++CDL2_5s>=(5000*2))
            { 
             SDL2_5s=false;
             DL2_5s=true;
            }
        } 
      else CDL2_5s=0;
}                     


{   
if (++Counter_SYS_1s>=(1000*2))
            {
            Counter_sys_1s=0; 
            output_toggle(SYS);
            }
}
if (input_state(MOK)==1)
{
if (++Counter_1s >=(1000*2))
            {
            Counter_1s=0;
            output_low(BEEPER);
            }

if (++Counter_5s >=(5000*2))
            {
            Counter_5s=0;
            output_high(BEEPER);
            }
}            

    }

 void main (void)
{
   init();                           // Configure peripherals/hardware

 while(1)
 { 

/////////MS Settings/////////MS Settings/////////MS Settings/////////

{
  set_adc_channel(9);               // Select channel AN9
  delay_ms(1);                       // Wait 1ms
  MS = read_adc();                   // Read from AN9 and  store in MS
  delay_ms(1);                       // Wait 1ms
    
if(MS >= 84 && MS <= 177) // >= 0.410V && <= 0.864V //  >= 140V & <=250V


{
    
      SDL2_5s=true; // 15 seconds delay before MS Changeover
      if(DL2_5s)               
     {
     output_high(MS_ON);
     DL2_5s=false;
     }
}     
      else SDL2_5s=false;
 
if(MS <= 53 || MS >= 258)// <= 0.260V || >=1.26V// Below <= 120V and >= 276V
  
      {
      output_low(MS_ON);// MS is not within usable range
      }
      
}
if (input_state(MOK)==1)

{
     output_low(RL1);
}

if (input_state(MOK)==0)
{
     output_high(RL1);
}

if (input_state(CHG_CTR)==1 && ResetFlag) // PWM Starts
      {
       ResetFlag=0;
       for (TabPos=0;TabPos<=10;++TabPos)
      {
         {
            set_pwm1_duty(PW_Tab[TabPos]);
            delay_ms(50); //  =3 sec
         } 
      }
      }  
if (input_state(CHG_CTR)==0) // PWM Stops

      {
        ResetFlag=1; 
        set_pwm1_duty(0L);
      }

 }
}

View attachment 16F886.rar
 

I can't help with CCS code specifics but at a glance I would say your ISR is far too long and possibly not finishing before the next ISR is due. I'm not sure what calls 'clock_isr()' but with all those calculations and comparisons inside it, the execution time will be fairly long.

just a guess...

Brian.
 

But how can I go about it? The code runs without problems if it doesn't include PWM functions. Please in what way is it long? Is it by defining much variables?

Thanks for your reply.
 

Hi,

May I ask why don't you use hardware PWM?
It does not need processing power ... just the setup.

Klaus
 

I see with MPLAB SIM that the "RTCC" (timer0) interrupt is correctly executed at 500 us period. There's no particularly time consuming code inside the interrupt so it should work. Violating this condition would just loose some timer interrupts but not block execution.

It's however not obvious to me how the main code is expected to "work" and where you see it "hanging". Suggest to test yourself with ICD.
 

@ Klaus, can you give me an example of how to setup a hardware pwm? Is it possible with 16F886?
 

Haha. Did you know that short defaults to int1 for 8-bit CCS? Defining TabPos as int1 makes the loop execute forever


Code C - [expand]
1
2
3
4
5
6
7
8
9
short TabPos,ResetFlag;
...
       for (TabPos=0;TabPos<=10;++TabPos)
      {
         {
            set_pwm1_duty(PW_Tab[TabPos]);
            delay_ms(50); //  =3 sec
         } 
      }



Looking sharp at simulator execution would have told you, of course.

- - - Updated - - -

Btw. I don't understand the hardware pwm point. The code is using hardware pwm.
 

Haha. Did you know that short defaults to int1 for 8-bit CCS? Defining TabPos as int1 makes the loop execute forever


Code C - [expand]
1
2
3
4
5
6
7
8
9
short TabPos,ResetFlag;
...
       for (TabPos=0;TabPos<=10;++TabPos)
      {
         {
            set_pwm1_duty(PW_Tab[TabPos]);
            delay_ms(50); //  =3 sec
         } 
      }



Looking sharp at simulator execution would have told you, of course.

- - - Updated - - -

Btw. I don't understand the hardware pwm point. The code is using hardware pwm.

Ok let me change the "short"
 

I can't help with CCS code specifics but at a glance I would say your ISR is far too long and possibly not finishing before the next ISR is due. I'm not sure what calls 'clock_isr()' but with all those calculations and comparisons inside it, the execution time will be fairly long.

just a guess...

Brian.

Other than "increment variable" I do not see any "calculations" in the ISR.
 

Hi,

@ Klaus, can you give me an example of how to setup a hardware pwm? Is it possible with 16F886?
Sorry, I was confused. I misinterpreted "soft start PWM" with "soft-PWM".
Reviewing your code it seems you already use hardware PWM.

Klaus
 

I see with MPLAB SIM that the "RTCC" (timer0) interrupt is correctly executed at 500 us period. There's no particularly time consuming code inside the interrupt so it should work. Violating this condition would just loose some timer interrupts but not block execution.

It's however not obvious to me how the main code is expected to "work" and where you see it "hanging". Suggest to test yourself with ICD.

Should HIGH_START be set to 0x06 = ( 256 - 250 ) vs ( 0xFF - 250 ) ?
 

Should HIGH_START be set to 0x06 = ( 256 - 250 ) vs ( 0xFF - 250 ) ?
Timer0 is not reloaded automatically. In the present code, it will generate 512 rather than 500 us period. But nothing depends on the exact interrupt frequency, I presume.
 

Another thong that, I guess is wrong, is:
const unsigned char PW_Tab[71]= {
0,10,20,30,41,51,61,71,82,92,102,112,123,133,143,153,164,174,184,194,205,
215,225,235,246,256,266,276,286,297,307,317,327,338,348,358,368,379,
389,399,409,420,430,440,450,461,471,481,491,502,512,522,532,543,553,
563,573,584,594,604,614,624,635,645,655,665,676,686,696,706
};

Isnt unsigned char 8 bit variable?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top