Project 1 - Controlling a DC motor using PWM and monitoring its Running status
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 16000000UL
// Define motor control pins
#define MOTOR_PORT PORTD
#define out1 (1 << PD2)
#define out2 (1 << PD3)
// LCD control pins
#define LCD_PORT PORTB
#define RS (1 << PD0)
#define EN (1 << PD1)
void motor(int a, int value)
{
OCR0A = (256 / 100) * value;
if (a == 1)
{
MOTOR_PORT |= out1;
MOTOR_PORT &= ~out2;
}
else if (a == -1)
{
MOTOR_PORT |= out2;
MOTOR_PORT &= ~out1;
}
else
{
MOTOR_PORT &= ~(out1 | out2);
}
}
void motor_timer0()
{
DDRD |= out1 | out2;
TCCR0A = (1 << 0) | (1 << 1) | (1 << 7) | (1 << 6);
TCCR0B = (1 << 0);
OCR0A = 50;
motor(0, 100);
}
void lcd_cmd(char cmd)
{
LCD_PORT = cmd;
PORTD &= ~RS;
PORTD |= EN;
_delay_ms(1);
PORTD &= ~EN;
}
void lcd_data(char data)
{
LCD_PORT = data;
PORTD |= RS;
PORTD |= EN;
_delay_ms(1);
PORTD &= ~EN;
}
void lcd_init()
{
lcd_cmd(0x38);
_delay_ms(5);
lcd_cmd(0x02);
_delay_ms(5);
lcd_cmd(0x01);
_delay_ms(5);
lcd_cmd(0x0C);
_delay_ms(5);
lcd_cmd(0x06);
_delay_ms(5);
lcd_cmd(0x80);
_delay_ms(5);
}
void cursorpos(char x, char y) {
if ((x < 1 || x > 2) || (y < 1 || y > 16))
{
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)
{
cursorpos(x, y);
while (*str)
{
lcd_data(*str);
str++;
}
}
void display_motor_status(int direction)
{
lcd_cmd(0x01);
lcd_cmd(0x80);
lcd_out(1, 1, "Motor Status");
if (direction == 1)
{
lcd_out(2, 1, "Clockwise");
}
else if (direction == -1)
{
lcd_out(2, 1, "Anti-clockwise");
}
else
{
lcd_out(2, 1, "Stopped");
}
}
int main(void)
{
DDRB = 0xff;
DDRD =0xff;
DDRC = 0x00;
PORTC = 0xff;
lcd_init();
motor_timer0();
int pwm = 64;
int motor_direction = 0;
while (1)
{
if ((PINC & (0b00000001)) == 0)
{
motor_direction = 1;
motor(1, pwm);
display_motor_status(motor_direction);
lcd_out(1, 1, "Motor Direction");
lcd_out(2, 1, "Clockwise");
_delay_ms(250);
}
if ((PINC & (0b00000010)) == 0)
{
motor_direction = -1;
motor(-1, pwm);
display_motor_status(motor_direction);
lcd_cmd(0x01);
lcd_out(1, 1, "Motor Direction");
lcd_out(2, 1, "Anti-clockwise");
_delay_ms(250);
}
if ((PINC & 0b00000011) == 0b00000011)
{
motor_direction = 0;
motor(0, pwm);
display_motor_status(motor_direction);
_delay_ms(250);
}
}
return 0;
}
output:-

