Project 1 - Controlling a DC motor using PWM and monitoring its Running status
Components:
- L293D Motor Driver IC: For driving the DC motor.
- PWM (Pulse Width Modulation): To control the speed of the motor.
- LCD Display: To display the running status of the motor.
Code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h" // Include your LCD library header file
#define MOTOR_FORWARD_PIN1 PD0
#define MOTOR_FORWARD_PIN2 PD1
#define MOTOR_PWM_PIN PD2
void pwm_init(void) {
// Set Timer0 to Fast PWM mode
TCCR0A = (1 << COM0A1) | (1 << WGM00) | (1 << WGM01); // Fast PWM, non-inverted
TCCR0B = (1 << CS00); // No prescaling
// Set PWM frequency
// TOP value for Fast PWM mode is 255
OCR0A = 128; // 50% duty cycle to start with
}
void motor_init(void) {
// Set MOTOR_FORWARD_PIN1, MOTOR_FORWARD_PIN2, and MOTOR_PWM_PIN as outputs
DDRD = (1 << MOTOR_FORWARD_PIN1) | (1 << MOTOR_FORWARD_PIN2) | (1 << MOTOR_PWM_PIN);
// Initial state (Motor stopped)
PORTD &= ~((1 << MOTOR_FORWARD_PIN1) | (1 << MOTOR_FORWARD_PIN2));
}
void lcd_init(void) {
// Initialize LCD (Assuming an initialization function from lcd.h)
lcd_init();
}
void lcd_display_status(const char *status) {
// Clear the LCD and display the status
lcd_clear();
lcd_set_cursor(0, 0);
lcd_print(status);
}
void set_motor_direction(int forward) {
if (forward) {
PORTD |= (1 << MOTOR_FORWARD_PIN1);
PORTD &= ~(1 << MOTOR_FORWARD_PIN2);
lcd_display_status("Motor Forward");
} else {
PORTD |= (1 << MOTOR_FORWARD_PIN2);
PORTD &= ~(1 << MOTOR_FORWARD_PIN1);
lcd_display_status("Motor Reverse");
}
}
void change_pwm_duty_cycle(uint8_t duty_cycle) {
OCR0A = duty_cycle;
}
int main(void) {
pwm_init();
motor_init();
lcd_init();
while (1) {
// Example: Set motor forward with 75% speed
set_motor_direction(1);
change_pwm_duty_cycle(191); // 75% duty cycle
_delay_ms(2000);
// Set motor reverse with 50% speed
set_motor_direction(0);
change_pwm_duty_cycle(128); // 50% duty cycle
_delay_ms(2000);
// Stop the motor
PORTD &= ~((1 << MOTOR_FORWARD_PIN1) | (1 << MOTOR_FORWARD_PIN2));
lcd_display_status("Motor Stopped");
_delay_ms(2000);
}
return 0;
}