Challenge

Project 1 - Controlling a DC motor using PWM and monitoring its Running status

AIM:

  • 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:

/*
 * project-1.c
 *
 * Created: 26-05-2022 15:25:49
 * Author : prave
 */ 

#include <avr/io.h>//we are using I/O registers of AVR	
#define F_CPU 16000000L//define the crystal frequency
#include <avr/interrupt.h>//we are using external interrupt pin
#include <util/delay.h>//delay function purpose
#define SW_dir (PIND&(1<<1))//d1 pin is declared as push button for direction control
#define SW_dspd (PIND&(1<<2))//d2 pin is declared as push button for speed control
#define PW (PINC&(1<<3))//c3 is declared as push button for power ON/OFF
#define lcd_port PORTB//portB pins declared or LCD data
#define RS_high PORTD|=(1<<5)//d5 pin is used for reg select(RS)
#define RS_low PORTD&=~(1<<5)//d5 pin is used for rs
#define EN_high PORTD|=(1<<6)//d6 pin as declared Enable
#define EN_low PORTD&=~(1<<6)//d6 pin is used for en
unsigned char i;
void lcd_cmd(char cmd)//command for lcd display
{
	lcd_port=(cmd&0xf0);//4bits lcd mode
	RS_low;
	EN_low;
	_delay_ms(1);//after 1ms disable lcd
	EN_high;//enable the lcd 
	lcd_port=((cmd<<4)&(0xf0));//lcd port
	RS_low;
	EN_low;
	_delay_ms(1);//after 1ms disable lcd
	EN_high;//enable the lcd
}
void lcd_data(char data)//send the data to lcd
{
	lcd_port=(data&0xf0);//4bits lcd mode
	RS_high;//access data register
	EN_low;
	_delay_ms(1);
	EN_high;
	lcd_port=((data<<4)&(0xf0));//4bits lcd mode
	RS_high;//access data register
	EN_low;
	_delay_ms(1);
	EN_high;
}
void lcd_init()
{
	lcd_cmd(0x28);//4bits lcd mode
	_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 off
	_delay_ms(5);
	lcd_cmd(0x06);//increment brightness the display cursor
	_delay_ms(5);
	lcd_cmd(0x80);//force cursor to begin fron 1st line
	_delay_ms(5);
}
void cursorpos(char x,char y)
{
	if ((x<1||x>2)||(y>16||y<1))//condition to checks the 2rows and 16 columns
	{
		x=1;
		y=1;
	}
	if (x==1)
	{
		lcd_cmd(0x7F + y);//{80-1}for starting the 1st line hex decimal value (80){y we are using the 7f+y means need to start from the column}
	}
	
	else//(x==2)
	{
		lcd_cmd(0xBF + y);//{0C-1=0B}for starting the 2nd line ,2nd row.
	}
}
void lcd_out(char x,char y,char *str)//here we checking which position we want to print
{
	cursorpos(x,y);
	while (*str)
	{
		lcd_data(*str);
		str++;
	}
}
int adc_read(char channel)// we are configuring the adc value
{
	unsigned int a,result;
	ADMUX=channel;//here we are going to use which channel we need to select in mux here using 2 bit
	ADCSRA=0x80;//control & status register to enable the adc conversation in mux here using 2 bit
	ADCH=0x00;//showing the value 0 or clearing the adc register
	ADCL=0x00;//showing the value 0
	ADCSRA|=(1<<6);//to start the conversation 6th bit adsc high
	while((ADCSRA&0x40)!=0);//when the conversation becomes zero means conversation of adc interrupted pin
	a=ADCL;//dummy data type a and ais stored the ADCL register(ADC0-ADC7)
	result=ADCH;//stored the high value(ADC8-ADC9)
	result=result<<8;//to get proper result or alined value we need to do left shift
	result=result|a;//we r adding the ADCL+ADCH to get the 16bits 
	return result;
}
int main(void)
{
	DDRB=0xFF;//Declaring all 8-pins are O/P
	DDRA|=((1<<0)|(1<<1));//Declaring A0 & A1 pins as O/P
	DDRD&=~(1<<1);//Declaring D1 pin as I/P
	DDRD&=~(1<<2);//Declaring D2 pin as I/P
	DDRD|=(1<<5);//Declaring D5 pin as O/P
	DDRD|=(1<<6);//Declaring D6 pin as O/P
	DDRC&=~(1<<3);//Declaring C6 pin as I/P
	PORTD|=(1<<2);//EN internal pull up reg for D2
	PORTC|=(1<<3);//EN internal pull up reg for C3
	i=64;//i=64,we are running the motor with 25% duty cycle
	TCCR0=0x61;//non- inverting mode,PWM phase correct mode,NO prescalar
	GICR=(1<<INT0);//using INT0 for interrupt
	MCUCR=0x02;//make interrupt negative edge triggered
	sei();//EN global interrupte
	lcd_init();//intialize the lcd
	while (1)
	{
		while(PW==0)//continue till the push button is released
		{
			if (SW_dir==0)//if the direction control push button is released
			{
				PORTA=0b00000001;//10 to respective 1A 2A pins to rotate in clk wise direction
				lcd_out(1,1,"MOTOR ON-CLKWISE");//Running clk-wise direction
			}
			else
			{
				PORTA=0b00000010;//10 to respective 1A 2A pins to rotate in anti-clk wise direction
				lcd_out(1,1,"MOTORON-ACLKWISE");//Running anticlk-wise direction
			}
			OCR0=i;//i increase in ISR,the corresponding value is to be loaded into OCR0
		}
		PORTA =0x00;//00 to respective 1A 2A pins to stop rotation
		lcd_out(1,1,"MOTOR IS TURNOFF");
	}
}
ISR(INT0_vect)//interrupt service routine
{
	i=i+20;//i increase the duty cycle also increase by 20 in each push,the corresponding value to be loaded into OCR0 in while loop
}

OUTPUT:

Power Switch:OFF,DIrection Switch:OFF,Speed Switch:OFF::Motor is TURN OFF Condition

Power Switch:ON,DIrection Switch:OFF,Speed Switch:OFF::Motor is TURN ON Condition

Power Switch:ON,DIrection Switch:ON,Speed Switch:OFF::Motor is TURN ON Condition and Direction of Rotation:Reverse.

Power Switch:ON,DIrection Switch:OFF,Speed Switch:ON::Motor is TURN ON Condition and SPeed of motor :Increased.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.