PIC Interface PWM
This code sets up PWM on PIC MCU (RC2 pin), with duty cycle controlled by switch inputs (RB0–RB3). Useful for LED dimming or DC motor speed control. Generate predefined PWM using four buttons
Functions for PIC Interface PWM
- pwm_init()
- pwm_dutycycle(unsigned int duty)
How It Works
- Timer2 + CCP1 module generate PWM.
- RC2 pin outputs PWM signal.
- Buttons on RB0–RB3 control duty cycle.
- RB0 → OFF (0%)
- RB1 → 25% duty
- RB2 → 50% duty
- RB3 → 100% duty
Code of PIC Interface PWM
- Generate PWM using PWM functions
- Define Port-B as input and RB0, RB1, RB2 and RB3 used as button input
Note : UN-command the line depend on your preferred compiler.
//www.ArunEworld.com/embedded/microchip/pic_mcu/
#include<pic.h> // for Hi-Tech Compiler
#define _XTAL_FREQ 4000000
//short currduty1=16;
void init()
{
PORTB=0X00;
TRISB=0X0f;
}
void pwm_dutycycle(unsigned int duty)
{
CCPR1L=duty;
CCP1CON&=0xCF;
CCP1CON=(CCP1CON|(0X30&(duty<<4)));
}
void pwm_init()
{
TRISC=0X00;
CCP1CON=0X0C;
PR2=96;
TMR2=0;
T2CON=0x7B;
pwm_dutycycle(0);
T2CON=0X7F;
}
void delay(unsigned int de) { while(de--); }
void main()
{
pwm_init();
while(1)
{
if(RB0) { /*delay(100);*/ pwm_dutycycle(0); }
if(RB1) { /*delay(100);*/ pwm_dutycycle(64); }
if(RB2) { /*delay(100);*/ pwm_dutycycle(128); }
if(RB3) { /*delay(100);*/ pwm_dutycycle(255); }
}
}
Code Explanation
Header & Clock
#include <pic.h> // Hi-Tech C compiler header #define _XTAL_FREQ 4000000 // 4 MHz crystal frequency
pic.hgives access to PIC registers._XTAL_FREQis required for delay macros (__delay_ms()/__delay_us()).
Initialization
void init()
{
PORTB = 0x00; // Clear PORTB
TRISB = 0x0F; // RB0–RB3 as input, RB4–RB7 as output
}
- PORTB is used for input switches (RB0–RB3).
Duty Cycle Function
void pwm_dutycycle(unsigned int duty)
{
CCPR1L = duty; // Load 8 MSBs of duty cycle
CCP1CON &= 0xCF; // Clear lower 2 bits
CCP1CON = (CCP1CON | (0x30 & (duty << 4))); // Update lower 2 bits
}
- Configures PWM duty cycle.
CCPR1Lstores the high 8 bits.CCP1CON<5:4>stores the lower 2 bits → total 10-bit resolution.
PWM Initialization
void pwm_init()
{
TRISC = 0x00; // PORTC as output (PWM pin RC2)
CCP1CON = 0x0C; // Configure CCP1 in PWM mode
PR2 = 96; // Period register → sets PWM frequency
TMR2 = 0; // Clear Timer2
T2CON = 0x7B; // Start Timer2 with prescaler
pwm_dutycycle(0); // Start with 0% duty cycle
T2CON = 0x7F; // Enable Timer2
}
- PWM output will be on RC2 (CCP1 pin).
PR2+T2CONdetermine the PWM frequency.CCP1CON = 0x0C→ Enables PWM mode.
Main Function
void main()
{
pwm_init(); // Initialize PWM
while(1)
{
if(RB0) pwm_dutycycle(0); // 0% duty → OFF
if(RB1) pwm_dutycycle(64); // ~25% duty
if(RB2) pwm_dutycycle(128); // ~50% duty
if(RB3) pwm_dutycycle(255); // ~100% duty
}
}
- Reads push buttons on RB0–RB3.
- Each button sets a different PWM duty cycle.
- The PWM output can control LED brightness / motor speed / buzzer tone.