Challenge

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

Program:

#include <avr/io.h>

#define F_CPU 16000000L

#include "avr/interrupt.h"

#include <util/delay.h>

#define sw_dir (PIND & (1<<1))//D1 pin is used for direction control which is given through push button

#define sw_dspd (PIND & (1<<2))//D2 pin is used for speed control which is given through push button

#define pw (PINC & (1<<3))//C3 is used for power on/off through switch all

#define lcd_port PORTB//portb is for lcd data

#define RS_high PORTD |= (1<<5)//D5 is used for Register Select(RS)

#define RS_low PORTD &=~ (1<<5)

#define EN_high PORTD |= (1<<6)//D6 is used foe enable

#define EN_low PORTD &=~ (1<<6)

unsigned char i;

void lcd_cmd(char cmd)//command for lcd display

{

lcd_port = (cmd & 0xf0);

RS_low;

EN_low;

_delay_ms(1);//after 1ms disable lcd

EN_high;//enable lcd

lcd_port = ((cmd<<4) & (0xf0));

RS_low;

EN_low;

_delay_ms(1);//after 1ms disable lcd

EN_high;//enable lcd

}

void lcd_data(char data)//send data to lcd

{

lcd_port = (data & 0xf0);

RS_high;//access data register

EN_low;

_delay_ms(1);

EN_high;

lcd_port = ((data<<4) & (0xf0));

RS_high;

EN_low;

_delay_ms(1);

EN_high;

}

void lcd_int()

{

lcd_cmd(0x28);

_delay_ms(5);

lcd_cmd(0x02);//return home

_delay_ms(5);

lcd_cmd(0x01);//clear screen

_delay_ms(5);

lcd_cmd(0x0C);//cursor off

_delay_ms(5);

lcd_cmd(0x06);/

//increment display cursor

_delay_ms(5);

lcd_cmd(0x80);//starts from first line

_delay_ms(5);

}

void cursorpos(char x, char y)

{

if((x<1 || x>2) || (y>16 || y<1))//condition to check the two rows and 16 columns

{

x=1;//row

y=1;//column

}

if(x==1)

{

lcd_cmd(0x7F + y);//used to start from column

}

else

{

lcd_cmd(0xBF + y);//used to start 2 line 2 row

}

}

void lcd_out(char x, char y, char *str)//position checking for printing

{

cursorpos(x,y);

while(*str)

{

lcd_data(*str);

str++;

}

}

int adc_read(char channel)//configuring adc value

{

unsigned int a, result;

ADMUX = channel;//mux for 2 bit

ADCSRA = 0x80;//enable adc

ADCH = 0x00;//clearing adc

ADCL = 0x00;//be seen value 0

ADCSRA |= (1<<6);//to start the conversion 6 bit ADSC high

while((ADCSRA & 0x40) != 0);//0x40 means interrupted pin

a=ADCL;//dummy data type to store ADCL

result=ADCH;//store high value

result=result<<8;//getting proper output

result=result | a;

return result;

}

int main(void)

{

DDRB = 0XFF;//declaring all 8 pins as output

DDRA |= ((1<<0)| (1<<1));//declaring A0 & A1 as output

DDRD &=~ (1<<1);//D1 pin as input

DDRD &=~ (1<<2);//D2 input

DDRD |= (1<<5);//D5 output

DDRD |= (1<<6);//D6 output

DDRC &=~ (1<<3);//C3 input

PORTD |= (1<<2);//enabling internal pull up register for D2

PORTC |= (1<<3);//enabling internal pull up register for D3

i = 64;//initializing i=64

TCCR0 = 0X61;//non inverting mode

GICR = (1<<INT0);//using int0 for interrupt

MCUCR = 0X02;//making interrupt

sei() ;//global interrupt

lcd_int();//initialize lcd

while (1)

{

while(pw==0)//continue till push button is released

{

if(sw_dir==0)//direction button is released

{

PORTA = 0b00000001;

lcd_out(1,1,"Motor On- CL");//running clockwise

}

else

{

PORTA = 0b00000010;

lcd_out(1,1,"Motor On- ACL");//running anti clockwise

}

OCR0 = i;//i increasing in isr and loaded into ocr0

}

PORTA = 0x00;

lcd_out(1,1,"Motor is TRUN OFF");//motor off

}

}

ISR(INT0_vect)//interrupt service routine

{

i = i+20;//i increases also duty cycle increases and value loaded in ocr0

}

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.