Author Topic: problems with c code for pic (adc and pwm)  (Read 2929 times)

0 Members and 1 Guest are viewing this topic.

Offline little_carlosTopic starter

  • Regular Contributor
  • *
  • Posts: 133
problems with c code for pic (adc and pwm)
« on: April 02, 2016, 02:22:15 am »
hey, so, i made a code to control pwm output with a pot on adc chanel (AN2), i run it on proteus and it works perfect, just as i wanted, but in the actual real circuit it doesnt behave like that, the change on the duty cycle is small, why is not acting like on proteus?
the pic is 16f887 btw
here is the code
unsigned adc;
void Initmain() {
ANSEL = 0x04;
ANSELH = 0;
TRISA = 1;
TRISC = 0;
PORTC = 0;
C1ON_bit = 0;                       // Disable comparators
C2ON_bit = 0;
PWM1_Init(5000);

}
void main(){
Initmain();
adc = 0;
PWM1_Start();
PWM1_Set_Duty(adc);


while (1) {
adc = ADC_READ(2);
PWM1_Set_Duty(adc);

}

delay_ms(5);
}
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: problems with c code for pic (adc and pwm)
« Reply #1 on: April 02, 2016, 11:20:27 am »
Is the ADC result a right justified 10 bit result in a 16 bit word ?
I assume your PWM is 16 bits, so you should do the following if
result is right justified -

PWM1_Set_Duty( adc << 6 );

This assumes A/D result is unsigned.

Regards, Dana
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 

Offline little_carlosTopic starter

  • Regular Contributor
  • *
  • Posts: 133
Re: problems with c code for pic (adc and pwm)
« Reply #2 on: April 02, 2016, 01:35:14 pm »
Is the ADC result a right justified 10 bit result in a 16 bit word ?
I assume your PWM is 16 bits, so you should do the following if
result is right justified -

PWM1_Set_Duty( adc << 6 );

This assumes A/D result is unsigned.

Regards, Dana
and if the pwm is 8 bit?
 

Offline ProAce

  • Contributor
  • Posts: 19
  • Country: si
Re: problems with c code for pic (adc and pwm)
« Reply #3 on: April 04, 2016, 08:41:35 am »
I assume it isn't working because you are trying to fit an int(adc) into char(duty ratio).
From MikroC lib:  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.
 

Offline Philfreeze

  • Regular Contributor
  • *
  • Posts: 123
  • Country: ch
Re: problems with c code for pic (adc and pwm)
« Reply #4 on: April 04, 2016, 10:13:04 am »
ADC_READ() returns for this PIC a 10bit value (0-1023). You want to give this to a PWM where 0=0% and 255=100%. It looks like PWM1_Set_Duty() has a 16bit parameter (unsigned short) for some reason.
You will get an unexpected behaviour if you just give the 10bit value to PWM1_Set_Duty() because it should only get values <256.

This means you probably have to perform:
Code: [Select]
adc = ADC_READ(2) >> 2; // shift by 2 is equal to /4
PWM1_Set_Duty(adc);

This way the maximum value of adc is now 255 (1023/4 round up).
 

Offline little_carlosTopic starter

  • Regular Contributor
  • *
  • Posts: 133
Re: problems with c code for pic (adc and pwm)
« Reply #5 on: April 04, 2016, 11:05:54 pm »
I assume it isn't working because you are trying to fit an int(adc) into char(duty ratio).
From MikroC lib:  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.
Thanks, but how could I implement it to my code?
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: problems with c code for pic (adc and pwm)
« Reply #6 on: April 05, 2016, 01:13:42 am »
unsigned adc;

adc = ADC_READ(2);            /* reading channel 2                                      */
PWM1_Set_Duty((unsigned char) (adc >> 2))   /* assuming 10 bit ADC.  If 12 bit, adc >> 4 */

or you could write it in one statement like:

PWM1_Set_Duty((unsigned char) (ADC_READ(2) >> 2));
 

Offline ProAce

  • Contributor
  • Posts: 19
  • Country: si
Re: problems with c code for pic (adc and pwm)
« Reply #7 on: April 05, 2016, 05:05:44 am »
Indeed. Don't let the shifting bits cofuse you. By shifting the (binary) value you are simply dividing it to fit 8bit (255 in decimals) duty ratio as Philfreeze already said. Check this out: http://www.eevblog.com/wiki/index.php?title=Embedded_Programming_Tips_and_Tricks_for_Beginners
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf