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