This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ADC and create PWM pulses

Hello
i want to drive a RGB led with three PWM pulses, i use 3 potentiometers to control the PWM duty cycle, timer0 is used to trigger an A2D conversion and when the interrupt arrives i save the result into a buffer and configure the next channel for a conversion. I write the following code and the led is blinking... there is an error but i am unable to find it.

unsigned char t0_reload_value = 0x05;
unsigned char d2a_output = 0xff;

typedef enum SCH {ch0 = 0x00,ch1,ch2} A2DCHANNEL;
A2DCHANNEL channel = ch0;
data volatile unsigned char a2d[3];



void init_pca(void)
{
        CMOD = 0x00;            //cps1=0,cps0=0 (fosc/12),ecf=0
        CH = 0x00;                      //clear PCA timer CH_CL
        CL = 0x00;

        CCAPM0 = 0x42;          //mode 8bit PWM
        CCAPM1 = 0x42;          //mode 8bit PWM
        CCAPM2 = 0x42;          //mode 8bit PWM


        CCAP0H = d2a_output;            //0.4% PWM Duty Cycle=(256-ccap2h)/256
        CCAP1H = d2a_output;            //0.4% PWM Duty Cycle=(256-ccap2h)/256
        CCAP2H = d2a_output;            //0.4% PWM Duty Cycle=(256-ccap2h)/256
        CR = 1;                                 // Turn PCA timer on
}

void init_timer0(void)
{
        TMOD &= 0xF0;                             /* Timer 0 mode 2 with software gate */
        TMOD |= 0x02;           /* GATE0=0; C/T0#=0; M10=1; M00=0; */

        TL0 = t0_reload_value;        /* init values */
        TH0 = t0_reload_value;        /* reload value */

        ET0=1;                                  /* enable timer0 interrupt */
        EA=1;                                                           /* enable interrupts */
        TR0=1;                                                    /* timer0 run */
}

void init_adc()
{
        unsigned char i;
        //Configure P1[0.2] as analog channels
        ADCF = 0x07;

/* Configure ADC clock
                Fadc=Fclk/4*PRS, PRS=5 Fclk=12Mhz then
                Fadc=600Khz and tconv=11/600=18.33usec
*/

        ADCLK = 0x05;

        ADCON = MSK_ADCON_ADEN;         //ADC enable (bit ADEN )

        ADCON &= ~MSK_ADCON_SCH;    //Clear the channel field adcon[2:0]
        ADCON |= channel;                                       //Select channel0 to convert

        ADCON &= ~MSK_ADCON_PSIDLE;         //Standard mode (Disables PSIDLE)

        EADC = 1;               //Enable adc interrupt
        EA = 1;                 //Enable interrupts

        IPH1 = 0x00;
        IPL1 = 0x02;    //Set interrupt level priority at state 1

  ADCON &= ~MSK_ADCON_ADEOC;        //Clear the End of conversion flag

        for(i=0;i<3;++i)
                a2d[i] = 0x00;                  //clean array
}


void main()
{
        unsigned char  r,g,b;
        init_pca();
        init_adc();
        init_timer0();
        while(1)
        {

                r = a2d[ch0];   //get a copy of most recent value
                g = a2d[ch1];   //get a copy of most recent value
                b = a2d[ch2];   //get a copy of most recent value

                CCAP0H = r;
                CCAP1H = g;
                CCAP2H = b;
        }
}

void irq_t0_overflow(void) interrupt 1 using 1
{

                ADCON |= MSK_ADCON_ADSST;       //start A2D conversion

}

void irq_a2d() interrupt 8 using 2
{

        a2d[channel]= ADDH;

        ++channel;
        if(channel == 0x03)
                channel = 0x00;

        ADCON &= ~MSK_ADCON_SCH;            //clear the channel field ADCON[2:0]
        ADCON |= channel;       //Select next channel for convertion
        ADCON &= ~MSK_ADCON_ADEOC;          //clear the End of conversion flag

}

Any ideas? Thanks

0