diff --git a/i2c.c b/i2c.c new file mode 100644 index 0000000..80a180f --- /dev/null +++ b/i2c.c @@ -0,0 +1,136 @@ +#define F_CPU 7372800UL +#include +#include +#include +#include "i2c.h" + +BYTE i2c_stop(void) + { + BYTE error = 0; + + NULL_SCL(); + I2C_DELAY(); + NULL_SDA(); + I2C_DELAY(); + + ONE_SCL(); + I2C_DELAY(); + ONE_SDA(); + I2C_DELAY(); + + if((I2C_PIN & (1 << I2C_SDA)) == 0) error = 2; + if((I2C_PIN & (1 << I2C_SCL)) == 0) error |= 1; + I2C_DELAY(); + I2C_DELAY(); + I2C_DELAY(); + I2C_DELAY(); + + return error; + } + +void i2c_start(void) + { + NULL_SDA(); + I2C_DELAY(); + NULL_SCL(); + I2C_DELAY(); + } + + +void i2c_restart(void) + { + ONE_SDA(); + I2C_DELAY(); + ONE_SCL(); + I2C_DELAY(); + + NULL_SDA(); + I2C_DELAY(); + NULL_SCL(); + I2C_DELAY(); + } + +void i2c_init(void) + { + ONE_SDA(); + ONE_SCL(); + + i2c_stop(); + } + +BYTE i2c_send_byte(BYTE data) + { + BYTE i; + BYTE ask = ACK; + + for(i = 0; i < 8; i++) + { + if((data & 0x80) == 0) + { + NULL_SDA(); + } + else + { + ONE_SDA(); + } + I2C_DELAY(); + ONE_SCL(); + I2C_DELAY(); + NULL_SCL(); + + data = (data << 1); + } + + ONE_SDA(); + I2C_DELAY(); + ONE_SCL(); + I2C_DELAY(); + + if((I2C_PIN & (1 << I2C_SDA)) == (1 << I2C_SDA)) + { + ask = NACK; + } + else + { + ask = ACK; + } + + NULL_SCL(); + + return ask; + } + +BYTE i2c_read_byte(BYTE ask) + { + BYTE byte = 0; + BYTE i; + + ONE_SDA(); + + for(i = 0; i < 8; i++) + { + byte = (byte << 1); + ONE_SCL(); + I2C_DELAY(); + if((I2C_PIN & (1 << I2C_SDA)) == (1 << I2C_SDA)) byte |= 0x01; + NULL_SCL(); + I2C_DELAY(); + } + + if(ask == ACK) + { + NULL_SDA(); + } + else + { + ONE_SDA(); + } + I2C_DELAY(); + ONE_SCL(); + I2C_DELAY(); + NULL_SCL(); + I2C_DELAY(); + ONE_SDA(); + + return byte; + } \ No newline at end of file diff --git a/i2c.h b/i2c.h new file mode 100644 index 0000000..323749f --- /dev/null +++ b/i2c.h @@ -0,0 +1,29 @@ +#ifndef I2C_H_ +#define I2C_H_ + +#define BYTE unsigned char + +#define I2C_DDR DDRC +#define I2C_PORT PORTC +#define I2C_PIN PINC + +#define I2C_SCL PORTC0 +#define I2C_SDA PORTC1 + +#define ACK 0 +#define NACK 1 + +#define I2C_DELAY() _delay_ms(1); + +#define ONE_SCL() { I2C_DDR &= ~(1 << I2C_SCL); I2C_PORT |= (1 << I2C_SCL); } +#define NULL_SCL() { I2C_DDR |= (1 << I2C_SCL); I2C_PORT &= ~(1 << I2C_SCL); } +#define ONE_SDA() { I2C_DDR &= ~(1 << I2C_SDA); I2C_PORT |= (1 << I2C_SDA); } +#define NULL_SDA() { I2C_DDR |= (1 << I2C_SDA); I2C_PORT &= ~(1 << I2C_SDA); } + +BYTE i2c_stop(void); +void i2c_start(void); +void i2c_restart(void); +void i2c_init(void); +BYTE i2c_send_byte(BYTE data); +BYTE i2c_read_byte(BYTE ask); +#endif /* I2C_H_ */ \ No newline at end of file diff --git a/main.ino b/main.ino new file mode 100644 index 0000000..446e049 --- /dev/null +++ b/main.ino @@ -0,0 +1,96 @@ +#include +#include +#include +#include "i2c.h" + +#define LCD_ADDRESS 0x27 + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void setup() { + i2c_init(); + textCounter.startTime = millis(); // Запоминаем время запуска программы +} + +void loop() { + unsigned long currentTime = millis(); // Текущее время + + // Проверяем, прошло ли 500 мс с момента последнего увеличения incrementValue + if (currentTime - textCounter.startTime >= 500) { + textCounter.incrementValue++; // Увеличиваем incrementValue на 1 + textCounter.startTime = currentTime; // Обновляем время + } + + DisplayData displayData; + strncpy(displayData.topLine, "we are responsible for those who have been tame ", sizeof(displayData.topLine) - 1); + displayData.topLine[sizeof(displayData.topLine) - 1] = '\0'; + displayData.value1 = 500; + displayData.value2 = 800; + displayData.value3 = 855; + + // Буферы для заполнения данных + char buffer1[17]; + char buffer2[17]; + + // Заполнение буфера 1 + fillBuffer1(displayData.topLine, buffer1, sizeof(buffer1), textCounter.incrementValue); + + // Заполнение буфера 2 + fillBuffer2(displayData.value1, displayData.value2, displayData.value3, buffer2, sizeof(buffer2)); + + // Создание массива для вывода на дисплей + char displayArray[32]; + strncpy(displayArray, buffer1, 16); // Копирование первых 16 символов из buffer1 в displayArray + strncpy(displayArray + 16, buffer2, 16); // Копирование первых 16 символов из buffer2 в displayArray, начиная с позиции 16 + + // Вывод данных на экран + i2c_start(); + i2c_send_byte(LCD_ADDRESS << 1); + i2c_send_byte(0x80); + for (int i = 0; i < 16; i++) { + i2c_send_byte(displayArray[i]); + } + i2c_send_byte(0xC0); + for (int i = 16; i < 32; i++) { + i2c_send_byte(displayArray[i]); + } + i2c_stop(); + + _delay_ms(500); // Задержка 500 мс +} + +void fillBuffer1(const char *source, char *buffer, size_t bufferSize, int incrementValue) { + int startIndex = incrementValue % strlen(source); // Определяем начальный индекс на основе incrementValue + int endIndex = startIndex + 16; + + if (endIndex > strlen(source)) { + // Если endIndex превышает длину строки source, переносим его на начало строки + endIndex = endIndex - strlen(source); + + // Копируем символы с конца строки source + strncpy(buffer, source + startIndex, strlen(source) - startIndex); + + // Копируем оставшиеся символы с начала строки source + strncat(buffer, source, endIndex); + } else { + strncpy(buffer, source + startIndex, endIndex - startIndex); + } + + buffer[endIndex - startIndex] = '\0'; // Установка нулевого символа в конце буфера +} + +void fillBuffer2(int value1, int value2, int value3, char *buffer, size_t bufferSize) { + snprintf(buffer, bufferSize, "%d.%d.%d", value1, value2, value3); +}