Challenge

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

#include <avr/io.h> //avr library
#define F_CPU 16000000L //CPU Frequency
#include "avr/interrupt.h" //library to add interrupt
#include <util/delay.h> //library to give delay
#define direction (PIND&(1<<1)) //direction change switch to D1
#define speed (PIND&(1<<2)) //speed control switch to D2
#define power (PINB&(1<<4)) //Power switch to C3
#define lcdport PORTC //LCD connected PORTB
#define rs_high() PORTD |= (1<<6); //object macro for PORTD0 set
#define rs_low() PORTD &= ~(1<<6); //object macro for PORTD0 reset
#define en_high() PORTD |= (1<<7); //object macro for PORTD1 set
#define en_low() PORTD &= ~(1<<7); //object macro for PORTD1 reset
unsigned char i;
//void lcd_cmd(unsigned char cmd)

void lcd_cmd(unsigned char cmd)
{
	lcdport = cmd; //send command to the PORTB
	rs_low(); //register low to command mode
	en_high(); //enable high to feed data
	_delay_ms(1);
	en_low(); //enable low to stop transfer
}
void lcd_data(unsigned char data)
{
	lcdport = data; //send data through PORTB
	rs_high(); //register high to data mode
	en_high(); //enable high transfer data
	_delay_ms(1);
	en_low(); //enable low to stop transfer
}
void lcd_init()
{
	lcd_cmd(0x38);_delay_ms(5); //4 bit 2 Lines 5x7 matrix Input
	lcd_cmd(0x02);_delay_ms(5); //to return home
	lcd_cmd(0x01);_delay_ms(5); //to clear screen
	lcd_cmd(0x0C);_delay_ms(5); //to display on and cursor blinking
	lcd_cmd(0x06);_delay_ms(5); //to increment cursor
	lcd_cmd(0x80);_delay_ms(5); //to cursor begin 1st line
}
void cursorpos(char x,char y)
{
	if ((x<1 || x>2) || (y<1 || y>16))
	{
		x=1;
		y=1;
	}          //gives value if wrong input is given
	if (x==1)
	{
		lcd_cmd(0x7F+y);
	} //position for first line
	else
	{
		lcd_cmd(0xBF+y); //position for second line
	}
	
}
void lcd_out(char x,char y,char *str)
{
	cursorpos(x,y); // to set cursor position
	while(*str)
	{
		lcd_data(*str); // if string has value it is passed to the data as argument
		str++;
	}
}
int main(void)
{

	DDRC = 0xFF; //enable all PORTC Output pins to interface with LCD 16x2
	DDRA |= ((1<<0)|(1<<1)); //enable A0 and A1 to interface with L293 Motor driver
	DDRD &= ~(1<<1); //enable D1 as input for direction switch
	DDRD &= ~(1<<2); //enable D2 as input for speed switch INT0
	DDRB &= ~(1<<3); //enable B3 as for PWM to the driver
	DDRB &= ~(1<<4); //enable D4 as input for power switch
	DDRD |= ((1<<6)|(1<<7)); //enable D6 for LCD reset and D7 for LCD enable pin
	PORTD |= (1<<2); //pull up PORTD2 pin for speed switch
	PORTB |= (1<<4); //pull up PORTB4 pin for power switch
	i=64; //declare the PWM as 25%
	TCCR0 = 0x61; //non inverting PWM phase correct Mode, no pre scaler
	GICR = (1<<INT0); //enable global interrupt pin INT0
	MCUCR = 0x02; //enable interrupt negative edge
	lcd_init(); //initialize LCD
	sei(); //start interrupt
	while (1)
	{
		while(power == 0) //if power switch toggled enters the loop
		{
			if(direction==0)//initially motor runs in clockwise direction since the pin is pulled up
			{ 
				PORTA = 0b00000001;
				lcd_out(1,1,"Motor is Running");
				lcd_out(2,3," Clockwise ");

			}
			else//if direction switch pushed motor rotates anticlockwise
			{ 
				PORTA = 0b00000010;
				lcd_out(1,1,"Motor is Running");
				lcd_out(2,3,"Anticlockwise");

			}
			OCR0 = i; //sets the pin value incrementing at push using interrupt
		}
		PORTA = 0x00;//if power button is off PORTA is low motor off
		lcd_out(1,1," Motor is OFF STATE ");
		lcd_out(2,3,"<_> WARNING ");
	}
}
ISR(INT0_vect)//interrupt to increase motor speed every time pushed speed switch connected to INT0 PORTD2
{
	i=i+20;
}
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.