Challenge

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

Implement a system on the simulator for controlling a DC motor using L293 motor driver, monitor its status and print the running status of motor on the LCD Display.

Program:

#include <avr/io.h> /*We are using I/O registers of AVR*/
#define F_CPU 16000000L /*Define the frequency*/
#include "avr/interrupt.h" /*Here we used the external interrupt pin*/
#include <util/delay.h> /*delay function purpose*/
#define sw_dir (PIND & (1<<1)) /*D1 pin is declared as push button for direction control*/
#define sw_spd (PIND & (1<<2)) /*D2 pin is declared as push button for Speed control*/
#define pw (PINC & (1<<3)) /*C3 pin is declared as push button for Power ON/OFF*/

#define lcd_port PORTB /*Here we declared the PORT B for the LCD */
#define RS_high PORTD|=(1<<5) /*D5 is used for the Register Select(RS) for HIGH (1)*/
#define RS_low PORTD &=~(1<<5) /*D5 is used for the Register Select(RS) for LOW (0)*/
#define EN_high PORTD|=(1<<6) /*D6 is used for the Enable(EN) for HIGH (1)*/
#define EN_low PORTD &=~(1<<6) /*D6 is used for the Enable(EN) for LOW (0)*/
unsigned char i;

void lcd_cmd(char cmd)
{
lcd_port=(cmd&0xf0); /*Making 4 bits for 4 bit LCD mode*/
RS_low;
EN_low;
_delay_ms(1); /*After 1ms disable LCD*/
EN_high; /*Enable LCD*/
lcd_port=((cmd<<4)&(0xf0)); /*LCD Port*/
RS_low;
EN_low;
_delay_ms(1); /*After 1ms disable LCD*/
EN_high; /*Enable LCD*/

}
void lcd_data(char data) /*Send the data to LCD*/
{
lcd_port=(data&0xf0); //making 4 bits for bit LCD mode//
RS_high;
EN_low;
_delay_ms(1);
EN_high;
lcd_port=((data<<4)&(0xf0));
RS_high;
EN_low;
_delay_ms(1);
EN_high;
}
void lcd_init()
{
lcd_cmd(0x28);_delay_ms(5); //used for 4 bits lcd mode //
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 1st line //
}
void cursorpos(char x, char y)
{
if ((x<1||x>2)||(y>16)||(y<1)) /*Here we check the 2 rows and 16 columns*/
{
x=1; /*X= Rows*/
y=1; /*Y= Columns*/
}
if (x==1)
{
lcd_cmd(0x7F+y); /*80-1=7f for starting the 1st line hex decimal value(80)...we need to start from that column...*/
}
else
{
lcd_cmd(0xBF+y); /*2nd line 2nd row*/
}
}

void lcd_out(char x, char y, char *str) /*Here we are checking in which position we want to print*/
{
cursorpos(x,y);
while (*str)
{
lcd_data(*str);
str++;
}
}

int adc_read(char channel) /* we r configuring the adc value*/
{
unsigned int a,result;
ADMUX=channel; /*here we are going to use which channel we need to select in mux here using2bit */
ADCSRA=0X80; /*control & status register to enable the adc conversion,enable the interrupt flag,adc interrupt.*/
ADCH=0X00; /*showing the value0or clearing the adc register*/
ADCL=0x00; /*showing the value0*/
ADCSRA|=(1<<6); /*to start the conversion6bit ADSC high*/
while((ADCSRA & 0x40)!=0); /*when the conversion become zero means conversion of adc(0x40 means interrupted pin)*/
a =ADCL; /*dummy data type a and a is stored the ADCL register(ADCO-ADC7)*/
result=ADCH; /*Store the high value(ADC8-ADC9)*/
result=result <<8; /*to get proper result or aliened value we need to do left shift*/
result=result|a; /*we are adding the ADCL+ADCH to get the 16 bits*/
return result;
}
int main(void)
{
DDRB=0xFF; /*Declaring all 8 pins are Output*/
DDRA|=((1<<0)|(1<<1)); /*Declaring A0 and A1 pins as Output*/
DDRD&=~(1<<1); /*Declaring D1 pin as Input*/
DDRD&=~(1<<2); /*Declaring D2 pin as Input*/
DDRD|=(1<<5); /*Declaring D5 pin as Output*/
DDRD|=(1<<6); /*Declaring D6 pin as Output*/
DDRC&=~(1<<3); /*Declaring D3 pin as Input*/
PORTD|=(1<<2); /*Enable D2 Pull up Resistor*/
PORTC|=(1<<3); /*Enable C3 Pull up Resistor*/
i=64; /*Initializing i=64 because we are running the motor with 25% duty cycle*/
TCCR0=0X61; /*Non-inverting Mode,PWM phase correct mode,no prescalar*/
GICR=(1<<INT0); /*Using INT0 for interrupt*/
MCUCR=0X02; /*Make interrupt Negative edge triggered */
sei(); /*Enable Global interrupt*/
lcd_init(); /*initialize LCD*/
while(1)
{
while(pw ==0)// continue till the push button is released.
{
if(sw_dir ==0)// if the direction control push button is released.
{
PORTA=0x01;// 10 to respective 1A 2A pins to rotate in clockwise direction.
lcd_out(1,1,"Motor ON-CLK");// Running clock wise direction
}
else
{
PORTA=0x02;// 10 to respective 1A 2A pins to rotate in Anti-Clockwise direction.
lcd_out(1,1,"Motor ON-ACL"); // running anti clock wise direction
}
OCR0=i;//i 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 is OFF");
}
}
ISR(INT0_vect) /*interrupt service routine*/
{
i=i+20; /*as i increases the duty cycle also increases.i increases by 20 in each push and the corresponding value is to be loaded into OCRO in while loop */
}

CONDITION 1:

  • power switch : OFF
  • Direction switch : OFF
  • Speed switch : OFF
  • Motor status : Motor is OFF condition.

CONDITION 2:

  • power switch : ON
  • Direction switch : OFF
  • Speed switch : OFF
  • Motor status : Motor is OFF condition.
  • Direction of rotation : clockwise

CONDITION 3:

  • power switch : ON
  • Direction switch : OFF
  • Speed switch : ON
  • Motor status : Motor is ON condition.
  • Direction of rotation : Anti clockwise

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.