Challenge

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

/*

* AVR project 1.c

*

* Created: 12/19/2024 9:13:40 PM

* Author : yuvar

*/

#include <avr/io.h>

#define F_CPU 16000000

#include <util/delay.h>

#include <avr/interrupt.h>

#define lcdport PORTB

#define en_high PORTD|=(1<<6)

#define en_low PORTD &=~(1<<6)

#define rs_high PORTD|=(1<<5)

#define rs_low PORTD &=~(1<<5)

#define motor_dir (PIND&(1<<1))

#define motor_spd (PIND& (1<<2))

#define pwr (PINC&(1<<3))

unsigned char i;

void lcd_command(unsigned char cmd);

void lcd_data(unsigned char data);

void lcd_init();

void cursorpos(char x, char y);

void lcd_out(char x, char y, char *str);

int adc_read(char channel);

void lcd_command(unsigned char cmd)

{

lcdport = (cmd&0xf0);

rs_low;

en_low;

_delay_ms(1);

en_high;

lcdport=((cmd<<4)&(0xf0)); // LCD port

rs_low;

en_low;

_delay_ms(1); //after 1ms disable LCD

en_high; // enable the LCD

}

void lcd_data(unsigned char data)

{

lcdport =(data&0xf0);

rs_high;

en_low;

_delay_ms(1);

en_high;

lcdport=((data<<4)&(0xf0)); //masking 4 bits for bit LCD mode//

rs_high; //access data register

en_low;

_delay_ms(1);

en_high;

}

void lcd_init()

{

lcd_command(0x28);_delay_ms(5);

lcd_command(0x02);_delay_ms(5);

lcd_command(0x01);_delay_ms(5);

lcd_command(0x0C);_delay_ms(5);

lcd_command(0x06);_delay_ms(5);

lcd_command(0x80);_delay_ms(5);

}

void cursorpos(char x,char y)

{

if( (x < 1 || x > 2) || (y < 1 || y > 16) )

{

x = 1;

y = 1;

}

if(x == 1)

lcd_command(0x80+y);

else

lcd_command(0xC0+y);

}

void lcd_out(char x,char y,char *str)

{

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 are going to use which channel we need to select in mux here using 2 bit

ADCSRA=0X80; // control and 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 (0x40means interrupt pin)

a=ADCL; //dummy data type a and a is stored the adcl register (ADC0-ADC7)

result=ADCH; //store the high value (ADC8-ADC9)

result=result<<8; //to get proper result or aligned value we need to do left shift

result=result|a; //we are adding the ADCL+ADCH to get 16 bits

return result;

}

int main(void)

{

DDRB=0xFF; // declaring all 8 pins as output

DDRA|=((1<<0)|(1<<1)); // declaring A0 and A1 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 pre scalar

GICR=(1<<INT0); // using into for interrupt

MCUCR=0X02; // make interrupt negative edge triggered

sei(); //enable global interrupt

lcd_init(); // initialized LCD

while (1)

{

while(pwr==0) //continue till push button is released

{

if (motor_dir==0) // if the direction control push button is released

{

PORTA=0b00000001; //10 respective 1A 2A pins to rotate in clockwise direction

lcd_out(1,1,"Motor ON-CLW"); // running clockwise direction

}

else

{

PORTA=0b00000010; //10 respective 1A 2A pins to rotate in anti-clockwise direction

lcd_out(1,1,"Motor ON-ACL"); // running anti-clockwise direction

}

OCR0=i; // i increase in ISR, the corresponding value is to be loaded into OCR0

}

PORTA=0X00; //0 0 to respective 1A 2A pins to stop condition

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

}

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.