hi guys urgent help

Thread Starter

devesh123

Joined Aug 23, 2011
2
Hi guys i am doing my project upon MPPT i am using PIC16F877A microcontroller i have written the code in C language in MPLabs but i am not able to see any PWM waveform through my circuit .PLEASE HELP ME ,i am in dire need.
Certain specifications
crystal oscillator frequency = 20MHz
PWM frequency = 100KHz
below is the given code


#include <pic.h>
__CONFIG(0x1832);

unsigned int Power, Power_Old;
unsigned char Voltage, Current, Voltage_Old, Current_Old, PWM = 0x1F, PWM_MAX = 0xFA, PWM_MIN = 0x05, FLAG, i;

void DELAY(void)
{
unsigned char a;
for (a=0; a<1; a++);
}


void main(void)
{
CCP1CON = 0;
PR2 = 0b00001100; /* Set Time Period Value */
TRISCbits.TRISC2=0; /* Set RC2 as an output pin */
T2CON = 0x00; /* No Prescalers Timer 2 OFF */
CCP1CON = 0b00001100; /* PWM Mode */
CCPR1L = 0b00001011;
TMR2 = 0; /* Reset Timer 2 */
T2CONbits.TMR2ON = 1; /* Timer 2 ON */
FLAG = 1; /*shows last increment/decrement*/

for(i=1; i>0; i++){
Power_Old = Power; /* Set panel power from previous cycle/

TRISAbits.TRISA1 = 1; /* AN0 analog input for voltage*/
ADCON0 = 0x81; /* 10000001 */
ADCON1 = 0xC4; /* 01000100*/
DELAY();
ADCON0bits.ADON = 1; /* Begin A/D Conversion*/
while(ADON); /* Wait for the conversion to end*/
Voltage = ADRESL;
Voltage += (ADRESH<<8);


TRISAbits.TRISA1 = 1; /* AN1 analog input for current*/
ADCON0 = 0x89; /* 10001001 1st 2 bits fosc/64 along with ADCON1, next 3 select channel AN1, last digit turns ADC on */
ADCON1 = 0xC4; /* 01000100 Left justify, fosc/64, 3 analog inputs, Vref+ = VDD, Vref- = VSS */
DELAY(); /* Gives ADC time to sample*/
ADCON0bits.ADON = 1; /* Begin A/D Conversion*/
while(ADON); /* Wait for the conversion to end*/
Current = ADRESL;
Current += (ADRESH<<8);

Power = Voltage * Current;

if(FLAG == 1){ /* Compare Voltage and power to previous and increment/decrement DUTY cycle*/
if(Power - Power_Old > 0){
PWM++;
FLAG = 1;
}
else{
PWM--;
FLAG = 0;
}
}

if(FLAG == 0){
if(Power - Power_Old > 0){
PWM--;
FLAG = 0;
}
else{
PWM++;
FLAG = 1;
}
}


if(PWM > PWM_MAX){ /* Keeps DC between 0 and 95% */
PWM = PWM_MAX;
}
if(PWM < PWM_MIN){
PWM = PWM_MIN;
}


PIR1bits.TMR2IF = 0; /* clear timer 2 flag*/
while(PIR1bits.TMR2IF==0); /* wait for end of period*/

}
}

thanks very much indeed for your help!!!!
 

russpatterson

Joined Feb 1, 2010
353
You're probably better off on the microchip or sparkfun forums for the uC stuff. But the first thing I'd do is break your code into some functions, so you can just get an LED blinking on an output pin. Then just get the PWM function showing up on your scope on an output pin. Sneak up on it. The datasheets for the PIC's are good but it takes some re-reading to understand what they are telling you sometimes. Go through the PWM section in step by step, repeat as necessary. Cut and paste important sections into your code so you don't have to wonder why you set those bits later on.

Also, find the header file (.h) for your PIC (it's be the part # in the filename) and use the macros to set the bits of the registers. It makes everything much easier to understand and edit. FWIW here's my setup code for PWM on the PIC16F1829

TRISC5 = 1; // Set TRIS pin to disable CPP1


//setup CCP1CON
/*
CCPxM<3:2> = 11:\

00 = Single output; PxA modulated; PxB, PxC, PxD assigned as port pins
01 = Full-Bridge output forward; PxD modulated; PxA active; PxB, PxC inactive
10 = Half-Bridge output; PxA, PxB modulated with dead-band control; PxC, PxD assigned as port pins
11 = Full-Bridge output reverse; PxB modulated; PxC active; PxA, PxD inactive

ECCP Modules only:
1100 = PWM mode: PxA, PxC active-high; PxB, PxD active-high
1101 = PWM mode: PxA, PxC active-high; PxB, PxD active-low
1110 = PWM mode: PxA, PxC active-low; PxB, PxD active-high
1111 = PWM mode: PxA, PxC active-low; PxB, PxD active-low
*/
CCP1M0 = 0; //ECCPx Mode Select bits -
// 11xx = PWM mode
// 1101 = PWM mode: PxA, PxC active-high; PxB, PxD active-low
CCP1M1 = 0;
CCP1M2 = 1;
CCP1M3 = 1;

DC1B0 = 0; // Least Significant bits of duty cycle
DC1B1 = 0;

/*
P1M0 = 0; // half bridge
P1M1 = 1; // half bridge
*/


P1M0 = 0; // single
P1M1 = 0; // single

CCPR1L = 0x32-8; // duty cycle
initTimer4(ON);

// CCP2 Timer Select -01 = CCP1 is based off Timer 4 in PWM Mode
C1TSEL0 = 1;
C1TSEL1 = 0;



/*** NOTES ***/
// set CCPxCON register

// bring out the same PWM signal to one, two, three or four output
// pins by setting the appropriate STRx<D:A> bits of the
// PSTRxCON register
// RDP: I think steering and half bridge, w/dead band are mutually exclusive, so don't set

// select the PWM output polarity for the Px<D:A> pins.

/* Set deadband delay period
The lower seven bits of the associated
PWMxCON register (Figure 23-4) sets the delay period
in terms of microcontroller instruction cycles (TCY or 4 TOSC). */
P1RSEN = 1; //1 = Upon auto-shutdown,
// the CCPxASE bit clears automatically once the shutdown event goes away;
// the PWM restarts automatically
PWM1CON = 0x86; // delay band: 6 = 6 Decimal
// Number of FOSC/4 (4 * TOSC) cycles between the scheduled time when a PWM signal
// should transition active and the actual time it transitions active
TRISC5 = 0; // Clear TRIS pin to enable CPP1
 

Thread Starter

devesh123

Joined Aug 23, 2011
2
To russpatterson
I am not sure of CCP1CON and CCPR1L register values and i am also not very much sure of TIMER 2 bit selection
i got those values from the below site

http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html

can you please tell me whether my main code is right or not

i selected the 1:1 prescaler value to find out the value for PR2 register and i calculated the PR2 as 49 so i am writing as
PR2 = 49;
is it okay???

for timer2 i followed the article below


T2CKPS1:T2CKPS0: Timer2 Clock Prescale Select bits
The input clock (FOSC/4) has a prescale option of 1:1, 1:4 or 1:16, selected by control bits T2CKPS1:T2CKPS0 (T2CON<1:0>).

00 = Prescaler is 1
01 = Prescaler is 4
1x = Prescaler is 16

TMR2ON: Timer2 On bit
Timer2 can be shut-off by clearing control bit, TMR2ON (T2CON<2>), to minimize power consumption.

1 = Timer2 is on
0 = Timer2 is off

TOUTPS3:TOUTPS0: Timer2 Output Postscale Select bits
The match output of TMR2 goes through a 4-bit postscaler (which gives a 1:1 to 1:16 scaling inclusive selected by control bits TOUTPS3:TOUTPS0 (T2CON<6:3>).

0000 = 1:1 postscale
0001 = 1:2 postscale
0010 = 1:3 postscale



1111 = 1:16 postscale

The following is an example how we can initialize the T2CON register:

1. TMR2ON=1; // the timer is enable
2. T2CKPS0=0; // Prescaler – 1:1
3. T2CKPS1=0;

4. TOUTPS0=1; // Postscaler – 1:16
5. TOUTPS0=1;
6. TOUTPS0=1;
7. TOUTPS0=1;

Or you can set all the T2CON register at once as follows

tell me whether do i have anything to do with postscalar value so i am taking those as 1:1 postscalar (0000)

thanks very much for your previous help!!
 
Top