Challenge

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

Project 1
Controlling a DC motor using PWM and monitoring its Running status
------------------------------------------------------------
#include <avr/io.h>//avr header file
#define F_CPU 16000000L//CPU frequency
#include <util/delay.h>//for delay
#include "avr/interrupt.h"//for external interrupt pin

#define lcdport PORTC//PORTC as LCD out, MACRO
#define direction (PIND & (1<<1))////D1 pin is declared as push button for direction control
#define speed (PIND & (1<<2))//D2 pin is declared as push button for Speed control
#define power_switch (PINB & (1<<1))//B1 pin is declared as push button for Power ON/OFF

#define rs_high() PORTD |= (1<<6); //D6 logical high,LCD
#define rs_low() PORTD &= ~(1<<6); //D6 logical low,LCD
#define en_high() PORTD |= (1<<5); //D5 logical high,LCD
#define en_low() PORTD &= ~(1<<5); //D5 logical low,LCD


int var;//for giving values for variable speed

void lcd_cmd (unsigned char cmd)//for LCD commands
{
lcdport=cmd;
rs_low(); //for command register
en_high();
_delay_ms(1);
en_low();
}
void lcd_data (unsigned char data)//for data register
{
lcdport=data;
rs_high(); //data register selected
en_high();
_delay_ms(1);
en_low();
}
void lcd_init()//for LCD initialization
{
lcd_cmd(0x38); //2 lines and 5x7 matrix(D0-D7,8bit)
_delay_ms(5);
lcd_cmd(0x02); //return home
_delay_ms(5);
lcd_cmd(0x01);//clear display screen
_delay_ms(5);
lcd_cmd(0x0c);//Display on,cursor off
_delay_ms(5);
lcd_cmd(0x06);//Increment cursor (shift to right)
_delay_ms(5);
lcd_cmd(0x80);//force cursor to beginning of first line
_delay_ms(5);
}
void cursor_pos(char x, char y)//x-row,y-column
{
if((x<1||x>2)||(y<1||y>16))//any type mistakes
{
x=1;
y=1;
}
if (x==1) //0x80 -(1,1) , (1,2)-0x81 , (1,3)-0x82.....
{
lcd_cmd(0x7F+y);//7F+1=0x80
}
else //0xC0
{
lcd_cmd(0xBF+y);//BF+1=0xC0
}
}

void lcd_out(char x, char y, char *str)//for passing string
{
cursor_pos(x,y);
while(*str)
{
lcd_data(*str);
str++;//character by character
}
}

int main(void)//program entry
{
PORTC = 0xFF;//LCD
DDRA |= (1<<0);//for L293 driver in
DDRA |= (1<<1);//for L293 driver in
DDRD &= ~(1<<1);//direction
DDRD &= ~(1<<2);//speed(interrupt)
DDRB &= ~(1<<1);//power switch


/*enabling pullup resistors*/
PORTB |= (1<<1);//power_switch
PORTD |= (1<<2);//enable pull up for interrupt0

var =64;//Initializing var=64 because we are running the motor with 25% duty cycle ie,(256x(25/100))=64. (since its an 8 bit register 2^8=256)

TCCR0 = 0x61;//non inverting mode, phase corrected pwm, no prescalar
GICR = (1<<INT0);//Use INT0 for interrupt
MCUCR = 0x02;//for negative edge triggered
sei();//enable global interrupt
lcd_init();//initilize LCD
while(1)
{
while(power_switch==0)// continue till the push button is released
{
if(direction ==0)// if the direction control push button is released
{
PORTA=0x01;// 0 1 to respective 1A 2A pins to rotate in clockwise direction.
lcd_out(1,1,"Motor is ON");//for printing motor ON
lcd_out(2,1,"Clock-wise");//printing it in clock wise

}
else
{
PORTA=0x02;// 10 to respective 1A 2A pins to rotate in Anti-Clockwise direction.
lcd_out(1,1,"Motor is ON");//for printing motor ON
lcd_out(2,1,"Anti-Clockwise");//printing it in anti-clock wise
}
OCR0=var;//var increases in ISR,the corresponding value is to be loaded into OCRO
}

PORTA=0x00;// 00 to respective 1A 2A pins to Stop rotation.
lcd_out(1,1,"Motor OFF");
}

}
ISR(INT0_vect) //interrupt service routine
{
/*as var increases the duty cycle also increases.var increases by 10 in each push and the corresponding value is to be loaded into OCRO */
var=var+10;
}

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.