ADC & PWM in MikroC need advice.

Thread Starter

oookey

Joined May 24, 2010
70
Hi All,

I tried to program the 12F615 to output PWM at pin 5, with respect to the analog input from pin 7 (LDR voltage).

The code compiled and programmed successfully to target chip.
But when ON, it had no output at pin 5, with respect brightness of the light. The circuit patching had no problem.

The codes is attached, please any advice? Thanks.

Chan
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
A couple of things:
Your analog input is on GP0 (channel 0) but you are reading ADC channel 2.

ADC_read returns an unsigned int (16 bits from the 10bit ADC) but PWM_Set_Duty wants a short (8 bits). You may have to do some scaling / casting to fit 0-1023 to 0-255.

Presumably, your CONFIG registers are set by the microC window shown but its best to put CONFIG info in the source code.

You should fully specify binary constants e.g. 0bxx with the full 8 bits i.e. 0b00000001, not 0b001 to avoid confusion.

Good luck!
 
Last edited:

Thread Starter

oookey

Joined May 24, 2010
70
Thank you JohnInTX :) ,
ADC_read returns an unsigned int (16 bits from the 10bit ADC) but PWM_Set_Duty wants a short (8 bits). You may have to do some scaling / casting to fit 0-1023 to 0-255.
Please advice how should i do scaling to fit 0-1023 to 0-255? This is my first attempt in programming.

Presumably, your CONFIG registers are set by the microC window shown but its best to put CONFIG info in the source code.
Please advice how to do it?

You should fully specify binary constants e.g. 0bxx with the full 8 bits i.e. 0b00000001, not 0b001 to avoid confusion.
I changed to 0b00000001, i still have to tackle the first two points.

The datasheet is attached. Please advice. Thanks :p
Chan
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
Please advice how should i do scaling to fit 0-1023 to 0-255?
The easiest way is to divide by 4 (or shift right by 2):

Rich (BB code):
adc_val = ADC_Read(0); //reads 0-1023 ADC value into the unsigned int. Next:
adc_val /= 4;  // divide by 4 -OR-
adc_val = result >> 2; shift right 2 (same result as /4)

//adc_val is now 0-255 which fits into the unsigned short that PWM1_Set_Duty requires so..

PWM1_Set_Duty ((unsigned short) adc_val);  // should do it
It looks like how you are setting the CONFIG (oscillator type etc) is OK for microC.

You should post a schematic of how its wired so we can take a look at it. I assume you are using the microC IDE/Debugger/Programmer?
 

Thread Starter

oookey

Joined May 24, 2010
70
Thanks JohnInTX :),

Your advice was very helpful!

The PIC is doing fine now! :D Attached is the images (oscilloscope wave) of the output at pin5, with & without light; the circuit & code for reference.

Thank you so much.

unsigned adc_Val ; // Create a variable to the ADC value.

void initmain() {
//unsigned short adc_Val;
ANSEL = 0B00000001; // Configure GPIO 0 pin as analog
GPIO = 0; // Initialize GPIO
TRISIO = 0b000001; // SET GPIO 0 AS INPUT, THE REST PINS TO OUTPUT.
CMCON0=0;
CMCON1=0; // OFF THE COMPARATOR
}
void main() {
initmain();
ADC_Init(); // Initialize ADC module with default settings
PWM1_Init(3000); // PWM FREQ. SET AT 3KHz
PWM1_Start();
while(1) {
adc_Val = ADC_Read(0); // read analog value from GPIO 0
adc_val /= 4; // divide by 4
PWM1_Set_Duty((unsigned short) adc_Val); // PWM DUTY CYCLE,
}
}
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
You're welcome!

One more thing to look at. Refer to section 10.3 of the databook for the PIC. For ADC accuracy, it wants a maximum input impedence of 10K. Yours is higher. Its not a big deal here but keep that in mind if you use the ADC again and need full accuracy.

You should also use decoupling capacitors on the power supply pins - something like a .1uf ceramic || 1uf Tantalum would be enough for this.

Have fun!
 
Top