Challenge

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

#define F_CPU 16000000UL // Define CPU Frequency

#define MOTOR_ENABLE_PIN PA2

#define MOTOR_DIRECTION_PIN_1 PA0

#define MOTOR_DIRECTION_PIN_2 PA1

#define LCD_DATA_PORT PORTB

void lcd_cmd(unsigned char cmd) {

LCD_DATA_PORT = cmd;

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

PORTD |= (1 << 2); // EN high

_delay_ms(1);

PORTD &= ~(1 << 2); // EN low

}

void lcd_data(unsigned char data) {

LCD_DATA_PORT = data;

PORTD |= (1 << 0); // RS high for data

PORTD |= (1 << 2); // EN high

_delay_ms(1);

PORTD &= ~(1 << 2); // EN low

}

void lcd_init() {

_delay_ms(50);

lcd_cmd(0x38); // Initialization of 16x2 LCD in 8-bit mode

_delay_ms(5);

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

_delay_ms(5);

lcd_cmd(0x01); // Clear display

_delay_ms(5);

lcd_cmd(0x06); // Auto-increment cursor

_delay_ms(5);

lcd_cmd(0x80); // Set cursor at home position

_delay_ms(5);

}

void lcd_clear() {

lcd_cmd(0x01); // Send clear display command

_delay_ms(2); // Short delay after sending the command

}

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

if (x == 1) {

lcd_cmd(0x80 + y - 1); // Set cursor position for the first line

} else {

lcd_cmd(0xC0 + y - 1); // Set cursor position for the second line

}

while (*str != '\0') {

lcd_data(*str);

str++;

}

}

void setup() {

DDRA |= (1 << MOTOR_ENABLE_PIN) | (1 << MOTOR_DIRECTION_PIN_1) | (1 << MOTOR_DIRECTION_PIN_2);

DDRD |= (1 << PD0) | (1 << PD2); // PD0 (RS) and PD2 (EN) as output for LCD

lcd_init();

}

void rotate_clockwise(uint8_t speed) {

PORTA |= (1 << MOTOR_DIRECTION_PIN_1);

PORTA &= ~(1 << MOTOR_DIRECTION_PIN_2);

PORTA |= (1 << MOTOR_ENABLE_PIN);

OCR1A = speed;

lcd_clear();

lcd_out(1, 1, "Clockwise");

}

void rotate_anticlockwise(uint8_t speed) {

PORTA &= ~(1 << MOTOR_DIRECTION_PIN_1);

PORTA |= (1 << MOTOR_DIRECTION_PIN_2);

PORTA |= (1 << MOTOR_ENABLE_PIN);

OCR1A = speed;

lcd_clear();

lcd_out(1, 1, "Anticlockwise");

}

void timer1_PWM_init() {

TCCR1A |= (1 << WGM11) | (1 << COM1A1);

TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10);

ICR1 = 255; //ICR1 to 255 means that the timer will count from 0 to 255 before it resets.

}

int main() {

setup();

timer1_PWM_init();

while (1) {

rotate_clockwise(125);

_delay_ms(15000);

rotate_anticlockwise(125);

_delay_ms(15000);

}

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.