Challenge

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

/*
* Project 1 DC Motor.c
*
* Created: 18/12/2022 11:49:16 AM
* Author : Noorul Ameen
*/

#include <avr/io.h>
#define F_CPU 16000000UL // AVR clock frequency
#include <avr/interrupt.h>
#include <util/delay.h>
#define sw (PINB & (1<<0)) // PB0 as INPUT PIN - Direction control Push Button
#define lcdport PORTA // LCD Data Line - PORTA
#define rs_high PORTB |= (1<<1) // LCD Register select for Data
#define rs_low PORTB &=~ (1<<1) // LCD Register select for Command
#define en_high PORTB |= (1<<2) // LCD Enable
#define en_low PORTB &=~ (1<<2)
unsigned char i;

void lcd_cmd(unsigned char cmd) // Function Definition to Pass LCD Command
{
lcdport = cmd;
rs_low;
en_high;
_delay_ms(1);
en_low;
}

void lcd_data(unsigned char data) // Function Definition to Pass LCD Data
{
lcdport = data;
rs_high;
en_high;
_delay_ms(1);
en_low;
}

void lcd_init1() // Function Definition to Initialize LCD
{
lcd_cmd(0x38); _delay_ms(5);
lcd_cmd(0x02); _delay_ms(5);
lcd_cmd(0x01); _delay_ms(5);
lcd_cmd(0x0C); _delay_ms(5);
lcd_cmd(0x06); _delay_ms(5);
lcd_cmd(0x80); _delay_ms(5);
}

void lcd_out(char x,char y,char *str) // Function Definition To Display Character on LCD
{

cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}

void cursorpos(char x, char y) // Function Definition To Position LCD Cursor
{

if( (x < 1 || x > 2) || (y < 1 || y > 16) )
{
x = 1;
y = 1;
}
if(x == 1)
lcd_cmd(0x80+y);
else
lcd_cmd(0xC0+y);

}
//Function Definition to Print Values on LCD
void lcd_print(char row, char coloumn, unsigned int value, int digits)
{
unsigned int temp;
unsigned int unit;
unsigned int tens;
unsigned int hundred;
unsigned int thousand;
unsigned int million;

unsigned char flag=0;

if(row==0||coloumn==0)
{
cursorpos(1,1);
}
else
{
cursorpos(row,coloumn);

}

if(digits==4 || flag==1)
{

temp = value/1000;
thousand = temp%10 +48;
lcd_data(thousand);
flag=1;
}
if(digits==3 || flag==1)
{

temp = value/100;
hundred = temp%10 +48;
lcd_data(hundred);
flag=1;
}
if(digits==2 || flag==1)
{

temp = value/10;
tens= temp%10 +48;
lcd_data(tens);
flag=1;
}
if(digits==1 || flag==1)
{

unit = value%10 + 48;
lcd_data(unit);
}
if(digits>5)
{
lcd_data('e');
}
}


int main(void)
{
DDRA = 0xff; // PORTA is OUTPUT to communicate with LCD
DDRB |= (1<<1); // PB1 connected to LCD RS pin
DDRB |= (1<<2); // PB2 connected to LCD Enable pin
DDRB &=~ (1<<0); // PB0 INPUT PIN - For Motor Direction control Push Button
PORTB |= (1<<0); // Enable Internal PULL UP Resister
DDRC = (1<<PC0) | (1<<PC1); // PC0 and PC1 gives INPUT signal to Motor controller for Direction selection
i=64; // To set Initial value to Rotate DC Motor at constant speed
OCR0 = i; // Store Initial value to OCR0 Register to compare with TCNT0 to Generate PWM signal
TCCR0 = 0x61; // Initialize TCCRO Register to select Wave Generation / Non-Inverted Waveform / Pre-scalar value
DDRB |= (1<<PB3); // Getting Generated PWM signal from PB3 pin
DDRD &=~ (1<<PD2); // PD2 PIN to Control Motor Speed using Push Button
PORTD |= (1<<PD2); // Enable internal PULL-UP Resister
GICR = (1<<INT0); //Enable INT0 bit of General Interrupt Control register
MCUCR = 0x02; // To generate Interrupt request
sei(); //Global Interrupt Enable
lcd_init1();
lcd_out(1,1,"MTR DIR: ");
lcd_out(2,1,"MTR SPEED: ");
while (1)
{
if(sw == 0)
{
PORTC = 0x01; // Motor forward direction signal send to Motor controller
lcd_out(1,11,"FWD");
}

else
{
PORTC = 0x02; // Motor forward direction signal send to Motor controller
lcd_out(1,11,"REV");
}

OCR0 = i;
lcd_print(2,12,i,3); // To Display motor speed in LCD
}
return 0;
}

ISR(INT0_vect) // Execution of Interrupt Vector to Increase Motor speed
{
i = i+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.