#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define rs PC0
#define en PC1
#define D4 PC2
#define D5 PC3
#define D6 PC4
#define D7 PC5
char column[2] = {0,64};
void lcd_command(unsigned char command)
{
PORTC = (PORTC & 0x03) | ((command & 0xF0) >> 2);
PORTC &= ~(1 << rs);
PORTC |= (1 << en);
_delay_ms(1);
PORTC &= ~(1 << en);
_delay_ms(200);
PORTC = (PORTC & 0x03) | ((command & 0x0F) << 2);
PORTC |= (1 << en);
_delay_ms(1);
PORTC &= ~(1 << en);
_delay_ms(2);
}
void lcd_data(unsigned char data)
{
PORTC = (PORTC & 0x03) | ((data & 0xF0) >> 2);
PORTC |= (1 << rs);
PORTC |= (1 << en);
_delay_ms(1);
PORTC &= ~(1 << en);
_delay_ms(200);
PORTC = (PORTC & 0x03) | ((data & 0x0F) << 2);
PORTC |= (1 << en);
_delay_ms(1);
PORTC &= ~(1 << en);
_delay_ms(2);
}
void set_cursor(uint8_t x,uint8_t y)
{
lcd_command(0x80 + x + column[y]);
}
void lcd_init(void)
{
DDRC |= (1 << rs) | (1 << en) | (1 << D4) | (1 << D5) | (1 << D6) | (1 << D7);
_delay_ms(20);
lcd_command(0x33);
lcd_command(0x32);
lcd_command(0x28);
lcd_command(0x0C);
lcd_command(0x06);
lcd_command(0x01);
_delay_ms(2);
}
void send_string(char *string)
{
while(*string != '\0')
{
lcd_data(*string++);
}
}
void lcd_clear(void)
{
lcd_command(0x01);
_delay_ms(2);
}
void spi_init(void)
{
DDRD |= (1 << PD2) | (1 << PD5) | (1 << PD7);
SPCR |= (1 << SPE) | (1 << SPR0) | (1 << MSTR);
}
uint8_t spi_transfer(uint8_t data)
{
SPDR = data;
while(!(SPSR & (1 << SPIF)));
return SPDR;
}
void setpotent(uint8_t value)
{
PORTD &= ~(1 << PD5);
spi_transfer(0x13);
spi_transfer(value);
PORTD |= (1 << PD5);
}
volatile int8_t encodervalue = 0;
volatile uint8_t potvalue = 64;
void encoder_init(void)
{
DDRD &= ~((1 << PD2) | (1 << PD3));
PORTD |= (1 << PD2) | (1 << PD3);
EICRA |= (1 << ISC10) | (1 << ISC00);
EIMSK |= (1 << INT1) | (1 << INT0);
sei();
}
ISR(INT1_vect)
{
static uint8_t laststate = 0;
uint8_t currentstate = (PIND & ((1 << PD2) | (1 << PD3)));
if(currentstate != laststate)
{
laststate = currentstate;
}
if((currentstate & (1 << PD2)) == ((currentstate & (1 << PD3)) >> 1))
{
encodervalue++;
if(potvalue < 127)
{
potvalue++;
}
else
{
encodervalue--;
if(potvalue > 0)
{
potvalue--;
}
}
}
}
ISR(INT0_vect)
{
static uint8_t laststate = 0;
uint8_t currentstate = (PIND & ((1 << PD2) | (1 << PD3)));
if(currentstate != laststate)
{
laststate = currentstate;
}
if((currentstate & (1 << PD2)) == ((currentstate & (1 << PD3)) >> 1))
{
encodervalue--;
if(potvalue > 0)
{
potvalue--;
}
else
{
encodervalue++;
if(potvalue < 127)
{
potvalue++;
}
}
}
}
void lcd_number(uint8_t number)
{
char buffer[4];
if(number < 10)
{
buffer[0] = '0' + number;
buffer[1] = '\0';
} else if(number < 100)
{
buffer[0] = '0' + number/10;
buffer[1] = '0' + number%10;
buffer[2] = '\0';
}else
{
buffer[0] = '0' + number/100;
buffer[1] = '0' + (number/10)%10;
buffer[2] = '0' + number%10;
buffer[3] = '\0';
}
send_string(buffer);
}
int main(void)
{
lcd_init();
spi_init();
encoder_init();
send_string("digital potent = ");
lcd_command(0xC0);
send_string("value = ");
while(1)
{
setpotent(potvalue);
lcd_command(0xC8);
lcd_number(potvalue);
_delay_ms(100);
}
return 0;
}