Page 1 of 1

PWM for PIC12F683

Posted: 22 Sep 2010 13:42
by JonathanM
Hello,

I wrote the code below using the MikroC Pro compiler to pulse width modulate the speed of a fan. The code is written for the PIC12F683. I am not sure that this code will work and I have not teseted it; it did build sucessfully. I wanted to get some help from you all. What is happening in the code:

==>An analoge signal voltage from a temperature sensor (LM34) is entering the ADC converter on pin 7 (0 to 5 volts = 0deg far to 300deg Far)

==>Convert ADC read to a temperature value

Set PWM duty cycle. Increase in temperature increases the duty cycle.

Please help with your feedback to make it work.

Thanks,
JonathanM

Code: Select all

#include <built_in.h>

  unsigned int Temp;
  unsigned int adc_sample_1, adc_sample_2;
  unsigned int adc_sample_3, adc_sample;
  int scale_coeff = 2932;

  void main() {

  WDTCON = 0x0018;   //Enable Watchdog timer
  PWM1_Init(19530); //Initialize PWM at 19.53KHz (per pic spec-sheet allows 10bit resolution)
  ADC_Init();       //Initialize ADC
  ADCON0 = 0x1F;    //Set VDD as Vref, ANO as analog read
  TRISIO.B2 = 0;    //Set pin 5 (CCP1) as output, used for PWM
  TRISIO.B0 = 1;     //Set pin 7  (ANO) as input, used for ADC read


  while(1){
  
  //ADC Read at ANO
  adc_sample_1 = ADC_Read(0);
  Delay_ms(1000);
  
  adc_sample_2 = ADC_Read(0);
  Delay_ms(1000);
  
  adc_sample_3 = ADC_Read(0);
  Delay_ms(1000);
  
  adc_sample = (adc_sample_1 + adc_sample_2 + adc_sample_3)/3; //Take 3 sample from ADC and take the average
  
  
  //Read ADC Channel 1
  Temp = (adc_sample*scale_coeff)/10000; //Using Integer calculation
  
  //PWM formular for 10 bit resolution: (Percent*1023)/100

  if(Temp > 82 && Temp < 84)
  {
     PWM1_Set_Duty(102);   //Set PWM to 10%
       PWM1_Start();
    }

  if(Temp > 84 && Temp < 86)
  {
      PWM1_Set_Duty(205);  //Set PWM to 20%
       PWM1_Start();
    }

  if(Temp > 86 && Temp < 88)
  {
      PWM1_Set_Duty(307);   //Set PWM to 30%
        PWM1_Start();
    }

  if(Temp > 88 && Temp < 90)
  {
     PWM1_Set_Duty(409);   //Set PWM to 40%
       PWM1_Start();
    }

  if(Temp > 90 && Temp < 92)
  {
     PWM1_Set_Duty(512);  //Set PWM to 50%
       PWM1_Start();
    }

  if(Temp > 92 && Temp < 94)
  {
      PWM1_Set_Duty(614);  //Set PWM to 60%
        PWM1_Start();
    }

  if(Temp > 94 && Temp < 96)
  {
      PWM1_Set_Duty(716);   //Set PWM to 70%
        PWM1_Start();
    }

  if(Temp > 96 && Temp <98 )
  {
     PWM1_Set_Duty(818);   //Set PWM to 80%
        PWM1_Start();
    }

  if(Temp > 98 && Temp < 100)
  {
      PWM1_Set_Duty(921);   //Set PWM to 90%
        PWM1_Start();
    }

  if(Temp >= 100)
  {
      PWM1_Set_Duty(1023);     //Set PWM to 100%
        PWM1_Start();
    }
  else if(Temp < 82)
  {
     PWM1_Set_Duty(0);   //Trun off PWM
        PWM1_Stop();
        
        break;     //Breaks program  out of the while loop and causes it to re-initialize all the registers/start over the process.
   }

  }

  }

Re: PWM for PIC12F683

Posted: 22 Sep 2010 22:37
by braus
JonathanM, from my humble point of view you did a great job when you wrote this code, I understand you are nervous because you are not sure if it will run properly, so, only thing I can tell you is TRY IT my friend, the more you test the project the most you will get confident with it. TRY IT, it is too exciting to see a PIC doing what you want, TRY IT.

Re: PWM for PIC12F683

Posted: 23 Sep 2010 02:00
by JonathanM
Dear Braus,

Thank you for your vote of confidence, it is most appreciated. Unfortunately I do not have the PIC12F683 at the moment (I have to order it). I will certainly test it once I receive it. I was just wondering if there were any noticeable issues/syntax errors with the code I wrote. If you or any one else reading this post notices any possible corrections/improvements to the code please let me know as I would like to get it up and running as soon as I receive the part.

This leads me to my next concern "How to flash the chip?"
To do this I will use my PicKit2 programmer and upload the hex file generated by the MikroC Pro compiler (for the code I wrote) to the chip.

Is this the correct method for flashing the 12F?

I do apologize for the newbie questions.

Thank you,

JonathanM

Re: PWM for PIC12F683

Posted: 28 Sep 2010 04:49
by Eng_Bandar
Try test your project by Proteus very easy.

Re: PWM for PIC12F683

Posted: 30 Sep 2010 16:14
by Bonca
Hi,
based on my experience take a look at tha last reply of this topic:
http://www.mikroe.com/forum/viewtopic.p ... lit=12f683

Bonca

Re: PWM for PIC12F683

Posted: 06 Oct 2010 03:10
by JonathanM
Thank you all for taking the time to respond to my post. I have not yet gotten the program to run. I think my main problem is not fully understanding the way in which I need to map the input to the ADC and the output to the CCP. My confusion is mainly between bits and pins on the PIC12F683 MCU. For example if I wanted to turn a bit high to light a LED. Lets say the LED is connected to bit 0 on Port B, for the PIC16F877A MCU I would say in the following code.

Code: Select all

void main(){
TRISB = 0;

while(1){
PORTB.B0 = 1;
}
}



But it is a little confusing to me with the I/O pins on the PIC12F683 how do the bits and pins correlate and how do I access them/use them for my application to read an analog signal from AN3 pin and output the PWM on the CCP pin???

Re: PWM for PIC12F683

Posted: 06 Oct 2010 13:10
by Bonca
Hi,
In my application you could find comments with page numbers of the 12F683 datasheet. According to this You will understand how to read the value of an analog pin, how to configure the PWM and so on...

Bonca

Re: PWM for PIC12F683

Posted: 03 Nov 2010 02:02
by JonathanM
Hello,
I was able to get my program to run per Bonca’s advice.
I am now writing because I ran into a new problem that has me going around in circles for some time now. My problem is; I cannot get the program to work when I use my math algorithm to determine the temperature in my “if” statements; the “if “statements do work however when I replace the temperature value with the count that the ADC produces.
Some information below
300 degF / 1023 bits = (0.2932 degF/bit)
The scaling coefficient I am using is 2932
And I am storing my ADC_Read into an “unsigned int adc_sample”
Therefore:

Code: Select all

Temp = (2932* adc_sample) / 10000
if((Temp => 86) && (Temp < 88))
  {
      PWM1_Set_Duty(307);   //Set PWM to 30%
        PWM1_Start();
}
But is does now work

If I replace the information in the if statement with the information in the code below it works

Code: Select all

if((adc_sample => 293) && (adc_sample < 300))
  {
      PWM1_Set_Duty(307);   //Set PWM to 30%
        PWM1_Start();
}
Any one has any idea why it is not working with my math please help.

Thanks

Re: PWM for PIC12F683

Posted: 03 Nov 2010 06:39
by MR2010
Hi, bcz unsigned int Temp; is only 65535 bits so it cant handle Temp = (2932* adc_sample) before /10000, hope im not wrong and this helps

Regards.

Re: PWM for PIC12F683

Posted: 03 Nov 2010 11:19
by Bonca
Hi,
I am not a good C programmer, but I always use <= or >= istead of a simple < or >.

Bonca

Re: PWM for PIC12F683

Posted: 15 Nov 2010 16:49
by JonathanM
Hello MR2010,

You were correct! That was my problem, if I change the value of my scaling coefficient to a smaller number like 29 it works. Or I can also change to the "unsigned long int" for the larger number 2932 and that also works as well.

Thanks for your help

Jonathan.