Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help needed - PWM generation using PIC16F676

Status
Not open for further replies.

suri0077

New Member
Hi Ian ,

I have seen your posts in the topic "HOW to Start with PIC16F676" and the help you provided to Mr.RITESH for PWM generation on PIC16F676.

I need some help regarding this, I want to implement 8bit PWM at 2kHZ as u did in the topic, but i want to change the duty cylcle like say i want PWM at pin2(RA5) and for some period of time like 500ms the duty cycle should be 80% and for other 500ms the duty cycle should be 5%.

Can u please help me, i am not able to do it, either i am able to acheive 80% duty cycle or 5% duty cycle

code written in MPLAB IDE:


/*
* File: PWM.c
* Author: s00742788
*
* Created on February 3, 2013, 12:31 PM
*/


#include <xc.h>
#include<htc.h>
#include<pic.h>
#include<pic16f676.h>
#define _XTAL_FREQ 4000000
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)


int OnPulse =0;
int OffPulse = 250;
char TOG = 0;
int i = 0;

void interrupt Interrupt_Service_Subroutine(void)
{
T0IF = 0;
i = i+1;
TOG = ~TOG;

if(i>=2001)
{
i=0;
}

if(i<=1000)
{
if(TOG)
{
RA5 = 1;
TMR0 = 242;
}

else
{
RA5 = 0;
TMR0 = 14;
}
}

if((i>1000) && (i<2001))
{
if(TOG)
{
RA5 = 1;
TMR0 = 32;


}

else
{
RA5 = 0;
TMR0 = 224;

}
}


}


void main()
{
int pulse;
TRISCbits.TRISC3 = 0;
TRISCbits.TRISC0 = 1;
TRISAbits.TRISA5 = 0;
CMCON = 7;
TMR0 = OnPulse;
ANSEL = 0x10;
OPTION_REG = 0;
T0IE = 1;
GIE = 1;
RC3=1;

while(1)
{

}
}

}
 
Hi Ian,


Thanks for the reply... My question is how do i make the program the program in such a way that for 1 second of the time the duty cycle should be 85% and for next 1 second it should be 5%.

i have written i<1000 and i>1000 so that this will happen, but at pin 2 i see output volatge of 0.3V which is 5% duty cycle.

my requirement is for 1 second, the output at pin2 should be 0.3V which is 5% duty cycle and for the next 1 second it should be 4.25V which is 85% of the duty cycle. please tell me how to do this.
 
A good practice is to draw the operation out as a flowchart, BEFORE you do too much coding.

You can do that as text, it does not have to be an image. Something like this;

1. setup PIC ports and PWM module
2. load PWM module with 85%
3. wait for 1 second
4. load PWM module with 5%
5. wait for 1 second
6. goto 2 (repeat!)

if you need perfect seconds (ie for clock use) then you need a slightly more complex system, so you really need to explain what the *entire project does* instead of just asking about PWM operation.
 
Hi RB,

Thanks for the response. I am in my final year of engineering and the project is to implement a solar charge controller.
I am using PIC16F676 which does not have a Hardware PWM Module, so i wrote this code to implement it in software.

The use for PWM in my program is to charge the battery in Trickle charging mode, so i want to oscillate the code between duty cycle of 85% and 5% .

But when i try to implement this in my code i only see 5% duty cycle at Pin2 which is 0.3V.

Can u tell me sample code of how to load PWM module with duty cycle and wait for 1 second

Also please tell me in how much time it takes forl Timer0 become full (count from 00 to FF)

In my code i am using Internal Oscillator of 4MHZ and Prescaler of 1:2

Regards,
Suresh
 
Roman!! The chip doesn't have a CCP module... It was a software implementation..


Suresh!! The counter was set in the original code for 2khz ( well slightly under ) PWM...

I told you in the PM what values to set for 85% and 5%

For 85% you set ON to 217 and OFF to 38

For 5% you set ON to 13 and OFF to 242
 
Hi Ian,

I have understood how to set duty cycle for 5% and 85%, what i need now is how to have duty cycle of 5% for 1second and duty cycle of 85% for 1 second in a continuous loop,

Also please tell me how much time it takes for Timer0 to get full from 00 to FF, is it 500 micro sec?

i need to implement trickle charging mode , at 85% duty cycle current provided to battery is maximum and at 5% current is minimum

how to count the 1 second time between 5% and 85% duty cycles is the problem for me plz help
 
Hi Ian,

Please tell me if the below code is correct, I found out for a PWM freq of 2KHZ with prescaler of 1:2 the timer0 gets full from 00 to FF in 500micro sec approximately.

So in below code for trial purpose i made RA5 pin ON for 400 Timer0 cycles which is around 400x500micro sec = 200msec
and made RA5 pin OFF for the same 400 Timer0 cycles which is around 400x500micro sec = 200msec

If I conncet a LED to the RA5 pin, will the LED be tuned ON and OFF with a interval of 200msec visible to human eye? please help

If this works i guess my problem will be solved...

void interrupt Interrupt_Service_Subroutine(void)
{
T0IF = 0;
i = i+1;

if(i>=401)
{
i=0;
}

if(i<=200)
{
TMR0 = 0;
RA5 = 0;

}

else
{
TMR0 = 0;
RA5 = 1;
}

}
 
The frequency of the PWM is @2khz.... Its called TWICE during one period ( on and off ).. That means there are 4000 calls to the interrupt per second..

Your variable i ( which needs to be a word ) needs to count to 4000..... Within the Timer interrupt to allow for 1 second of time.
 
Hi Ian,

If you dont mind can u change the code, i am a newbie and i am not good at understanding sometimes. Please do the needful.

Regards,
Suresh
 
In simulation this changes from 5% to 85% every second.

Code:
/*
 * File:   PWM.c
 * Author: s00742788
 *
 * Created on February 3, 2013, 12:31 PM
 */


#include <xc.h>    You can't have all these..
//#include<htc.h>
//#include<pic.h>
#include<pic16f676.h>
#define _XTAL_FREQ  4000000
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)


int OnPulse = 217;
int OffPulse = 38;
char TOG = 0;
int i = 0;

void interrupt Interrupt_Service_Subroutine(void)
	{
    	T0IF = 0;
        i += 1;
	TOG = ~TOG;
    
        if(i>=8000)	// two seconds
		{
                i=0;
		}
        
	if(i<=4000) 	// First second 85%
		{
		if(TOG)
			{
			RA5 = 1;
			TMR0 = 217;
			}

		else
			{
			RA5 = 0;
			TMR0 = 38;
			}
		}

        if(i>4000)    // Second second 5%
		{
		if(TOG)		
			{
			RA5 = 1;
			TMR0 = 13;
			}
		else
			{
			RA5 = 0;
			TMR0 = 242;
			}
		}
	}


void main()
	{
	int pulse;
	TRISCbits.TRISC3 = 0;
        TRISCbits.TRISC0 = 1;
	TRISAbits.TRISA5 = 0;
	CMCON = 7;
	TMR0 = OnPulse;
	ANSEL = 0x10;
	OPTION_REG = 0;
	T0IE = 1;
	GIE = 1;
        RC3=1;
        
	while(1)
        {

        }
   }
 
Hi ian,

I think there is some confusion

if(i<=4000) // First second 85% (This would be 5% duty cycle as TMR0 is On from 217 to 255)
{
if(TOG)
{
RA5 = 1;
TMR0 = 217;
}

else
{
RA5 = 0;
TMR0 = 38;
}
}

if(i>4000) // Second second 5% (This would be 85% duty cycle as RA5 is ON for TMR0 from 13 to 255)
{
if(TOG)
{
RA5 = 1;
TMR0 = 13;
}
else
{
RA5 = 0;
TMR0 = 242;
}

Regards,
Suresh
 
Hi Ian,

Thanks for the reply. yesterday i tried the same way but i had the code like this

Scenario 1:
if(i>=20001)
{
i=0;
}

if(i<=10000) //Duty cycle 5%
{
if(TOG)
{
RA5 = 1;
TMR0 = 217;
}

else
{
RA5 = 0;
TMR0 = 38;
}
}

if(i>10000)
{ //Duty cycle 85%
if(TOG)
{
RA5 = 1;
TMR0 = 13;
}
else
{
RA5 = 0;
TMR0 = 242;
}
}


or even like this

Scenario 2:

if(i>=1001)
{
i=0;
}

if(i<=1000) //Duty cycle 5%
{
if(TOG)
{
RA5 = 1;
TMR0 = 217;
}

else
{
RA5 = 0;
TMR0 = 38;
}
}

if(i>1000)
{ //Duty cycle 5%
if(TOG)
{
RA5 = 1;
TMR0 = 13;
}
else
{
RA5 = 0;
TMR0 = 242;
}
}


In both the case i got output at pin2 as 0.32V and it didnt change at all, only the 1st loop was getting executed with duty cycle of 5%


Can u tell me what i got wrong in these two scenarios


Regards,
Suresh
 
Hi Ian,

I am not sure about these two terms what you said

1. Declare variable 'i' as word, please tell me why, 4000 means its saved on only 16 bits right

2. Output pin getting overloaded?????

You said its working for you, please tell me how are you verifying this, software or hardware?

I am getting really nervous with these results, i know my approach is fine, but the problems are not getting solved..

Please help.

Regards,
Suresh
 
Hi Ian,

If you dont mind please leave your mail ID , Or i have sent u an add request in Skype. Please add me there. It would be of great help if you can help me

Regards,
Suresh
 
Sorry about that!! You must remember that when I'm at work, I cannot spend every minute online....

Anyway... We have had a power cut at work ( Due to the snow .. possibly) and I am now back home...

I simulate with ISIS, but I'm pretty confident about the results..


You already have i as a word... ( int i;) s don't worry about that...

I do not respond on skype... In fact I'm going to remove it from here... I have too many nutters trying to "add" me...
 
Hi Ian,

So in ISIS could you see the duty cycle changes with 1 sec interval, and can u tell me about the point Pin getting overloaded????

Regards,
Suresh
 
Status
Not open for further replies.

Latest threads

Back
Top