Summary of PIC12F675 PWM Code and Proteus Simulation
This article provides C code (MPLAB with HI-TECH C) to generate PWM on a PIC12F675 using Timer0 interrupts. It explains initializing Timer0, using an ISR to toggle GP0 and load Timer0 with values based on a global PWM variable (0–255) to set duty cycle, and configuring ADC/comparator off so GP0 is digital. Example: 4 MHz internal oscillator yields ~1.8 kHz PWM at PWM=127 (50%). Frequency can be changed via CPU clock or Timer0 prescaler. A download link for code and Proteus simulation is provided.
Parts used in the PIC12F675 PWM Project:
- PIC12F675 microcontroller
- DC motor (example load)
- DC motor driver circuitry (required between PIC and motor)
- Power supply (for PIC and motor/driver)
- Optional external crystal (up to 20 MHz) or internal 4 MHz oscillator
- Development tools: MPLAB v8.85
- Compiler: HI-TECH C v9.83
- Simulation software: Proteus v7.10
This post provides the PWM code for PIC12F675 microcontroller using timer0. There are many uses for PWM signal, e-g you can control dc motor speed using PWM. Timer0 is initialized in the start of the main function and using timer0 interrupts, PWM is generated.
This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
It is assumed that you know how to configure timer0 of PIC12F675 microcontroller. If you don’t then please read this page first, before proceeding with this article.
The result of simulating the code in Proteus is shown below.
Here PIC12F675 is running on 4MHz internal oscillator. A PWM wave of 1.8KHz frequency with 50% duty cycle is being generated as shown in the above figure. GP0 pin is being used as PWM_PIN, which you can easily change in the code. Also, you can change PWM duty cycle in the code at any time as well.
Code
The code used to initialize PWM is shown below.
In this InitPWM() function, timer0 is initialized with it’s interrupts enabled. Rest of the PWM generation code is written inside timer0 interrupt service routine code, which is shown below.
Whenever timer0 expires and an interrupt is generated, then interrupt ISR() function is executed. In this function, depending upon the state of the PWM_PIN (i-e if it is high or low), timer0 register is loaded with appropriate value. There is a global variable with the name of PWM defined in the code. This variable can have a value from 0 (0% duty cycle) to 255 (100% duty cycle). You can change PWM variable in the main function and it will automatically change the duty cycle of the PWM wave. So, in the ISR code shown above, depending upon the value of PWM variable, proper value is loaded in timer0 register to indicate when it is going to expire again and toggle GP0 pin value.
The main function code is shown below.
In the main function, firstly ADC and comparator both are turned off to make GP0 pin a digital IO pin. Then PWM is initialized using InitPWM() function. After that, PWM variable is assigned a value of 127, which corresponds to a duty cycle of 50% (as shown in figure 1). You can change duty cycle of PWM by just changing the value of PWM variable.
You can change PWM frequency by changing the CPU frequency of PIC12F675 microcontroller. In other words, currently I am using internal oscillator of 4MHz value which generates a PWM frequency of 1.8KHz. But you can use external crystal of upto 20MHz value to generate a maximum PWM frequency of 9KHz. Also, you can change PWM frequency by changing the frequency Pre-Scalar of timer0 in the code.
This code is intended to be a simple example of how you can generate PWM using PIC12F675 microcontroller. As an example, You can use this PWM code to control dc motor with PIC12F675 controller. You will need some sort of dc motor driver circuitry in between PIC12F675 controller and the dc motor. Other than that, using this simple PWM controlling code, you can control dc motor speed with PIC12F675 controller easily.
You can leave your comments in the comment section below.
Downloads
PWM code using PIC12F675 was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
Further Reading Suggestions
Source: PIC12F675 PWM Code and Proteus Simulation
- How is PWM generated in this project?
PWM is generated using Timer0 interrupts; the ISR toggles GP0 and reloads Timer0 based on the PWM variable. - Which pin is used for PWM output?
GP0 pin is used as the PWM_PIN in the example. - How do you set the PWM duty cycle?
By assigning a value 0 to 255 to the global PWM variable; 0 is 0% and 255 is 100% duty cycle. - What oscillator and PWM frequency are used in the example?
The example uses the 4 MHz internal oscillator producing about 1.8 kHz PWM frequency with PWM=127 (50%). - Can PWM frequency be changed?
Yes; change the CPU frequency (e.g., use up to a 20 MHz crystal) or change Timer0 prescaler in the code. - Do you need additional hardware to drive a DC motor?
Yes; you need motor driver circuitry between the PIC12F675 and the DC motor. - What must be turned off to use GP0 as digital IO?
ADC and comparator must be turned off to make GP0 a digital IO pin. - Which tools were used to compile and simulate the code?
The code was compiled in MPLAB v8.85 with HI-TECH C v9.83 and simulated in Proteus v7.10.