Friday, February 5, 2016

DC Motor speed controller using PIC12F1822 microcontroller

DC Motor speed control using PWM technique

Using PWM (Pulse Width Modulation) it is easy to control the speed of DC motor by varying duty cycle of the PWM signal. When the duty cycle is varied, the power delivered to the motor is also varied which yields speed variation. When the duty cycle is 0, the motor has no move, and when the duty cycle is 100% the motor rotates at full speed.
PIC12F1822 is equipped with PWM module and it can generate a PWM signal on pin RA2 or RA5 according to its configuration, in this project the pin RA2 is responsible for generating the PWM signal (by default).
DC motor speed control circuit:

dc motor speed control pic microcontroller mikroc code

The N type mosfet IRF3205S can be replaced with different types of N mosfets, but you have to be careful about the motor characteristics and the mosfet.
The potentiometer connected to RA0 controls the speed of the motor which means PWM duty cycle is affected by the analog reading on pin RA0.
The internal oscillator of the microcontroller is used (8MHz) and MCLR pin function is disabled.
The diode which is connected in parallel with the motor is used to protect the circuit from reversed current comes from the motor.
DC Motor speed controller mikroC code:
This is the mikroC code of this project where the PWM frequency is 1000Hz.
Timer1 is used to interrupt every 100ms for analog reading which means we have 1 analog reading every 100ms.

 * DC motor speed control with PIC12F1822
 * Speed controlled from potentiometer connected
   on RA0.
 * Timer1 interrupts every 100ms for analog reading.
 * Written by: BENCHEROUDA Okba
 * E-mail:
 * Website:
 * Internal oscillator used at 8MHz

 unsigned int i;
 void Interrupt(){
  if (TMR1IF_bit){
    TMR1IF_bit = 0;
    TMR1H         = 0x3C;
    TMR1L         = 0xB0;
    if(i != ADC_Read(0)){
     i = ADC_Read(0);
     PWM1_Set_Duty((i >> 2)) ;
 void main() {
  OSCCON = 0x70; // Internal oscillator 8MHz
  ANSELA = 1;    // Configure AN0 pin as analog
  // Initialize Timer1 to Interrupt every 100ms
  T1CON         = 0x21;
  TMR1IF_bit    =    0;
  TMR1H         = 0x3C;
  TMR1L         = 0xB0;
  TMR1IE_bit    =    1;
  INTCON        = 0xC0;
  // End Timer1 initialization
  PORTA = 0;     // Initial value of port A bits
  TRISA = 1;
  while(1);  // Endless loop

The following video shows this project in circuit hardware: