Small DC Motor Control by PWM Method Using Atmega8
Small DC Motor Control by PWM Method Using Atmega8
Small DC Motor Control by PWM Method Using Atmega8
Atmega8 Microcontroller
BY CC Dharmani, www.dharmanitech.com
Hi Friends,
Here I’m discussing DC motor control using the PWM counters of AVR ATmega8
microcontroller. I had used a DC motor from an old personal stereo cassette player. The circuit
provides speed and direction control of the motor. The PWM waveforms are used for driving the
MOSFET H-bridge as shown in the schematic:
At a time only one of the two PWM channel is active, driving only two MOSFETS (either
Q1-Q4 or Q3-Q2). Other two MOSFETs remain OFF. Whenever the Direction Control switch is
toggled, the PWM channel is also changed, driving the alternative pair of MOSFET, which
changes the direction of current flow through motor, resulting in the direction change in rotation
of motor shaft.
Code:
//********************************************************
// *********** PWM DC MOTOR CONTROL *************
//********************************************************
//Controller : ATmega8 (1MHz internal Crystal)
//Compiler : ICCAVR
//Author : CC Dharmani, Chennai(India)
//Date : Nov 2008
//********************************************************
#include <iom8v.h>
#include <macros.h>
//defining macros for setting minimum and maximum PWM counter values
//and step-size for controlling the voltage applied to MOSFETs base
#define COUNTER_LOWER_LIMIT 0x0090
#define COUNTER_UPPER_LIMIT 0x00f8
#define STEP_SIZE 0x0008
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x06; //PWM pins OC1A & OC1B defined as outputs
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0xE0; //internal pull-up enabled for three pins connected to switches
DDRD = 0x00;
}
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
for(i=0;i<miliSec;i++)
for(j=0;j<100;j++)
{
asm("nop");
asm("nop");
}
}
void main(void)
{
unsigned int counter = COUNTER_LOWER_LIMIT;
unsigned char dir = 0, dir1 = 0;
init_devices();
while(1)
{
CHECK_PB:
while(increaseButton_OPEN && decreaseButton_OPEN)
{ //loop here until any push-button is pressed
if(DIRECTION_FORWARD) //check for Direction control switch status
dir = 0;
else
dir = 1;
if(dir != dir1) //chenge direction if switch position has changed
{
STOP_MOTOR;
delay_ms(500);
if(dir == 0)
set_FORWARD;
else
set_REVERSE;
START_MOTOR;
dir1 = dir;
}
}
OCR1A = counter;
OCR1B = counter;
}
else //speed-decrease push-button is pressed
{
delay_ms(20); //key debouncing delay after key-pressed
if(decreaseButton_OPEN) goto CHECK_PB;
while(decreaseButton_PRESSED); //wait here till the push-button is kept pressed
delay_ms(20); //key debouncing delay after key released
OCR1A = counter;
OCR1B = counter;
}
}
}
//****************************** END ***************************************
//********** CC Dharmani, www.dharmanitech.com ****************