If you like to experiment with microcontrollers you've probably tried out analog-to-digital conversion and generating PWM signals. Using a popular PIC microcontroller like the 16F877A, which has both ADC and CCP (Capture/Compare/PWM) modules, you can test out both of these easily because mikroC provides easy to use library functions for both of them. (Most of you will be familiar with these libraries, so I won't be going in to much detail about them here. Leave a comment if you like to learn more.. :) )
Now, think of a scenario like this: You want to change the duty cycle of your PWM signal based on a analog signal. It can be from a variable resistor that you want to use to increase or decrease the duty cycle, or it can be a feedback from a sensor which is analog.
So, how can we do it?... we simply use the ADC to convert the analog signal and use that value as the duty cycle value. All we need is a microcontroller that has both a CCP and a PWM module. As I said before, the popular 16F877A fits the criteria.
So, now that we have our microcontroller, let's get down to the code.
Here's the sample code
Let's see what's happening in the code,
Here's the basic circuit for testing this code
Use the R2 variable resistor to get the varying analog signal. The brightness of the LED will change based on the PWM.
You can use this same method to generate a PWM based on any analog signal. Just think of the possibilities...
References
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010242
Now, think of a scenario like this: You want to change the duty cycle of your PWM signal based on a analog signal. It can be from a variable resistor that you want to use to increase or decrease the duty cycle, or it can be a feedback from a sensor which is analog.
So, how can we do it?... we simply use the ADC to convert the analog signal and use that value as the duty cycle value. All we need is a microcontroller that has both a CCP and a PWM module. As I said before, the popular 16F877A fits the criteria.
So, now that we have our microcontroller, let's get down to the code.
Here's the sample code
unsigned int temp_res;
unsigned char temp_duty;
void main() {
ADCON1 = 0x80; // Configure analog inputs and Vref
TRISA = 0xFF; // Set PORTA as an input
TRISC = 0; // Set PORTC as an Output
PORTC = 0;
// Initialize and start the PWM unit
PWM_Init(5000);
PWM_Start();
while(1){
temp_res = Adc_Read(2); // Get results of AD conversion
from channel 2 (RA2 pin)
temp_duty = (temp_res/4); // Convert the 10 bit value
to 8 bits
PWM_Change_Duty(temp_duty); // Set the duty value
Delay_ms(50); // Slow everything down a little
}
}
Let's see what's happening in the code,
- First, we declare 2 variables - temp_res to store the result of AD conversion and temp_duty to store the 8 bit value for the duty cycle.
- We use the ADC_Read(2) function to read the analogue input from AN2 pin, convert it to digital and store the 10 bit value in temp_res.
- Since the value for the duty cycle should be 8 bits (0 to 255) we simply divide the temp_res by 4 and store it in temp_duty.
- Finally, we use the PWM_Change_Duty() function and set the duty cycle to the value of temp_duty.
Here's the basic circuit for testing this code
Use the R2 variable resistor to get the varying analog signal. The brightness of the LED will change based on the PWM.
You can use this same method to generate a PWM based on any analog signal. Just think of the possibilities...
References
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010242
What is different about the pic16f887 that this code doesnt work with it?
ReplyDeletei tried your code, its working but as the analog voltage is changed the pulse width changes but the frequency shown in the DSO remain same, whats the problem?????
ReplyDeleteplease post the link of the header file.
ReplyDelete