Project 1 - Controlling a DC motor using PWM and monitoring its Running status
#include <avr/io.h> //i/o register of avr
#define F_CPU 16000000ul //defining cpu frequency
#include "avr/interrupt.h" //external interrupt
#include<util/delay.h> //delay function
#define sw_dir (PIND&(1<<1)) //D1 pin is used as push button for direction control
#define sw_spd (PIND&(1<<2)) //D2 pin is used as push button for speed control
#define pw (PINC&(1<<3)) //c3 pin is used as push button for power on/off
#define lcd_port PORTB //portb dedicated to lcd data
#define RS_high PORTD|=(1<<5) //d5 for register select high
#define RS_low PORTD&=~(1<<5) //d5 for register select low
#define En_high PORTD|=(1<<6)
#define En_low PORTD&=~(1<<6) //d6 used for enable
unsigned char i; //variable declaired for increase the duty cycle of pwm
void lcd_cmd(char cmd)
{
lcd_port=(cmd&0X0F); // masking 4bit lcd mode
RS_low;
En_low;
_delay_ms(1);
En_high;
lcd_port=((cmd<<4)&(0X0F));
RS_low;
En_low;
_delay_ms(1);
En_high;
}
void lcd_data(char data)
{
lcd_port=(data&0X0F); // masking 4bit lcd mode
RS_high;
En_low;
_delay_ms(1);
En_high;
lcd_port=((data<<4)&(0X0F));
RS_high;
En_low;
_delay_ms(1);
En_high;
}
void lcd_init()
{
lcd_cmd(0X02);_delay_ms(5); //return the cursor to home
lcd_cmd(0X01);_delay_ms(5); //clear screen
lcd_cmd(0X0C);_delay_ms(5); //display ON cursor OFF
lcd_cmd(0X06);_delay_ms(5); //increment cursor
lcd_cmd(0X80);_delay_ms(5); //force cursor to begin !st line
lcd_cmd(0X28);_delay_ms(5); //used for 4 bit lcd mode
}
void lcd_out(char x,char y,char *str) //function for printing strings
{
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
void cursorpos(char x,char y)
{
if((x<1||x>2)||(y>16||y<1))
{
x=1;
y=1;
}
if(x==1)
{
lcd_cmd(0X7+y);
}
else
{
lcd_cmd(0XBF+y);
}
}
int main(void)
{
DDRB=0XFF; //delairing all B pin as output
DDRA=((1<<0)|(1<<1)); //delairing all A0 A1 pin as output
DDRD&=~(1<<1); //declairing D1 pin as input
DDRD&=~(1<<1); //declairing D2 pin as input
DDRD|=(1<<5); //declairing D5 pin as input
DDRD|=(1<<6); //declairing D6 pin as input
DDRC&=~(1<<3); //declairing C3 pin as input
PORTD|=(1<<2); //enabling internal pull up register for D2
PORTC|=(1<<3); //enabling internal pull up register for D2
i=64; //initialiaing i=64 because e are running the motor with 25% of duty cucle
TCCR0=0X61; //non inverting mode, pwm phase correct mode , no prescalers
GICR=(1<<INT0); //unsing INT0 for interrupt
MCUCR=0X02; // make interrupt negative edge trigger
sei(); //enable global interrupt
lcd_init(); //initialise lcd
while (1)
{
while(pw==0) //continue till the power push button is release
{
if(sw_dir==0) //if the direction control push button is release
{
PORTA=0b00000001; //1 0 to respective 1A and 2A pins to rotate in clockise direction
lcd_out(1,1,"motor is running");
lcd_out(2,3,"clockwise");
}
else
{
PORTA=0b00000010; //0 1 to respective 1A and 2A pins to rotate in anticlockise direction
lcd_out(1,1,"motor is running");
lcd_out(2,3,"anticlockwise");
}
OCR0=i; // As, i increase in ISR, the corresponding value is to be loaded into the OCR0
}
PORTA=0X00; //0 0 respective 1A 2A pins to stop rotation
lcd_out(1,1,"motor is off");
lcd_out(2,3,"caution !!!!");
}
}
ISR(INT0_vect) //interrupt service routein
{
i=i+20; //as i increase the duty cycle also increase. i increase by 20 in each puch.
cli();
}
#include <avr/io.h> //i/o register of avr
#define F_CPU 16000000ul //defining cpu frequency
#include "avr/interrupt.h" //external interrupt
#include<util/delay.h> //delay function
#define sw_dir (PIND&(1<<1)) //D1 pin is used as push button for direction control
#define sw_spd (PIND&(1<<2)) //D2 pin is used as push button for speed control
#define pw (PINC&(1<<3)) //c3 pin is used as push button for power on/off
#define lcd_port PORTB //portb dedicated to lcd data
#define RS_high PORTD|=(1<<5) //d5 for register select high
#define RS_low PORTD&=~(1<<5) //d5 for register select low
#define En_high PORTD|=(1<<6)
#define En_low PORTD&=~(1<<6) //d6 used for enable
unsigned char i; //variable declaired for increase the duty cycle of pwm
void lcd_cmd(char cmd)
{
lcd_port=(cmd&0X0F); // masking 4bit lcd mode
RS_low;
En_low;
_delay_ms(1);
En_high;
lcd_port=((cmd<<4)&(0X0F));
RS_low;
En_low;
_delay_ms(1);
En_high;
}
void lcd_data(char data)
{
lcd_port=(data&0X0F); // masking 4bit lcd mode
RS_high;
En_low;
_delay_ms(1);
En_high;
lcd_port=((data<<4)&(0X0F));
RS_high;
En_low;
_delay_ms(1);
En_high;
}
void lcd_init()
{
lcd_cmd(0X02);_delay_ms(5); //return the cursor to home
lcd_cmd(0X01);_delay_ms(5); //clear screen
lcd_cmd(0X0C);_delay_ms(5); //display ON cursor OFF
lcd_cmd(0X06);_delay_ms(5); //increment cursor
lcd_cmd(0X80);_delay_ms(5); //force cursor to begin !st line
lcd_cmd(0X28);_delay_ms(5); //used for 4 bit lcd mode
}
void lcd_out(char x,char y,char *str) //function for printing strings
{
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
void cursorpos(char x,char y)
{
if((x<1||x>2)||(y>16||y<1))
{
x=1;
y=1;
}
if(x==1)
{
lcd_cmd(0X7+y);
}
else
{
lcd_cmd(0XBF+y);
}
}
int main(void)
{
DDRB=0XFF; //delairing all B pin as output
DDRA=((1<<0)|(1<<1)); //delairing all A0 A1 pin as output
DDRD&=~(1<<1); //declairing D1 pin as input
DDRD&=~(1<<1); //declairing D2 pin as input
DDRD|=(1<<5); //declairing D5 pin as input
DDRD|=(1<<6); //declairing D6 pin as input
DDRC&=~(1<<3); //declairing C3 pin as input
PORTD|=(1<<2); //enabling internal pull up register for D2
PORTC|=(1<<3); //enabling internal pull up register for D2
i=64; //initialiaing i=64 because e are running the motor with 25% of duty cucle
TCCR0=0X61; //non inverting mode, pwm phase correct mode , no prescalers
GICR=(1<<INT0); //unsing INT0 for interrupt
MCUCR=0X02; // make interrupt negative edge trigger
sei(); //enable global interrupt
lcd_init(); //initialise lcd
while (1)
{
while(pw==0) //continue till the power push button is release
{
if(sw_dir==0) //if the direction control push button is release
{
PORTA=0b00000001; //1 0 to respective 1A and 2A pins to rotate in clockise direction
lcd_out(1,1,"motor is running");
lcd_out(2,3,"clockwise");
}
else
{
PORTA=0b00000010; //0 1 to respective 1A and 2A pins to rotate in anticlockise direction
lcd_out(1,1,"motor is running");
lcd_out(2,3,"anticlockwise");
}
OCR0=i; // As, i increase in ISR, the corresponding value is to be loaded into the OCR0
}
PORTA=0X00; //0 0 respective 1A 2A pins to stop rotation
lcd_out(1,1,"motor is off");
lcd_out(2,3,"caution !!!!");
}
}
ISR(INT0_vect) //interrupt service routein
{
i=i+20; //as i increase the duty cycle also increase. i increase by 20 in each puch.
cli();
}


