@▷ PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8 | Diagram for Schematic

PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8

PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8



 

PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8

 


Here is a very simple project of controlling a small DC-motor (taken from an old personal cassette player) with ATmega8. The ATmega8 is having three PWM channels, out of which two are used here. PWM waveforms are fed to MOSFET (RFD3055) H-bridge. Here, direction is controlled using a two-position toggle switch and speed of the motor is controlled by two push-buttons, one for increasing the speed and other for reducing. The schematic is geiven here (click on the image to enlarge): When switch SW1 is closed, OC1A channel is active which will feed the PWM signal to Q1 & Q4 MOSFETs. The OC1B pin will remain low keeping the Q3 & Q2 in OFF condition. When SW1 is toggled to open position, OC1A pin will become low, making Q1 & Q4 OFF and OC1B will feed the PWM signal to Q3 & Q2, resulting in the change in the direction of current flow through motor. Hence, motor rotation direction will change. The speed is controlled by Push-buttons S2 & S3. Pressing S2 will increase the speed in fixed steps. Similarly, pressing S3 will reduce the speed in fixed steps.


PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8

Here on the bread-board, I've used two push-buttons but the direction control switch is replaced by a small wire which was connected to ground or kept open for changing the direction (since I was not having the toggle switch in stock at the moment). The bread-board also includes 6-pin In-System Programming connector which is not shown in the schematic.

(The InSystemProgramming (ISP) connector is shown in my earlier posts, hence omitted here!! But, if you are new to ISP, refer to my post DIY AVR Programmers to make one yourself!!)

Code for this PWM motor control:

Code:

//********************************************************
// *********** PWM DC MOTOR CONTROL *************
//********************************************************
//Controller : ATmega8 (1MHz internal Crystal)
//Compiler : ICCAVR
//Date : Nov 2008
//********************************************************

#include
#include

#define increaseButton_PRESSED !(PIND & 0x40)
#define increaseButton_OPEN (PIND & 0x40)
#define decreaseButton_PRESSED !(PIND & 0x80)
#define decreaseButton_OPEN (PIND & 0x80)
#define DIRECTION_FORWARD !(PIND & 0x20)
#define DIRECTION_REVERSE (PIND & 0x20)
#define STOP_MOTOR TCCR1B = 0x00; TCCR1A = 0x00
#define START_MOTOR TCCR1B = 0x09
#define set_FORWARD TCCR1A = 0x81
#define set_REVERSE TCCR1A = 0x21

//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;
}

//TIMER1 initialize - prescale:1
//PWM Frequency: 1KHz
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFC; //setup
TCNT1L = 0x18;
OCR1A = COUNTER_LOWER_LIMIT;
OCR1B = COUNTER_LOWER_LIMIT;
ICR1H = 0x03;
ICR1L = 0xE8;
TCCR1A = 0x81; //set forward; OC1A connected, OC1B disconnected
TCCR1B = 0x09; //start Timer
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer1_init();

MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}


//***** FUNCTION FOR SOFTWARE DELAY OF 1 mSEC (appx.) *******

void delay_ms(int miliSec) //for 1 Mhz crystal
{
int i,j;

for(i=0;ifor(j=0;j<100;j++)
{
asm("nop");
asm("nop");
}
}

//************************ main ***************************

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;
}
}

if(increaseButton_PRESSED) //Speed-increase push-button is pressed
{
delay_ms(20); //key debouncing delay after key-pressed
if(increaseButton_OPEN) goto CHECK_PB;
while(increaseButton_PRESSED); //wait here till the push-button is kept pressed
delay_ms(20); //key debouncing delay after key released

if(counter >= COUNTER_UPPER_LIMIT) //if speed is already maximum, no action
counter = COUNTER_UPPER_LIMIT;
else
counter += STEP_SIZE; //increase speed by a fixed step

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

if(counter <= COUNTER_LOWER_LIMIT) //if speed is already minimum, no action
counter = COUNTER_LOWER_LIMIT;
else
counter -= STEP_SIZE; //reduce speed by a fixed step

OCR1A = counter;
OCR1B = counter;
}

}
}
//****************************** END ***************************************



PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8



PWM Motor Driver with MOSFET H-Bridge and AVR ATmega8



Advertiser