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

