Challenge

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

#ifndef F_CPU

#define F_CPU 8000000UL // 8MHz clock speed

#endif

#include <avr/io.h>

#include <util/delay.h>

// Define motor control pins

#define MOTOR_EN PB3 // Enable pin for PWM (OC0)

#define MOTOR_IN1 PD2 // Control pin 1

#define MOTOR_IN2 PD3 // Control pin 2

// Define LCD control pins

#define RS PC0

#define RW PC1

#define E PC2

// Define LCD data pins

#define D4 PC4

#define D5 PC5

#define D6 PC6

#define D7 PC7

void LCD_Command(unsigned char cmnd) {

PORTC = (PORTC & 0x0F) | (cmnd & 0xF0); // Sending upper nibble

PORTC &= ~(1 << RS); // RS = 0 for command

PORTC &= ~(1 << RW); // RW = 0 for write

PORTC |= (1 << E); // Enable pulse

_delay_us(1);

PORTC &= ~(1 << E);

_delay_us(200);

PORTC = (PORTC & 0x0F) | (cmnd << 4); // Sending lower nibble

PORTC |= (1 << E); // Enable pulse

_delay_us(1);

PORTC &= ~(1 << E);

_delay_ms(2);

}

void LCD_Char(unsigned char data) {

PORTC = (PORTC & 0x0F) | (data & 0xF0); // Sending upper nibble

PORTC |= (1 << RS); // RS = 1 for data

PORTC &= ~(1 << RW); // RW = 0 for write

PORTC |= (1 << E); // Enable pulse

_delay_us(1);

PORTC &= ~(1 << E);

_delay_us(200);

PORTC = (PORTC & 0x0F) | (data << 4); // Sending lower nibble

PORTC |= (1 << E); // Enable pulse

_delay_us(1);

PORTC &= ~(1 << E);

_delay_ms(2);

}

void LCD_Init(void) {

DDRC = 0xFF; // Make all pins of PORTC output

_delay_ms(20); // LCD power on delay

// Initialization sequence

LCD_Command(0x02); // 4-bit mode

LCD_Command(0x28); // 2 lines, 5x7 matrix

LCD_Command(0x0C); // Display on, cursor off

LCD_Command(0x06); // Increment cursor

LCD_Command(0x01); // Clear display

_delay_ms(2);

}

void LCD_String(const char *str) {

while (*str) {

LCD_Char(*str++);

}

}

void LCD_Clear(void) {

LCD_Command(0x01); // Clear display

_delay_ms(2);

LCD_Command(0x80); // Cursor to home position

}

void PWM_init()

{

/* Set fast PWM mode with non-inverted output */

TCCR0 = (1<<WGM00) | (1<<WGM01) | (1<<COM01) | (1<<CS00);

DDRB |= (1<<MOTOR_EN); /* Set OC0 pin as output */

}

void motor_init()

{

/* Set MOTOR_IN1 and MOTOR_IN2 as outputs */

DDRD |= (1<<MOTOR_IN1) | (1<<MOTOR_IN2);

/* Initialize motor to stop state */

PORTD &= ~((1<<MOTOR_IN1) | (1<<MOTOR_IN2));

}

void motor_control(uint8_t duty_cycle, uint8_t direction)

{

/* Set motor direction */

if (direction == 1) {

PORTD |= (1<<MOTOR_IN1);

PORTD &= ~(1<<MOTOR_IN2);

} else if (direction == 0) {

PORTD &= ~(1<<MOTOR_IN1);

PORTD |= (1<<MOTOR_IN2);

} else {

PORTD &= ~((1<<MOTOR_IN1) | (1<<MOTOR_IN2)); /* Stop */

}

/* Set motor speed (duty cycle) */

OCR0 = duty_cycle;

}

int main ()

{

unsigned char duty;

PWM_init();

motor_init();

LCD_Init();

while (1)

{

/* Increase speed from 0% to 100% */

LCD_String("Forward direction");

for (duty = 0; duty < 255; duty++)

{

motor_control(duty, 1); /* Forward direction */

_delay_ms(8); /* Adjust for smoother transition */

}

/* Run at full speed for a while */

_delay_ms(2000);

LCD_Clear();

/* Decrease speed from 100% to 0% */

LCD_String("Forward direction");

for (duty = 255; duty > 0; duty--)

{

motor_control(duty, 1); /* Forward direction */

_delay_ms(8); /* Adjust for smoother transition */

}

/* Pause for a while before reversing */

_delay_ms(2000);

LCD_Clear();

/* Increase speed from 0% to 100% in reverse */

LCD_String("Reverse direction");

for (duty = 0; duty < 255; duty++)

{

motor_control(duty, 0); /* Reverse direction */

_delay_ms(8); /* Adjust for smoother transition */

}

/* Run at full speed in reverse for a while */

_delay_ms(2000);

LCD_Clear();

/* Decrease speed from 100% to 0% in reverse */

LCD_String("Reverse direction");

for (duty = 255; duty > 0; duty--)

{

motor_control(duty, 0); /* Reverse direction */

_delay_ms(8); /* Adjust for smoother transition */

}

/* Pause before repeating the cycle */

_delay_ms(2000);

LCD_Clear();

}

return 0;

}

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.