hi guys urgent help

Discussion in 'The Projects Forum' started by devesh123, Sep 2, 2011.

  1. devesh123

    Thread Starter New Member

    Aug 23, 2011
    2
    0
    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!!!!
     
  2. russpatterson

    Member

    Feb 1, 2010
    351
    16
    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
     
  3. devesh123

    Thread Starter New Member

    Aug 23, 2011
    2
    0
    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!!
     
Loading...