Challenge

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

Embedded Offline Batch 2

#include //Including AVR library file
#define F_CPU 16000000L //Define CrystalFrequency
#include "avr/interrupt.h" //library to add interrupt
#include //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_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 arg
str++;
}
}
void lcd_cmd(unsigned char cmd)
{
lcdport = cmd; //send command to thePORTB
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 thru 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 start()
{
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 forLCD 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 as25%
TCCR0 = 0x61; //non inverting PWM phase correct Mode, no pre scaler
GICR = (1< MCUCR = 0x02; //enable interrupt negative edge
lcd_init(); //initialise LCD
sei(); //start interrupt
}
int main(void)
{

start(); //start fn to initialise all the possible pins and ports
while (1)
{
while(power == 0) //if power switch toggled enters the loop
{
if(direction==0)
{ 
PORTA = 0b00000001;//initially motor runs in clockwise direction since the pin is pulled up
lcd_out(1,1,"Motor is Running");
lcd_out(2,3," clockwise ");

}
else
{
PORTA = 0b00000010;  //if direction switch pushed motor rotates anticlockwise
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 ");
lcd_out(2,3," !!CAUTION!! ");
}
}
ISR(INT0_vect)
{
i=i+20;
}//interrupt Service rotine

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.