how to increase the resolution on this adc to pwm code on pic16f887? - Page 1
Forum section: electronics / general

author: little_carlos
author_rank: Regular Contributor
timestamp: April 02, 2016, 08:01:24 pm
content: hi, i have this code, it works but the resolution on the pot is very small, what i mean is that the whole range of duty cycle can be increased or decreased with a small movement on the pot, not even 20% of the total movement of the pot, here is the code :int potdigital;void Initmain() {ANSEL = 0x04;ANSELH = 0;TRISA = 1;TRISC = 0;PORTC = 0;C1ON_bit = 0; // Disable comparatorsC2ON_bit = 0;PWM1_Init(1000);potdigital = 0;}void main(){Initmain();PWM1_Start();PWM1_Set_Duty(0);while (1) {potdigital = ADC_READ(2);PWM1_Set_Duty(potdigital);delay_ms(5);}}what can i do to increase the resolution on the pot to have a more accurate duty cycle control

author: JPortici
author_rank: Super Contributor
timestamp: April 04, 2016, 07:06:12 am
content: RTFM.Please, read the help provided in mikro c.void PWM1_Set_Duty(unsigned short duty_ratio);Sets PWM duty ratio. Parameter duty takes values from 0 to 255, where 0 is 0%, 127 is 50%, and 255 is 100% duty ratio. Other specific values for duty ratio can be calculated as (Percent*255)/100.This should be rather obvious if you remember that you are passing a 10 bit number.

author: rstofer
author_rank: Super Contributor
timestamp: April 04, 2016, 09:08:08 pm
content: As stated above, you are reading into an unsigned int and using 10 or 12 bits depending on the device.When you write to the PWM, you are only sending the lower 8 bits, what about the most significant bits?You need to right shift the unsigned int until only 8 significant bits remain and then stuff those into the PWM function.Yes, you will lose 2 or 4 least significant bits but that's the nature of using an 8 bit PWM.http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/adc_library.htm

author: Ian.M
author_rank: Super Contributor
timestamp: April 04, 2016, 09:23:34 pm
content: Why use MikroC's borked library functions?If you initialise the ECCP module for PWM by loading the registers directly, you can set the duty cycle in CCPR1L + CCP1CON:DCxB for the two LSBs, with 10 bit resolution, which matches the ADC resolution for this PIC. You'll also need to make sure PR2 is set tozero0xFF for a PWM timebase that permits 10 bit duty cycle resolution.Edit: corrected PR2. The PWM period is PR2+1 cycles of the Timer 2 clock, after prescaling.

author: JPortici
author_rank: Super Contributor
timestamp: April 04, 2016, 09:29:28 pm
content: Ian... from piclist?I suppose he is moving first steps into the pic world. I'd recommend mikro c too at this stage, very useful for proof of concepts and testing displays and whatever before writing your own code.. And i like it better than arduino's "language" as i find it more similar to Canyway (older) pic16 have 10 bit pwm, but with a rather absurd logic for the 2 lsbs, so you usually discard them and "fake" a 8 bit pwm.. i never understood why you have to put the lsbs in odd positions in another register (because the severe lack of ram bytes on old parts? infact slightly more modern pics have 2 dedicated registers instead, which can be used in left or right justified mode)

author: dannyf
author_rank: Super Contributor
timestamp: April 04, 2016, 10:12:39 pm
content: "not even 20% of the total movement of the pot, "Because the adc is 10 bit and your pwm is likely 8 bit.Two solutions.1. Use 8bit adc.2. Increase the pwm to 10bits.

author: Buriedcode
author_rank: Super Contributor
timestamp: April 05, 2016, 01:51:08 pm
content: As suggested, you can either use the upper 8 bits of your ADC result, and send it to the 8-bit PWM (mikroC's PWM library uses an 8-bit input). OR, manually use the PWM, (the datasheet provides step-by-step instructions for this) in which case you can use 10-bits to match the ADC.For the simple case of using a pot to control PWM, using built-in libraries, using this line:potdigital = ADC_READ(2) >> 2;Your ADC result will be a 10-bit number (stored in unsigned int, 16-bit).Left shift by 2 will knock this down to 8-bit by dumping the two LSB's (divide by 4).At the moment, your ADC result is the equivalent of four 8-bit numbers, so the range of the pot (assuming its connected between GND and Vref/VDD) 0-100%, 0-100%, 0-100%, 0-100%.