Project 1 - Controlling a DC motor using PWM and monitoring its Running status
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.
CODE
#include <avr/io.h>//AVR preprocessor section
#define F_CPU 16000000UL//frequency of the AVR
#include "avr/interrupt.h"//AVR interrupt preprocessor
#include <util/delay.h>//library for delay
#define sw_dir (PIND&(1<<1))// the pushbutton for direction control of port d1 pin
#define sw_spd (PIND&(1<<2))// the pushbutton for speed control of port d2 pin
#define pw (PINC&(1<<3))// the pin c3 as pushbutton for purpose of power ON/OFF
#define lcd_port PORTB// the port b is used for LCD data
#define RS_high PORTD|=(1<<5)//port d pin 5 used as RS pin of LCD
#define RS_low PORTD&=~(1<<5)
#define EN_high PORTD|=(1<<6)//port d pin 6 used as Enable pin of LCD
#define EN_low PORTD&=~(1<<6)
unsigned char i;//Variable i is used for purpose of PWM duty cycle
void lcd_cmd(char cmd)
{
lcd_port=(cmd&0xf0);// 4 bits for 4 bit LCD mode
RS_low;//register select low
EN_low;//disable
_delay_ms(1);
EN_high;//enable the LCD
lcd_port=((cmd<<4)&(0xf0));
RS_low;
EN_low;
_delay_ms(1);//wait for 1 millisecond
EN_high;
}/*commands for LCD display*/
void lcd_data(char dat)
{
lcd_port=(dat&0xf0);// 4 bits for 4 bit LCD mode
RS_high;//register select high
EN_low;
_delay_ms(1);//wait for 1 millisecond
EN_high;//enable the LCD
lcd_port=((dat<<4)&(0xf0));
RS_high;
EN_low;
_delay_ms(1);
EN_high;
}/*sending the data to LCD*/
void lcd_init()
{
lcd_cmd(0x02);//return home
_delay_ms(5);//wait for 5 milliseconds
lcd_cmd(0x01);//clear screen
_delay_ms(5);
lcd_cmd(0x0c);//display ON cursor OFF
_delay_ms(5);
lcd_cmd(0x06);//Increment the cursor
_delay_ms(5);
lcd_cmd(0x80);//force the cursor from the 1st line
_delay_ms(5);
lcd_cmd(0x28);//used for 4 bit LCD mode
_delay_ms(5);
}/*Function for LCD initialization purpose*/
void cursorpos(char x, char y)
{
if((x<1||x>2)||(y>16||y<1))//condition for the 2 rows and 16 columns
{
x=1;
y=1;
}//x=row and y=column
if(x==1)
lcd_cmd(0x7f+y);//for starting the 1st line hex decimal and y for column
else
lcd_cmd(0xBF+y);//for 2nd line 2nd column
}//function for cursor position
void lcd_out(char x, char y, char *str)
{
cursorpos(x,y);//cursor position function
while(*str)
{
lcd_data(*str);
str++;
}
}//function for the LCD output
int main(void)
{
DDRB|=0Xff;//configuring the port d all pins as the output
DDRA|=((1<<0)|(1<<1));//port a ADC pins 0 and 1 used as output pins
DDRD&=~(1<<1);//configuring the port d pin 1 as input
DDRD&=~(1<<2);//configuring the port d pin 1 as input
DDRD|=(1<<5);//configuring the port d pin 5 as the output
DDRD|=(1<<6);//configuring the port d pin 6 as the output
DDRC&=~(1<<3);//configuring the port c pin 3 as the output
PORTD|=(1<<2);// Internal pull_resistor enabled of port d pin2
PORTC|=(1<<3);// Internal pull_resistor enabled of port c pin3
i=64;//24% duty cycle value from 256 maximum value for running the DC motor
TCCR0=0X61;//Non_inverting mode,PWM phase correct mode, NO pre scalar
GICR=(1<<INT0);//using general interrupt control register INT0 and setting the high
MCUCR=0X02;//make negative edge trigger
sei();//enable the global interrupt
lcd_init();//calling the lcd_init function
while (1)
{
while(pw==0)
{
if(sw_dir==0)
{
PORTA=0b00000001;//1 0 to 1A and 2A pins to rotate in clockwise
lcd_out(1,1,"Motor is Running");//displays at 1st row 1st column
lcd_out(2,3,"Clockwise");//displays at 2nd row 3rd column
}
else
{
PORTA=0b00000010;//0 1 to 1A and 2A pins to rotate in anticlockwise
lcd_out(1,1,"Motor is Running");//displays at 1st row 1st column
lcd_out(2,3,"anticlockwise");//displays at 2nd row 3rd column
}
OCR0=i;//output control register loads the interrupt ISR value
}
PORTA=0X00;//0 0 to 1A and 2A pins to stop rotating
lcd_out(1,1," Motor is OFF ");//displays at 1st row 1st column
lcd_out(2,3,"WARNING ");//displays at 2nd row 3rd column
}
}
ISR(INT0_vect)//interrupt service routine INT0 is accessing
{
i=i+20;//it increases the duty cycle and that value stores in the OCR0
}
