Project 1 - Controlling a DC motor using PWM and monitoring its Running status
Overview of the Project:
Implement a system on the simulator for controlling a DC motor using L293 motor driver, monitor its status and print the running status of motor on the LCD Display.
Goals:
- Implement a system on simulator for Controlling the DC motor using L293 motor driver.
- Displaying the running status of DC motor on the LCD display.
program:
#include <avr/io.h> //we are using the i/o register of Avr
#define F_CPU 16000000L //define CPU frequency
#include <util/delay.h> //delay function
#include "avr/interrupt.h" //we are using External interrupt frequency
#define lcdport PORTC //PORTC AS LCD, MACRO
#define rs_high() PORTD |= (1<<6); //D6 logical high
#define rs_low() PORTD &= ~(1<<6); //D6 logical low
#define en_high() PORTD |= (1<<5); //D5 logical high
#define en_low() PORTD &= ~(1<<5); //D5 logical low
#define direction (PIND & (1<<1))
#define power_button (PIND & (1<<4))
#define speed (PIND & (1<<2))
unsigned char c; //variable Declared to increase the duty cycle
void lcd_cmd (unsigned char cmd)
{
lcdport=cmd;
rs_low(); //command register selected
en_high();
_delay_ms(1);
en_low();
}
void lcd_data (unsigned char data)
{
lcdport=data;
rs_high(); //data register selected
en_high();
_delay_ms(1);
en_low();
}
void lcd_init()
{
lcd_cmd(0x38);
_delay_ms(5);
lcd_cmd(0x02); //return home
_delay_ms(5);
lcd_cmd(0x01);//clear screen
_delay_ms(5);
lcd_cmd(0x0c);//display ON cursor OF
_delay_ms(5);
lcd_cmd(0x06);// increment cursor
_delay_ms(5);
lcd_cmd(0x80);//first line
_delay_ms(5);
}
void cursor_pos(char x, char y)//x-row,y-col
{
if((x<1||x>2)||(y<1||y>16))//any typo mistakes
{
x=1;
y=1;
}
if (x==1) //0x80 -1,1 1,2-0x81 1,3-0x82.....
{
lcd_cmd(0x7F+y);//7F+2
}
else //0xC0
{
lcd_cmd(0xBF+y);//BF+5=C4
}
}
void lcd_out(char x, char y, char *str)
{
cursor_pos(x,y);//2,5
while(*str)
{
lcd_data(*str);
str++;
}
}
int main(void)
{
/* Replace with your application code */
DDRC = 0xFF; //declaring all C pins are output
DDRB = 0xFF;
PORTB = 0xFF;
DDRA |= (1<<0) | (1<<1);//declaring A0 A1 pins are output
DDRD &=~ (1<<4);//declaring D4 pins as input
DDRD &=~ (1<<1);//declaring D1 pins as input
DDRD |= (1<<5)|(1<<6);//declaring D5 D6 pins are output
PORTD |= (1<<1);// to enable pull up for direction button
PORTD |= (1<<4);// to enable pull up for power button
PORTD |= (1<<3); // to enable pull up for interrupt
sei();//Enable global interrupt
GICR |= (1<<7);//using interrupt
c = 64;//initializing c=64 because we are running the motor with 25% of duty cycle
TCCR0 = 0x64;//non inverting mode,PWM phase correct mode,no Prescalars
MCUCR = 0x80;//make interrupt negative edge triggered
lcd_init(); //initialize lcd
while(1)
{
while(power_button == 0)//continue till the power push button is released
{
if(direction == 0)//if the direction control push button is released
{
PORTA = 0x01;//01 to respective 1A 2A pins to rotate in clockwise direction
lcd_out(1,1,"Motor running in");
_delay_ms(5);
lcd_out(2,1," Clockwise");
}
else
{
PORTA = 0x02;//02 to respective 1A 2A pins to rotate in aunticlockwise direction
lcd_out(1,1,"Motor running in");
_delay_ms(5);
lcd_out(2,1," Anti-clockwise");
}
OCR0 = c;
}
PORTA = 0x00;//00 to respective pins to stop rotation
lcd_out(1,1,"Motor is OFF");
}
}
ISR(INT1_vect)//interrupt service routine
{
c = c + 25;
}
output:
motor is "OFF "Condition

"Motor running in clockwise"

"Motor running in Anticlockwise"
