Challenge

Project 1 - Controlling a DC motor using PWM and monitoring its Running status

//AJAY JOSEPH SIR

//ANSWER :

#include <avr/io.h> // Pre-processor directive for I/O registers

#define F_CPU 16000000l // CPU frequency

#include "avr/interrupt.h" // User defined pre-processor directive for interrupts

#include <util/delay.h> // Pre-processor directive for delay functions

#define sw_dir (PIND & (1<<1)) // D1 pin as push button for direction control

#define sw_spd (PIND & (1<<2)) // D2 pin as push button for speed control

#define pw (PINC & (1<<3)) // C3 pin as push button for power ON/OFF

#define lcd_port PORTB // Port B pins used for LCD data

#define RS_high PORTD |= (1<<5) // D5 pin for Register select

#define RS_low PORTD &=~ (1<<5)

#define EN_high PORTD |= (1<<6) // D6 pin for Enable

#define EN_low PORTD &=~ (1<<6)

unsigned char i;

void lcd_cmd(char cmd) // For command register

{

lcd_port = (cmd & 0xF0); // For 4 bit LCD mode

RS_low;

EN_low;

_delay_ms(1);

EN_high;

lcd_port = ((cmd<<4)&(0xF0));

RS_low;

EN_low;

_delay_ms(1);

EN_high;

}

void lcd_data(char data) // For data register

{

lcd_port = (data & 0xF0); // For 4 bit LCD mode

RS_high;

EN_low;

_delay_ms(1);

EN_high;

lcd_port = ((data<<4)&(0xF0));

RS_high;

EN_low;

_delay_ms(1);

EN_high;

}

void lcd_init()

{

lcd_cmd(0x02); // Return cursor to home

_delay_ms(5);

lcd_cmd(0x01); // Clear screen

_delay_ms(5);

lcd_cmd(0x0C); // Display ON, cursor OFF

_delay_ms(5);

lcd_cmd(0x06); // Increment cursor

_delay_ms(5);

lcd_cmd(0x80); // Cursor to begin at the 1st line

_delay_ms(5);

lcd_cmd(0x28); // 4 bit LCD mode

_delay_ms(5);

}

void cursor_position(char x, char y)

{

if ((x<1||x>2)||(y>16||y<1))

{

x = 1;

y = 1;

}

if (x == 1)

{

lcd_cmd(0x7F+y);

}

else

{

lcd_cmd(0xBF+y);

}

}

void lcd_out(char x, char y, char *str)

{

cursor_position(x, y);

while (*str)

{

lcd_data(*str);

str++;

}

}

int main(void)

{

DDRB = 0xFF; // Declaring pins B0 to B7 as outputs

DDRA |= ((1<<0)|(1<<1)); // Declaring pins A0 and A1 as outputs

DDRD &=~ (1<<1); // Declaring D1 pin as input

DDRD &=~ (1<<2); // Declaring D2 pin as input

DDRD |= (1<<5); // Declaring D5 pin as output

DDRD |= (1<<6); // Declaring D6 pin as output

DDRC &=~ (1<<3); // Declaring C3 pin as input

PORTD |= (1<<2); // Internal pull up resistor for D2

PORTC |= (1<<3); // Internal pull up resistor for C3

i = 64; // As motor is running at with 25% duty cycle

TCCR0 = 0x61; // Non-inverting mode, PWM phase correct with no pre-scalars

GICR = (1<<INT0); // INT0 for interrupt

MCUCR = 0x02; // Interrupt is negative edge triggered

sei(); // Global interrupt

lcd_init();

while (1)

{

while (pw == 0) // Continues till the power push button gets released

{

if (sw_dir == 0) // if direction control push button gets released

{

PORTA = 0b00000001; // To rotate in clockwise direction

lcd_out(1,1, "Motor is running");

lcd_out(2,3, "clockwise");

}

else

{

PORTA = 0b00000010; // To rotate in anti clockwise direction

lcd_out(1,1, "Motor is running");

lcd_out(2,3, "anti clockwise");

}

OCR0 = i; // As i increases, the corresponding value is loaded into OCR0

}

PORTA = 0x00; // To stop the rotation

lcd_out(1,1, "Motor is OFF");

lcd_out(2,3, "CAUTION !!!");

}

}

ISR(INT0_vect) // Interrupt service routine

{

i = i + 20; // As i increases, the corresponding value is loaded into OCR0

}

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.