Project 1 - Controlling a DC motor using PWM and monitoring its Running status
#include <avr/io.h>
#define F_CPU 16000000L
#include <util/delay.h>
#include <avr/interrupt.h>
#define lcdport PORTC // Port C is used as lcd port
#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 sw (PIND&(1<<7))
unsigned char i;
void lcd_cmd(unsigned char cmd)
{
lcdport=cmd;
rs_low;
en_low;
_delay_ms(1);
en_high;
}
void lcd_data(unsigned char data)
{
lcdport=data;
rs_high;
en_low;
_delay_ms(1);
en_high;
}
void lcd_init()
{
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 curs_pos(char x,char y)
{
if((x<1 || x>2) || (y<1 || y>16))
{
x=1;
y=1;
}
if(x==1)
lcd_cmd(0x7F+y);
else
lcd_cmd(0xBF+y);
}
void lcd_out(char x, char y,char *str)
{
curs_pos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
int adc_read(char channel)
{
unsigned int a,result;
ADMUX = channel;
ADCSRA = 0x80;
ADCH = 0x00;
ADCL = 0x00;
ADCSRA |= (1<<6);
while ((ADCSRA & 0x40) != 40);
a = ADCL;
result = ADCH;
result = result<<8;
result = result | a;
return result;
}
void lcd_print(char row, char col, unsigned int value,int digits)
{
unsigned int temp;
unsigned int unit;
unsigned int ten;
unsigned int hundred;
unsigned int thousand;
unsigned int million;
unsigned char flag = 0;
if (row==0||col ==0)
{
curs_pos(1,1);
}
else
{
curs_pos(row,col);
}
if((digits==5) || (flag ==1))
{
million = value/10000+48;
lcd_data(million);
flag = 1;
}
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;
ten = temp%10 + 48;
lcd_data(ten);
flag = 1;
}
if((digits==1) || (flag ==1))
{
unit = value%10 + 48;
lcd_data(unit);
}
if(digits>5)
{
lcd_data('e');
}
}
int main(void)
{
lcd_init();
DDRD &= ~(1<<2); // push button to control the speed
PORTD |= (1<<2); // Enabling the pull up resistor
DDRD &= ~(1<<7); // Making the pin 7 of port D as input. Power switch to switch on the motor
PORTD |= (1<<7); // Enabling the pull up resistor
DDRA = 0xFF; // Making the entire port as output as the motor driver is connected.
i=64;
OCR0 = i; // Loading the duty cycle value to OCR0 register.
TCCR0 = 0x61; // Configuring the TCCR register.
DDRB |= (1<<3); // Making the pin 3 of port B as output as it is connected with Motor driver.
GICR |= (1<<INT0); // Enabling the interrupt bit.
MCUCR = 0x02;
sei(); // Enabling the global interrupt
lcd_out(1,1,"Dir:");
while (1)
{
if (sw==0)
{
PORTA=0x01;
lcd_out(1,5,"Clock ");
}
else
{
PORTA=0x02;
lcd_out(1,5,"AntiClock ");
}
OCR0 = i;
}
return 0;
}
ISR (INT0_vect)
{
i = i+10; // Changing the duty cycle value; Incrementing my 10.
}