Challenge

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

Answer

C Program for run DC motor Clock wise and Anti clock wise direction and show status of motor on 16X2 LCD Display.

 /*
 * Project1.c
 *
 * Created: 18-10-2022 23:34:03
 * Author : Axit Rupareliya
 */ 

#include                                            // we are using I/O registers of AVR
#define F_CPU 16000000L                                       // define the crystal frequency
#include                                     // we are using external interrupt pin
#include                                        // delay function purpose
#define sw_dir (PIND & (1<<1))                                // d1 pin is declared as push button for direction control.
#define sw_dspd (PIND & (1<<2))                               // d2 pin is declared as push button for speed control.
#define pw (PINC & (1<<3))                                    // c3 is declared as push button for power ON/OFF

#define lcd_port PORTB                                        // PORTB pins are for LCD data
#define RS_high PORTD |= (1<<5)                               // d5 pin is used for Register Select(RS)
#define RS_low PORTD &=~ (1<<5)                               // d5 pin is used for RS
#define EN_high PORTD |= (1<<6)                               // d6 pin is used for Enable
#define EN_low PORTD &=~ (1<<6)                               // d6 pin is used for En.
unsigned char i;

void lcd_cmd(char cmd)                                        //command for lcd display
{
	lcd_port = (cmd & 0xf0);                              //4 bits for 4 bit lcd mode
	RS_low;
	EN_low;
	_delay_ms(1);                                         //after 1ms disable lcd
	EN_high;                                              //enable the lcd
	lcd_port = ((cmd<<4) & (0xf0));                       //lcd port
	RS_low;
	EN_low;
	_delay_ms(1);                                         //after 1ms disable lcd
	EN_high;                                              //enable the lcd
}

void lcd_data (char data)                                     //send the data to lcd
{
	lcd_port = (data & 0xf0);                             //4 bits for 4 bit lcd mode
	RS_high;                                              //access data register
	EN_low;
	_delay_ms(1);
	EN_high;
	lcd_port = ((data<<4) & (0xf0));                      //4 bits for 4 bit lcd mode
	RS_high;                                              //access data register
	EN_low;
	_delay_ms(1);
	EN_high;
}

void lcd_init()
{
	lcd_cmd(0x28);                                        // used for 4 bit lcd mode
	_delay_ms(5);
	lcd_cmd(0x02);                                        // return home
	_delay_ms(5);
	lcd_cmd(0x01);                                        // clear screen
	_delay_ms(5);
	lcd_cmd(0x0C);                                        // display on cursor off
	_delay_ms(5);
	lcd_cmd(0x06);                                        // increment the display cursor
	_delay_ms(5);
	lcd_cmd(0x80);                                        // force cursor to begin from 1st line
	_delay_ms(5);
}

void cursorpos(char x,char y)
{
	if((x<1 || x>2) || (y>16 || y<1 ))                    //condition will checks the 2 rows and 16 columns
	{
		x=1;                                          // x= row
		y=1;                                          // y= column
	}
	if(x==1)
	{
		lcd_cmd(0x7F + y);                            //{ 80-1 = 7F} for starting the 1st line hex decimal value (80) {y we r using the 7F+y means we need to dtart from that column}
	}
	else                                                  //(x==2)
	{

		lcd_cmd(0xBF + y);                            //{0C-1 = 0B} for starting the 2nd line, 2nd row.
	}
}


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

int adc_read(char channel)                                    // we are configuring the adc value
{
	unsigned int a, result;
	ADMUX = channel;                                      // here we r going to use which channel we need to select in mux here using 2 bit
	ADCSRA = 0X80;                                        //control & status register to enable the adc conversion ,enable the interrupt flag, adc interrupt. ADEN=1
	ADCH = 0X00;                                          // showing the value 0 or clearing the adc register
	ADCL = 0x00;                                          // showing the value 0
	ADCSRA |= (1<<6);                                     // to start the conversion 6 bit 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 ais stored the ADCL register (ADC0-ADC7)
	result = ADCH;                                        // Store the high value (ADC8-ADC9)
	result = result<<8;                                   //to get proper result or alined value we need to do left shift
	result = result | a ;                                 // we r adding the ADCL + ADCH to get the 16 bits
	return result;
}

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 OCR0 in while loop
}

int main(void)
{
	DDRB = 0XFF;                                          //Declaring all 8-pins as output.
	DDRA |= ((1<<0)| (1<<1));                             //Declaring A0 & 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 C3 pin as input.
	PORTD |= (1<<2);                                      //enabling internal pull up resistor for D2.
	PORTC |= (1<<3);                                      //enabling internal pull up resistor for D3.
	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<

Screenshot of Simulation

Video of simulation is given in attachement section

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.