Project 1 - Controlling a DC motor using PWM and monitoring its Running status
/*****************************************************************************************
* NAME : project1lcd.c
* Description : To run a dc motor using L293 driver and monitor its running status
* Created : 08-12-2022 22:49:24
* Author : sarath
*******************************************************************************************/
#include <avr/io.h>
#define F_CPU 16000000L
#include <util/delay.h>
#include <avr/interrupt.h>
#define rs_high() PORTD |=(1<<0);
#define rs_low() PORTD &= ~(1<<0);
#define en_high() PORTD |= (1<<1);
#define en_low() PORTD &= ~(1<<1);
#define lcdport PORTB
#define clock_wise() PORTA = (1<<0)|(0<<1);
#define anti_clock() PORTA = (0<<0)|(1<<1)
uint8_t flag=0;
int i=96;
void lcd_command(unsigned char cmd)
{
lcdport = cmd;
rs_low();
en_high();
_delay_ms(1);
en_low();
}
void lcd_data(unsigned char dat)
{
lcdport = dat;
rs_high();
en_high();
_delay_ms(1);
en_low();
}
void lcd_init()
{
lcd_command(0x38); //2lines 5*8 matrix
_delay_ms(5);
lcd_command(0x02); //Return home
_delay_ms(5);
lcd_command(0x01); //clear display
_delay_ms(5);
lcd_command(0x0c); //Display on, cursor off
_delay_ms(5);
lcd_command(0x06); //Shift the cursor right
_delay_ms(5);
lcd_command(0x80); //Force the cursor to the beginning of the 1st line
_delay_ms(5);
}
void cursorpos(char x, char y)
{
if( (x < 1 || x > 2) || (y < 1 || y > 16) ) //if cursor crosses bounds of lcd 2*16
{
x = 1;
y = 1;
}
if(x == 1)
lcd_command(0x7F+y);
else
lcd_command(0xBF+y);
}
void lcd_out(char x,char y,char *str)
{
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
void pwminit()
{
TCCR1B = 0b00000100; //Waveform Generation bit setting,prescalar=256
TCCR1A = 0b10000001; //TOP setting, 8bit PWM in phase correct, MAX = 255
DDRD |=(1<<5); //bit 1 of port b as output its used for L293 enable
}
int main(void)
{
DDRA |= (1<<0)|(1<<1); //Set pino 0 and 1 as output for switching in L293
DDRB=0xff; //set the portB as lcdport output
DDRD|=(1<<0)|(1<<1); //Set as Output for lcd rs and en
lcd_init();
pwminit();
sei(); // enable the global interrupt
GICR=(1<<7)|(1<<6); // to enable INT1 and INT0
PORTD=(1<<2)|(1<<3); //setting interrupt pins by enabling pullup
while(1)
{
OCR1A = i; //loading comparator reg with i for duty cycle set
if (flag==0)
{
lcd_command(0x01);_delay_ms(5);
lcd_out(1,1,"rotating ");
lcd_out(2,1,"anti clockwise....");
}
else
{
lcd_command(0x01);_delay_ms(5);
lcd_out(1,1,"rotating ");
lcd_out(2,1,"clockwise....");
}
//OC1A toggle config
TCCR1A |= (0<< 7);
_delay_ms(1000);
}
}
ISR(INT0_vect) //when the push button at PD2 pressed LED get ON(INT0 AT PD2 PIN)
{
if(i<256) //incrementing till max duty cycle
{
i=i+16;
if(i>255)
i=255;
_delay_ms(100);
}
}
ISR(INT1_vect) //when the push button at PD3 pressed LED get off(INT1 AT PD3 PIN)
{
if (flag==0) //to roatate clockwise
{
clock_wise();
flag=1;
}
else
{
//to rotate anticlockwise
}
{
anti_clock();
flag=0;
}
}