#include <avr/io.h> //avr library
#define F_CPU 16000000L //CPU Frequency
#include "avr/interrupt.h" //library to add interrupt
#include <util/delay.h> //library to give delay
#define direction (PIND&(1<<1)) //direction change switch to D1
#define speed (PIND&(1<<2)) //speed control switch to D2
#define power (PINB&(1<<4)) //Power switch to C3
#define lcdport PORTC //LCD connected PORTB
#define rs_high() PORTD |= (1<<6); //object macro for PORTD0 set
#define rs_low() PORTD &= ~(1<<6); //object macro for PORTD0 reset
#define en_high() PORTD |= (1<<7); //object macro for PORTD1 set
#define en_low() PORTD &= ~(1<<7); //object macro for PORTD1 reset
unsigned char i;
//void lcd_cmd(unsigned char cmd)
void lcd_cmd(unsigned char cmd)
{
lcdport = cmd; //send command to the PORTB
rs_low(); //register low to command mode
en_high(); //enable high to feed data
_delay_ms(1);
en_low(); //enable low to stop transfer
}
void lcd_data(unsigned char data)
{
lcdport = data; //send data through PORTB
rs_high(); //register high to data mode
en_high(); //enable high transfer data
_delay_ms(1);
en_low(); //enable low to stop transfer
}
void lcd_init()
{
lcd_cmd(0x38);_delay_ms(5); //4 bit 2 Lines 5x7 matrix Input
lcd_cmd(0x02);_delay_ms(5); //to return home
lcd_cmd(0x01);_delay_ms(5); //to clear screen
lcd_cmd(0x0C);_delay_ms(5); //to display on and cursor blinking
lcd_cmd(0x06);_delay_ms(5); //to increment cursor
lcd_cmd(0x80);_delay_ms(5); //to cursor begin 1st line
}
void cursorpos(char x,char y)
{
if ((x<1 || x>2) || (y<1 || y>16))
{
x=1;
y=1;
} //gives value if wrong input is given
if (x==1)
{
lcd_cmd(0x7F+y);
} //position for first line
else
{
lcd_cmd(0xBF+y); //position for second line
}
}
void lcd_out(char x,char y,char *str)
{
cursorpos(x,y); // to set cursor position
while(*str)
{
lcd_data(*str); // if string has value it is passed to the data as argument
str++;
}
}
int main(void)
{
DDRC = 0xFF; //enable all PORTC Output pins to interface with LCD 16x2
DDRA |= ((1<<0)|(1<<1)); //enable A0 and A1 to interface with L293 Motor driver
DDRD &= ~(1<<1); //enable D1 as input for direction switch
DDRD &= ~(1<<2); //enable D2 as input for speed switch INT0
DDRB &= ~(1<<3); //enable B3 as for PWM to the driver
DDRB &= ~(1<<4); //enable D4 as input for power switch
DDRD |= ((1<<6)|(1<<7)); //enable D6 for LCD reset and D7 for LCD enable pin
PORTD |= (1<<2); //pull up PORTD2 pin for speed switch
PORTB |= (1<<4); //pull up PORTB4 pin for power switch
i=64; //declare the PWM as 25%
TCCR0 = 0x61; //non inverting PWM phase correct Mode, no pre scaler
GICR = (1<<INT0); //enable global interrupt pin INT0
MCUCR = 0x02; //enable interrupt negative edge
lcd_init(); //initialize LCD
sei(); //start interrupt
while (1)
{
while(power == 0) //if power switch toggled enters the loop
{
if(direction==0)//initially motor runs in clockwise direction since the pin is pulled up
{
PORTA = 0b00000001;
lcd_out(1,1,"Motor is Running");
lcd_out(2,3," Clockwise ");
}
else//if direction switch pushed motor rotates anticlockwise
{
PORTA = 0b00000010;
lcd_out(1,1,"Motor is Running");
lcd_out(2,3,"Anticlockwise");
}
OCR0 = i; //sets the pin value incrementing at push using interrupt
}
PORTA = 0x00;//if power button is off PORTA is low motor off
lcd_out(1,1," Motor is OFF STATE ");
lcd_out(2,3,"<_> WARNING ");
}
}
ISR(INT0_vect)//interrupt to increase motor speed every time pushed speed switch connected to INT0 PORTD2
{
i=i+20;
}