Переписал на С, возникает undefined reference, попробую ночью дофиксить.
This commit is contained in:
Андрей Деркачев 2023-06-25 17:58:24 +00:00
parent a7b8634193
commit 4df52b2ab6
3 changed files with 261 additions and 0 deletions

136
i2c.c Normal file
View File

@ -0,0 +1,136 @@
#define F_CPU 7372800UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#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;
}

29
i2c.h Normal file
View File

@ -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_ */

96
main.ino Normal file
View File

@ -0,0 +1,96 @@
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#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);
}