#define F_CPU 10000000UL
#include <avr/io.h>
#include <util/delay.h>
inline uint8_t BIT(uint8_t n)
{
return (1 << n);
}
namespace LCD1602
{
inline void RS_0(void) {PORTD &= ~BIT(0);}
inline void RS_1(void) {PORTD |= BIT(0);}
inline void RW_0(void) {PORTD &= ~BIT(1);}
inline void RW_1(void) {PORTD |= BIT(1);}
inline void E_0(void) {PORTD &= ~BIT(2);}
inline void E_1(void) {PORTD |= BIT(2);}
inline void SetData(uint8_t data) {PORTA = data;}
inline void BeginRead(void) {DDRA = 0x00;}
inline void EndRead(void) {DDRA = 0xff;}
void BusyWait(void)
{
BeginRead();
RS_0();
RW_1();
E_1();
while (PINA & 0x80);
E_0();
EndRead();
}
void WriteCmd(uint8_t cmd)
{
BusyWait();
SetData(cmd);
RS_0();
RW_0();
_delay_ms(1);
E_1();
_delay_ms(1);
E_0();
}
void WriteData(uint8_t data)
{
BusyWait();
SetData(data);
RS_1();
RW_0();
_delay_ms(1);
E_1();
_delay_ms(1);
E_0();
}
void WriteString(const char *s)
{
while (*s)
WriteData(*s++);
}
void Init(void)
{
DDRA = 0xff;
DDRD = 0x7f;
PORTD |= BIT(7);
_delay_ms(15);
WriteCmd(0x38);
_delay_ms(5);
WriteCmd(0x38);
_delay_ms(5);
WriteCmd(0x38);
WriteCmd(0x01);
WriteCmd(0x0c);
}
}
void display(uint16_t i)
{
LCD1602::WriteCmd(0xc0);
LCD1602::WriteData('0' + i % 1000 / 100);
LCD1602::WriteData('0' + i % 100 / 10);
LCD1602::WriteData('0' + i % 10);
}
int main(void)
{
uint16_t i = 0;
LCD1602::Init();
LCD1602::WriteString("Hello World!");
display(i);
while (1)
{
if ((PIND & BIT(7)) == 0)
{
_delay_ms(1);
if ((PIND & BIT(7)) == 0)
{
i++;
display(i);
if (i >= 1000)
i = 0;
while ((PIND & BIT(7)) == 0)
_delay_ms(10);
_delay_ms(200);
}
}
}
}