Challenge

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

PROJECT 1 SOLUTION:-

#define F_CPU 16000000L
#include
#include
#include

#define lcdport PORTC//here i use macro named as lcdport by assigning all the C pins.
#define rs_high() PORTD |= (1 << 6)//here i am assigning the rs_high as function by giving an argument that pin D6 is taken as high
#define rs_low() PORTD &= ~(1 << 6)//here again making that pin D6 as low for rs_low.
#define en_high() PORTD |= (1 << 5)//here i am assigning the en_high as function by giving an argument that pin D5 is taken as high
#define en_low() PORTD &= ~(1 << 5)//here again making that pin D5 as low for en_low.
#define direction PORTD |= (1 << 0)// this macro is used for the changing the direction of the motor and also here i enable that pull up register
#define speed() PORTD |= (1 << 2);// here speed is nothing but the interrupt so here i am enabling the INT0 pull up register.
#define power_switch PORTD |= (1 << 1)// this macro is used for starting the motor

unsigned int VAR = 64;// here i initially provided the value of VAR global variable.
unsigned int n=1;

void lcd_data(unsigned char data) //this function is used to storing the data i.e. given by user.
{
    lcdport = data;//This line sets the value of a variable or register named lcdport to the value of another variable or register named data
    rs_high();
    en_high();
    _delay_ms(10);
    en_low();
}

void lcd_cmd(unsigned char cmd) //This line starts the definition of a function named lcd_cmd. This function takes an unsigned character cmd as an argument.
{
    lcdport = cmd;//this is setting the data for sending a command to an LCD.
    rs_low();// here we are controlling the RS (Register Select) pin.
    en_high();// here we are setting the enable pin of an lcd.
    _delay_ms(10);
    en_low();
}

void lcd_code() //here i am adding the more specific lcd codes for showing the cursor, data, clearing screen etc on the lcd screen
{
        
    lcd_cmd(0x38);//this command is used for 2 line and 5x7 matrix of lcd screen
    _delay_ms(5);

    lcd_cmd(0x02);//this is used for return home
    _delay_ms(5);

    lcd_cmd(0x01);// this command used for clearing the screen of the lcd
    _delay_ms(5);

    lcd_cmd(0x0C);// this is used for display ON , cursor OFF
    _delay_ms(5);

    lcd_cmd(0x06);// this is used for incrementing the cursor
    _delay_ms(5);

    lcd_cmd(0x80);// this command is used for force cursor begin 1st line
    _delay_ms(5);
}

void cursor_pos(char x, char y) // a function named cursor_pos that takes two characters, x and y, as arguments.
{
    if ((x < 1 || x > 2) || (y < 1 || y > 16)) // this condition used for any typo error , due this condition our cursor will always be within 2 rows i.e. fixed inside the lcd display and also there is fixed 16 column so cursor will always be inside the screen
    {
        x = 1;// if due to typing error that row and column given higher then this will redefined the row and column as an initial position
        y = 1;
    }
    if (x == 1) {
        lcd_cmd(0x7F + y);// this is nothing but same command as 80 for lcd
        } else {
        lcd_cmd(0xBF + y);
    }
}
void lcd_print(char row, char column, unsigned int n, int digits)
{
    unsigned int unit;
    if(row==0 || column==0)
    {
        cursor_pos(1,1);
    }else{
        cursor_pos(row, column);
    }
    if(digits==1){
        unit= n%10 +48;
        lcd_data(unit);
    }
}

void lcd_out(char x, char y, char *str) // this function is used for printing the string type or any character type data on the lcd screen and in this function the data will be going to print one by one
{
    cursor_pos(x, y);
    while (*str) {
        lcd_data(*str);
        str++;
    }
}

ISR(INT0_vect) //here this ISR function is used for calling the interrupt and here i am calling for INT0
{
    if(PIND & (1 << 0) && PIND & (1 << 1) || !(PIND & (1 << 0)) && PIND & (1 << 1))//this condition is going to execute only when the power switch is getting closed.
    {
    lcd_out(1, 1, "Motor gear is  ");
    lcd_print(1, 16, n, 1);
    _delay_ms(2000);
    }
    if (VAR < 1024) {
        VAR = VAR+50;//here we are increasing the speed of motor by changing the OCRO register value to 50
    }
    n++;
}

int main(void) {
    
    
    DDRD &= ~(1 << 1);//here the pin D1 is used as input pin for the power key
    DDRD &= ~(1 << 0);// here the pin D0 is used as I/P pin for the motor direction revolution
    GICR |= (1 << INT0);// here we are enabling the INT0
    sei();// here it is used to enabling the global interrupt
    speed();//by calling this macro we are enabling the INT pull up register
    DDRA |= (1 << 4);//these 2 pins are used used as O/P pins for the L293 driver that is used for giving the direction of revolution for the motor
    DDRA |= (1 << 2);
    DDRC = 0xFF;
    DDRD |= (1 << 6);// these pin use used as output pin for rs and en pin of lcd
    DDRD |= (1 << 5);
    TCCR0 = 0x61;//here we give there is no prescaling and using the phase correct PWM mode by clearing the OC0 on comparing when up counting
    MCUCR = 0x02;// for using INT0, we are making ISC01 AND ISC00 register as high and low respectively and by giving this input value the interrupt will work on falling edge(it will going to count from 64 to 0 VAR value).
    lcd_code();

    while (1) {
        if (!(PIND & (1 << 1)))
        {
            lcd_out(1, 1, "Motor is off    ");
            lcd_out(2, 1, "             ");
            PORTA &= ~(1 << 2); // clear bit 2
            PORTA &= ~(1 << 4); // Clear bit 4
            }
        if (PIND & (1 << 0) && PIND & (1 << 1))
        {
                PORTA |= (1 << 2); // Set bit 2
                PORTA &= ~(1 << 4); // Clear bit 4
                
                _delay_ms(100);
                lcd_out(1, 1, "Motor is running");
                lcd_out(2, 1, "clockwise    ");
        }
        if(!(PIND & (1 << 0)) && PIND & (1 << 1))
        {
                PORTA |= (1 << 4); // Set bit 2
                PORTA &= ~(1 << 2); // Clear bit 4
                
                _delay_ms(100);
                lcd_out(1, 1, "Motor is running");
                lcd_out(2, 1, "Anticlockwise");
            }// by using PIN function inside the if condition we are going to check the status of the particular pin.
            OCR0 = VAR;// here initially we are giving the VAR value to the OC0 register.
    }
}

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.