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




/*
* test.c
*
* Created: 15-07-2023 19:40:46
* Author : AMARNATH CHAKLADAR
*/
#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);
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//
}
void cursorpos(char x, char y)
{
if ((x<1||x>2)||(y<1)||(y>16)) /*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 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*/
OCR0 =i;
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; // 01 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-ACLK"); // 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");
}
return 0;
}
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 */
}