Микроконтроллер Atmega8, может стать отличной заменой сильно подорожавших плат Arduino Nano. Большое кол-во проектов создаваемых на платах Arduino Nano часто используют небольшое объем памяти и применять Arduino Nano в данных проектах нецелесообразно. В Atmega8 имеет 8 кБ программируемой Flash памяти, 1кБ SRAM памяти и 512 байта EEPROM.
Микроконтроллер Atmega8 поддерживается средой программирования Arduino IDE, так же большинство библиотек совместимы с этими контроллерами.
На этой странице будет рассмотрен пример подключения дисплей LCD1602 оснащенным модулем на PCF8574, который позволяет подключить символьный дисплей 1602 к микроконтроллеру ATmega8 всего по двум проводам SDA и SCL (I2C).
Atmega8
Для использования Atmega8 в Arduino IDE Вам необходимо собрать следующую схему:
Как добавить микроконтроллер Atmega8 в среду программирования Arduino IDE и прошивать микроконтроллер можно узнать из статьи http://rcl-radio.ru/?p=82486
Загрузите тестовый скетч:
#include <avr/io.h> #include <util/delay.h> #define RS 0 #define E 2 #define LED 3 #define ADDR_LED 0x27 byte led_b; int main(){ wire_set(8000000,100000); // тактовая частота контроллера, частота шины I2C setInit(); Clear(); // очистка экрана led(1); // включение и отключение подсветки экрана // собственные символы, 0...7 Write(0, 0b11111, 0b00000, 0b10001, 0b10001, 0b10001, 0b10001, 0b00000, 0b11111); Write(1, 0b11111, 0b10001, 0b11111, 0b10001, 0b11111, 0b10001, 0b11111, 0b00000); Curs(0,0); PrintString("HELLO "); PrintFloat(-1.2344, 3); Curs(1,0); PrintInt(-12345); PrintChar(0); // вывод собственного символа 0 PrintChar(1); // вывод собственного символа 1 while(1){ } } void led(bool led_on_off){ if(led_on_off==1){i2c_write_1bit(led_b |= (1<<LED));} if(led_on_off==0){i2c_write_1bit(led_b &=~ (1<<LED));} } void Write(byte addr_w, byte wr1,byte wr2,byte wr3,byte wr4,byte wr5,byte wr6,byte wr7,byte wr8){ lcd(0b01000000|addr_w*8);PrintChar(wr1);PrintChar(wr2);PrintChar(wr3);PrintChar(wr4);PrintChar(wr5);PrintChar(wr6);PrintChar(wr7);PrintChar(wr8);} void PrintInt(int data_int){char str[6];PrintString(itoa(data_int, str, 10));} void PrintFloat(float data_float, byte dp){ char str[8]; if(data_float<0){data_float=-data_float;PrintChar(0b101101);PrintString(itoa((int)data_float, str, 10));} else{PrintString(itoa((int)data_float, str, 10));} int float10 = round((data_float - (int)data_float)*pow(10,dp)); PrintChar(0b101110); PrintString(itoa(float10, str, 10)); } void setInit(){ lcd(0x03);_delay_us(4500); lcd(0x03);_delay_us(4500); lcd(0x03);_delay_us(200); lcd(0b00000010);_delay_ms(5); lcd(0b00001100);_delay_ms(5); lcd(0b00000001); } void Clear(){lcd(0b00000001);} void Curs(byte str, byte mesto){ if(str==0){lcd(0b10000000+mesto);} if(str==1){lcd(0b11000000+mesto);} } void PrintString(const char* str) {while(*str != '\0') {_delay_us(200);PrintChar(*str);str++;}} void PrintChar(const char chr) {lcdSend(false, (uint8_t)chr);} void e_pin(){ i2c_write_1bit(led_b |= (1<<E)); _delay_us(200); i2c_write_1bit(led_b &= ~(1<<E)); } void lcd(uint8_t sett) {lcdSend(true, sett);} void lcdSend(bool rs, byte data) { if(rs==0){led_b |= (1<<RS);} else {led_b &= ~(1<<RS);}//RS _delay_us(200); if(((data >> 7) & 1) ==1){i2c_write_1bit(led_b |= (1<<7));} else {i2c_write_1bit(led_b &= ~(1<<7));} if(((data >> 6) & 1) ==1){i2c_write_1bit(led_b |= (1<<6));} else {i2c_write_1bit(led_b &= ~(1<<6));} if(((data >> 5) & 1) ==1){i2c_write_1bit(led_b |= (1<<5));} else {i2c_write_1bit(led_b &= ~(1<<5));} if(((data >> 4) & 1) ==1){i2c_write_1bit(led_b |= (1<<4));} else {i2c_write_1bit(led_b &= ~(1<<4));} e_pin(); if(((data >> 3) & 1) ==1){i2c_write_1bit(led_b |= (1<<7));} else {i2c_write_1bit(led_b &= ~(1<<7));} if(((data >> 2) & 1) ==1){i2c_write_1bit(led_b |= (1<<6));} else {i2c_write_1bit(led_b &= ~(1<<6));} if(((data >> 1) & 1) ==1){i2c_write_1bit(led_b |= (1<<5));} else {i2c_write_1bit(led_b &= ~(1<<5));} if(((data >> 0) & 1) ==1){i2c_write_1bit(led_b |= (1<<4));} else {i2c_write_1bit(led_b &= ~(1<<4));} e_pin(); } void i2c_write_1bit(byte i2c_reg){ wire_start_w(ADDR_LED); wire_write(i2c_reg); wire_stop(); } ////// I2C //////////// void wire_set(long f_clock, long i2c_clock){ TWBR = (((f_clock)/(i2c_clock)-16 )/2) ; TWSR = 0; } void wire_start_w(byte i2c_addr){ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); TWDR = i2c_addr << 1; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); } void wire_write(byte i2c_data){ TWDR = i2c_data; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); } void wire_stop(){ TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); }
Скетч использует 3068 байт (37%) памяти устройства. Всего доступно 8192 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 1015 байт для локальных переменных. Максимум: 1024 байт.
После загрузки скетча на дисплее LCD1602 Вы увидите следующее:
Функции управления LCD1602_I2C:
- wire_set(8000000,100000) — тактовая частота контроллера, частота шины I2C
- setInit() — инициализация
- Clear() — очистка дисплея
- led(1) — включение (1) и отключение (0) подсветки дисплея
- Write(а, b) — функция собственных символов (8 символов)
- а — номер символа
- b — массив символа
- Curs(0,0) — номер строки, положение курсора
- PrintString() — вывод String
- PrintFloat(a, b) — вывод Float
- a — число Float
- b — кол-во чисел после запятой
- PrintInt() — вывод int
- PrintChar() — вывод собственного символа