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
}



