From 037f7ce38a085118b8bb5413b612c9366451a4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A7=D0=B5=D1=80?= =?UTF-8?q?=D1=82=D0=BA=D0=BE=D0=B2?= Date: Thu, 11 May 2023 08:24:30 +0000 Subject: [PATCH 1/8] lcd --- пример с библиотеками ардуино.txt | 55 ++++++++++++++++++ типо с.txt | 93 +++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 пример с библиотеками ардуино.txt create mode 100644 типо с.txt diff --git a/пример с библиотеками ардуино.txt b/пример с библиотеками ардуино.txt new file mode 100644 index 0000000..e843baa --- /dev/null +++ b/пример с библиотеками ардуино.txt @@ -0,0 +1,55 @@ +#include +#include + +LiquidCrystal_I2C lcd(32, 16, 2); + +byte MasArray[32] = { + 78, 69, 71, 82, 32, 77, 65, 78, 68, 65, 82, 73, 78, 33, 33, 33, + 32, 32, 32, 32, 46, 32, 32, 32, 32, 46, 32, 32, 32, 46, 37, 33 +}; + +char colum1[17]; +char colum2[17]; + +unsigned long previousTime = 0; +const unsigned long interval = 200; + +void delay_ms(unsigned long milliseconds) { + unsigned long startTime = millis(); + while (millis() - startTime < milliseconds) { + // Wait until the specified time has passed + } +} + +void setup() { + Serial.begin(9600); + lcd.init(); + lcd.backlight(); + + for (int i = 0; i < 32; i++) { + if (i < 16) { + colum1[i] = (char)MasArray[i]; + } else { + colum2[i - 16] = (char)MasArray[i]; + } + } + colum1[16] = '\0'; + colum2[16] = '\0'; +} + +void loop() { + unsigned long currentTime = millis(); + + if (currentTime - previousTime >= interval) { + previousTime = currentTime; + + for (int i = 15; i > 0; i--) { + lcd.setCursor(i, 0); + lcd.print(colum1); + lcd.setCursor(0, 1); + lcd.print(colum2); + delay_ms(200); // Use the custom delay_ms() function instead of delay() + lcd.clear(); + } + } +} diff --git a/типо с.txt b/типо с.txt new file mode 100644 index 0000000..9d293cc --- /dev/null +++ b/типо с.txt @@ -0,0 +1,93 @@ +#include + +#define LCD_ADDRESS 0x27 +#define LCD_ROWS 2 +#define LCD_COLUMNS 16 + +byte MasArray[32] = { +78, 69, 71, 82, 32, 77, 65, 78, 68, 65, 82, 73, 78, 33, 33, 33, +32, 32, 32, 32, 46, 32, 32, 32, 32, 46, 32, 32, 32, 46, 37, 33 +}; + +char colum1[17]; +char colum2[17]; + +unsigned long previousTime = 0; +const unsigned long interval = 200; + +void delay_ms(unsigned long milliseconds) { +unsigned long startTime = millis(); +while (millis() - startTime < milliseconds) { +// Wait until the specified time has passed +} +} + +void lcdCommand(uint8_t command) { +Wire.beginTransmission(LCD_ADDRESS); +Wire.write(0x00); +Wire.write(command); +Wire.endTransmission(); +} + +void lcdWrite(uint8_t value) { +Wire.beginTransmission(LCD_ADDRESS); +Wire.write(0x40); +Wire.write(value); +Wire.endTransmission(); +} + +void lcdSetCursor(uint8_t row, uint8_t col) { +uint8_t row_offsets[] = { 0x00, 0x40 }; +uint8_t offset = row_offsets[row] + col; +lcdCommand(0x80 | offset); +} + +void lcdClear() { +lcdCommand(0x01); // Clear display +delay_ms(2); // Delay for clear display command +} + +void lcdInit() { +Wire.begin(); +lcdCommand(0x38); // Function set: 8-bit mode, 2 lines, 5x8 font +lcdCommand(0x0C); // Display control: Display ON, Cursor OFF, Blinking OFF +lcdClear(); +} + +void lcdPrint(const char* str) { +while (*str) { +lcdWrite(*str++); +} +} + +void setup() { +Serial.begin(9600); +lcdInit(); + +for (int i = 0; i < 32; i++) { +if (i < 16) { +colum1[i] = (char)MasArray[i]; +} else { +colum2[i - 16] = (char)MasArray[i]; +} +} +colum1[16] = '\0'; +colum2[16] = '\0'; +} + +void loop() { +unsigned long currentTime = millis(); + +if (currentTime - previousTime >= interval) { +previousTime = currentTime; + +for (int i = 15; i > 0; i--) { +lcdSetCursor(i, 0); +lcdPrint(colum1); +lcdSetCursor(0, 1); +lcdPrint(colum2); +delay_ms(200); // Use the custom delay_ms() function instead of delay() +lcdClear(); +} +} +} From be7bedb8c727a3163805525f8ba34ebac4f95044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A7=D0=B5=D1=80?= =?UTF-8?q?=D1=82=D0=BA=D0=BE=D0=B2?= Date: Thu, 15 Jun 2023 16:29:15 +0000 Subject: [PATCH 2/8] 1602 --- Disp1602.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Disp1602.cpp diff --git a/Disp1602.cpp b/Disp1602.cpp new file mode 100644 index 0000000..e79b898 --- /dev/null +++ b/Disp1602.cpp @@ -0,0 +1,87 @@ +#include + +#include + +LiquidCrystal_I2C lcd(0x27, 16, 2); + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void setup() { + lcd.begin(16, 2); + 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 + + // Вывод данных на экран + lcd.setCursor(0, 0); + lcd.print(displayArray); + + lcd.setCursor(0, 1); + lcd.print(displayArray + 16); // Вывод второй половины displayArray +} + +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); +} \ No newline at end of file From 97f38c92d53a4c63fcc666216b7a85ab0795b6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=94=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=D1=87=D0=B5=D0=B2?= Date: Sat, 29 Jul 2023 13:50:30 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D0=BB(=D0=B0)=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20''?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- display_functions.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ display_functions.h | 24 +++++++++++++++++ i2c_functions.c | 24 +++++++++++++++++ i2c_functions.h | 12 +++++++++ main.c | 53 +++++++++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+) create mode 100644 display_functions.c create mode 100644 display_functions.h create mode 100644 i2c_functions.c create mode 100644 i2c_functions.h create mode 100644 main.c diff --git a/display_functions.c b/display_functions.c new file mode 100644 index 0000000..76b8f9d --- /dev/null +++ b/display_functions.c @@ -0,0 +1,64 @@ +#include "display_functions.h" +#include + +#define LCD_ADDRESS 0x27 // Адрес дисплея на шине I2C +#define LCD_WIDTH 16 // Ширина дисплея в символах +#define LCD_HEIGHT 2 // Высота дисплея в строках + +void lcd_send_command(uint8_t command) { + Wire.beginTransmission(LCD_ADDRESS); + i2c_send_byte(0x80); // Co = 0, Rs = 0 (управляющий байт) + i2c_send_byte(command); + Wire.endTransmission(); +} + +void lcd_send_data(uint8_t data) { + Wire.beginTransmission(LCD_ADDRESS); + i2c_send_byte(0xC0); // Co = 0, Rs = 1 (байт данных) + i2c_send_byte(data); + Wire.endTransmission(); +} + +void lcd_send_string(const char *str) { + while (*str) { + lcd_send_data(*str); + str++; + } +} + +void lcd_clear() { + lcd_send_command(0x01); // Очистка дисплея + _delay_ms(2); // Небольшая пауза для завершения очистки +} + +void lcd_init() { + Wire.begin(); + lcd_send_command(0x38); // Установка интерфейса: 8 бит данных, 2 строки, 5x8 точек + lcd_send_command(0x08); // Отключение дисплея, курсора и мигания курсора + lcd_send_command(0x01); // Очистка дисплея + _delay_ms(2); // Небольшая пауза для завершения очистки + lcd_send_command(0x06); // Установка направления текста: курсор увеличивается, сдвиг дисплея + lcd_send_command(0x0C); // Включение дисплея без курсора и мигания курсора +} + +void lcd_print_char(char c) { + lcd_send_data(c); +} + +void lcd_print_string(const char *str) { + lcd_send_string(str); +} + +void lcd_update(const DisplayData *displayData, const TextCounter *textCounter) { + lcd_clear(); // Очистка дисплея перед выводом новой информации + + // Вывод данных на первую строку + lcd_send_command(0x80); // Установка курсора на начало первой строки + lcd_send_string(displayData->topLine); + + // Вывод данных на вторую строку + lcd_send_command(0xC0); // Установка курсора на начало второй строки + char buffer[17]; + snprintf(buffer, sizeof(buffer), "%d.%d.%d", displayData->value1, displayData->value2, displayData->value3); + lcd_send_string(buffer); +} diff --git a/display_functions.h b/display_functions.h new file mode 100644 index 0000000..0d25b61 --- /dev/null +++ b/display_functions.h @@ -0,0 +1,24 @@ +#ifndef DISPLAY_FUNCTIONS_H +#define DISPLAY_FUNCTIONS_H + +#include "i2c_functions.h" +#include + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +void lcd_init(); +void lcd_print_char(char c); +void lcd_print_string(const char *str); +void lcd_update(const DisplayData *displayData, const TextCounter *textCounter); + +#endif diff --git a/i2c_functions.c b/i2c_functions.c new file mode 100644 index 0000000..5ccac3f --- /dev/null +++ b/i2c_functions.c @@ -0,0 +1,24 @@ +#include "i2c_functions.h" +#include + +// Здесь можно вставить код инициализации I2C, если требуется + +void i2c_delay() { + _delay_us(2); +} + +void i2c_start() { + // Реализация отправки стартового условия I2C +} + +void i2c_stop() { + // Реализация отправки стопового условия I2C +} + +void i2c_send_byte(uint8_t data) { + // Реализация отправки одного байта данных по I2C +} + +void i2c_send_bytes(const uint8_t *data, uint8_t length) { + // Реализация отправки массива данных (длиной length) по I2C +} diff --git a/i2c_functions.h b/i2c_functions.h new file mode 100644 index 0000000..555e732 --- /dev/null +++ b/i2c_functions.h @@ -0,0 +1,12 @@ +#ifndef I2C_FUNCTIONS_H +#define I2C_FUNCTIONS_H + +#include + +void i2c_delay(); +void i2c_start(); +void i2c_stop(); +void i2c_send_byte(uint8_t data); +void i2c_send_bytes(const uint8_t *data, uint8_t length); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..1fa31e8 --- /dev/null +++ b/main.c @@ -0,0 +1,53 @@ +#include +#include +#include "display_functions.h" + +// Основной код вашего проекта + +int main() { + // Настройка портов и другие инициализации + + lcd_init(); // Инициализация дисплея + + // Ваш код в функции setup() + + while (1) { + 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 + + // Вывод данных на экран + lcd.setCursor(0, 0); + lcd.print(displayArray); + lcd.setCursor(0, 1); + lcd.print(displayArray + 16); // Вывод второй половины displayArray + + // Ваш код в функции loop() может быть здесь или в другом месте + + // Обновление данных на дисплее + lcd_update(&displayData, &textCounter); + } + + return 0; +} From 8dade4f9a009fe69a81d4c9d34e5999dc1853f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A7=D0=B5=D1=80?= =?UTF-8?q?=D1=82=D0=BA=D0=BE=D0=B2?= Date: Thu, 28 Sep 2023 14:26:24 +0000 Subject: [PATCH 4/8] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D0=BB(=D0=B0)=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20''?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lcdpcf8574.cpp | 316 ++++++++++++++++++++++++++++++++++++++++++++++ lcdpcf8574.h | 110 ++++++++++++++++ pcf8574.cpp | 115 +++++++++++++++++ pcf8574.h | 21 +++ sketch_sep19a.ino | 83 ++++++++++++ 5 files changed, 645 insertions(+) create mode 100644 lcdpcf8574.cpp create mode 100644 lcdpcf8574.h create mode 100644 pcf8574.cpp create mode 100644 pcf8574.h create mode 100644 sketch_sep19a.ino diff --git a/lcdpcf8574.cpp b/lcdpcf8574.cpp new file mode 100644 index 0000000..e0829c3 --- /dev/null +++ b/lcdpcf8574.cpp @@ -0,0 +1,316 @@ +#include "MyLCD.h" + +// задержеки через асемблер +#define lcd_e_delay() __asm__ __volatile__( "rjmp 1f\n 1:" ); +#define lcd_e_toggle() toggle_e() + + +volatile uint8_t dataport = 0; + +static void toggle_e(void); + +// сама реализация задержек +static inline void _delayFourCycles(unsigned int __count) +{ + if ( __count == 0 ) + __asm__ __volatile__( "rjmp 1f\n 1:" ); + else + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" + "brne 1b" + : "=w" (__count) + : "0" (__count) + ); +} + +// тупа оборачиваем функцию в макрос +#define delay(us) _delayFourCycles( ( ( 1*(F_CPU/4000) )*us)/1000 ) + +// переключение пина для начала записи команды +static void toggle_e(void) +{ + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); +} + + +// отправка байта для контроллера LCD +static void lcd_write(uint8_t data,uint8_t rs) +{ + if (rs) //отправка данных (RS=1, RW=0) + dataport |= _BV(LCD_RS_PIN); + else // отпрака инструкций(RS=0, RW=0) + dataport &= ~_BV(LCD_RS_PIN); + dataport &= ~_BV(LCD_RW_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + // отправка старшего полубайта + dataport &= ~_BV(LCD_DATA3_PIN); + dataport &= ~_BV(LCD_DATA2_PIN); + dataport &= ~_BV(LCD_DATA1_PIN); + dataport &= ~_BV(LCD_DATA0_PIN); + if(data & 0x80) dataport |= _BV(LCD_DATA3_PIN); + if(data & 0x40) dataport |= _BV(LCD_DATA2_PIN); + if(data & 0x20) dataport |= _BV(LCD_DATA1_PIN); + if(data & 0x10) dataport |= _BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + + // отправка младшего полубайта + dataport &= ~_BV(LCD_DATA3_PIN); + dataport &= ~_BV(LCD_DATA2_PIN); + dataport &= ~_BV(LCD_DATA1_PIN); + dataport &= ~_BV(LCD_DATA0_PIN); + if(data & 0x08) dataport |= _BV(LCD_DATA3_PIN); + if(data & 0x04) dataport |= _BV(LCD_DATA2_PIN); + if(data & 0x02) dataport |= _BV(LCD_DATA1_PIN); + if(data & 0x01) dataport |= _BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + + // завершаем передачу + dataport |= _BV(LCD_DATA0_PIN); + dataport |= _BV(LCD_DATA1_PIN); + dataport |= _BV(LCD_DATA2_PIN); + dataport |= _BV(LCD_DATA3_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); +} + +// чтение байта +static uint8_t lcd_read(uint8_t rs) +{ + uint8_t data; + + if (rs) // запись данных (RS=1, RW=0) + dataport |= _BV(LCD_RS_PIN); + else // запись инструкций (RS=0, RW=0) + dataport &= ~_BV(LCD_RS_PIN); + dataport |= _BV(LCD_RW_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + // чтение страшего полубайта + data = pcf8574_getoutputpin(LCD_PCF8574_DEVICEID, LCD_DATA0_PIN) << 4; + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); + + lcd_e_delay(); + + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + // чтение младшего полубайта + data |= pcf8574_getoutputpin(LCD_PCF8574_DEVICEID, LCD_DATA0_PIN) &0x0F; + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); + + return data; +} + +// ждем пока ЖК освободится +static uint8_t lcd_waitbusy(void) + +{ + register uint8_t c; + + // ждем + while ( (c=lcd_read(0)) & (1<= LCD_START_LINE2) && (pos < LCD_START_LINE4) ) + addressCounter = LCD_START_LINE3; + else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) ) + addressCounter = LCD_START_LINE4; + else + addressCounter = LCD_START_LINE1; +#endif + lcd_command((1<>4; + dataport |= _BV(LCD_DATA0_PIN); // _BV(LCD_FUNCTION_8BIT)>>4; + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + // дрючим дисплей чтобы он начал работать + lcd_e_toggle(); + delay(4992); + lcd_e_toggle(); + delay(64); + lcd_e_toggle(); + delay(64); + + // переходим в 4 битный режим + dataport &= ~_BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + delay(64); + + + lcd_command(LCD_FUNCTION_DEFAULT); // настраиваем кол-во строк + lcd_command(LCD_DISP_OFF); // вырубаем дисплей + lcd_clrscr(); // чистим экран + lcd_command(LCD_MODE_DEFAULT); // запускаемся в стандартном режиме + lcd_command(dispAttr); // отправляем настройки +} diff --git a/lcdpcf8574.h b/lcdpcf8574.h new file mode 100644 index 0000000..b9059de --- /dev/null +++ b/lcdpcf8574.h @@ -0,0 +1,110 @@ +#ifndef LCD_H +#define LCD_H + +#define LCD_PCF8574_INIT 1 // pcf + +#define LCD_PCF8574_DEVICEID 0 //id - +#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES + +// : / , / +#define LCD_ENTRY_DEC 0x04 // , +#define LCD_ENTRY_DEC_SHIFT 0x05 // , +#define LCD_ENTRY_INC_ 0x06 // , . +#define LCD_ENTRY_INC_SHIFT 0x07 // , + +// / , / , +#define LCD_DISP_OFF 0x08 // +#define LCD_DISP_ON 0x0C // , +#define LCD_DISP_ON_BLINK 0x0D // , , +#define LCD_DISP_ON_CURSOR 0x0E // , +#define LCD_DISP_ON_CURSOR_BLINK 0x0F // , , + +// / +#define LCD_MOVE_CURSOR_LEFT 0x10 // +#define LCD_MOVE_CURSOR_RIGHT 0x14 // +#define LCD_MOVE_DISP_LEFT 0x18 // +#define LCD_MOVE_DISP_RIGHT 0x1C // + +// : +#define LCD_FUNCTION_4BIT_1LINE 0x20 // 4- , , 5x7 +#define LCD_FUNCTION_4BIT_2LINES 0x28 // 4- , , 5x7 +#define LCD_FUNCTION_8BIT_1LINE 0x30 // 8- , , 5x7 +#define LCD_FUNCTION_8BIT_2LINES 0x38 // 8- , , 5x7 + +#define LCD_LINES 2 // - +#define LCD_DISP_LENGTH 16 // - +#define LCD_LINE_LENGTH 0x40 // +#define LCD_START_LINE1 0x00 // DDRM 1 +#define LCD_START_LINE2 0x40 // DDRM 2 +#define LCD_WRAP_LINES 1 // + + + +#define LCD_DATA0_PIN 4 // +#define LCD_DATA1_PIN 5 // +#define LCD_DATA2_PIN 6 // +#define LCD_DATA3_PIN 7 // +#define LCD_RS_PIN 0 // RS +#define LCD_RW_PIN 1 // RW +#define LCD_E_PIN 2 // +#define LCD_LED_PIN 3 // + + +// HD44780U. +#define LCD_CLR 0 // +#define LCD_HOME 1 // +#define LCD_ENTRY_MODE 2 // +#define LCD_ENTRY_INC 1 // +#define LCD_ENTRY_SHIFT 0 // +#define LCD_ON 3 // +#define LCD_ON_DISPLAY 2 // +#define LCD_ON_CURSOR 1 // +#define LCD_ON_BLINK 0 // +#define LCD_MOVE 4 // +#define LCD_MOVE_DISP 3 // +#define LCD_MOVE_RIGHT 2 // +#define LCD_FUNCTION 5 // +#define LCD_FUNCTION_8BIT 4 // 8 +#define LCD_FUNCTION_2LINES 3 // +#define LCD_FUNCTION_10DOTS 2 // +#define LCD_CGRAM 6 // CG RAM +#define LCD_DDRAM 7 // DD RAM +#define LCD_BUSY 7 // + +// +#define LCD_MODE_DEFAULT ((1<= 0 && deviceid < PCF8574_MAXDEVICES)) { + data = pcf8574_pinstatus[deviceid]; + } + return data; +} + +// получаем статус пинов вывода +int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + data = pcf8574_pinstatus[deviceid]; + data = (data >> pin) & 0b00000001; + } + return data; +} + +// настройка вывода +int8_t pcf8574_setoutput(uint8_t deviceid, uint8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) { + pcf8574_pinstatus[deviceid] = data; + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(data); + i2c_stop(); + return 0; + } + return -1; +} + +// установить выходные контакты, заменить фактический статус устройства из pinstart для i2c +int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pinstart - pinlength + 1 >= 0 && pinstart - pinlength + 1 >= 0 && pinstart < PCF8574_MAXPINS && pinstart > 0 && pinlength > 0)) { + uint8_t b = 0; + b = pcf8574_pinstatus[deviceid]; + uint8_t mask = ((1 << pinlength) - 1) << (pinstart - pinlength + 1); + data <<= (pinstart - pinlength + 1); + data &= mask; + b &= ~(mask); + b |= data; + pcf8574_pinstatus[deviceid] = b; + //рестартим + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(b); + i2c_stop(); + return 0; + } + return -1; +} + +// настройка пинов вывода +int8_t pcf8574_setoutputpin(uint8_t deviceid, uint8_t pin, uint8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + uint8_t b = 0; + b = pcf8574_pinstatus[deviceid]; + b = (data != 0) ? (b | (1 << pin)) : (b & ~(1 << pin)); + pcf8574_pinstatus[deviceid] = b; + //рестартим + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(b); + i2c_stop(); + return 0; + } + return -1; +} + +// установка высокого уровня на выходных пинах +int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin) { + return pcf8574_setoutputpin(deviceid, pin, 1); +} + +// установка низкого уровня на выходных пинах +int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin) { + return pcf8574_setoutputpin(deviceid, pin, 0); +} + +// получение входных данных +int8_t pcf8574_getinput(uint8_t deviceid) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) { + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_READ); + data = ~i2c_readNak(); + i2c_stop(); + } + return data; +} + +// получение входного контакта (высокий или низкий) +int8_t pcf8574_getinputpin(uint8_t deviceid, uint8_t pin) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + data = pcf8574_getinput(deviceid); + if(data != -1) { + data = (data >> pin) & 0b00000001; + } + } + return data; +} \ No newline at end of file diff --git a/pcf8574.h b/pcf8574.h new file mode 100644 index 0000000..34a9439 --- /dev/null +++ b/pcf8574.h @@ -0,0 +1,21 @@ +#ifndef PCF8574_H_ +#define PCF8574_H_ + +#define PCF8574_ADDRBASE (0x27) // - + +#define PCF8574_I2CINIT 1 // i2c + +#define PCF8574_MAXDEVICES 1 // - +#define PCF8574_MAXPINS 8 // - + +void pcf8574_init(); +int8_t pcf8574_getoutput(uint8_t deviceid); +int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_setoutput(uint8_t deviceid, uint8_t data); +int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data); +int8_t pcf8574_setoutputpin(uint8_t deviceid, uint8_t pin, uint8_t data); +int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_getinput(uint8_t deviceid); +int8_t pcf8574_getinputpin(uint8_t deviceid, uint8_t pin); +#endif diff --git a/sketch_sep19a.ino b/sketch_sep19a.ino new file mode 100644 index 0000000..2816b91 --- /dev/null +++ b/sketch_sep19a.ino @@ -0,0 +1,83 @@ +#include "MyLCD.h" + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void setup() { + lcd_init(LCD_DISP_ON_BLINK); // инициализация дисплея + lcd_home(); // домой курсор + lcd_led(0); // вкл подсветки + 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 + + // Вывод данных на экран + lcd_gotoxy(0, 0); + lcd_puts(displayArray); + + lcd_gotoxy(0, 1); + lcd_puts(displayArray + 16); // Вывод второй половины displayArray +} + +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); +} From 0a9eb215dbeca8563a8a9e75ea02d44f17f36ad2 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Tue, 7 Nov 2023 12:01:09 +0300 Subject: [PATCH 5/8] uart modified --- UART/circular_buf.c | 36 +++++++++++++ UART/circular_buf.h | 18 +++++++ UART/main.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ UART/timer.c | 23 +++++++++ UART/timer.h | 7 +++ UART/uart.c | 119 ++++++++++++++++++++++++++++++++++++++++++ UART/uart.h | 11 ++++ main.c | 25 --------- uart_module.c | 82 ----------------------------- uart_module.h | 20 ------- 10 files changed, 337 insertions(+), 127 deletions(-) create mode 100644 UART/circular_buf.c create mode 100644 UART/circular_buf.h create mode 100644 UART/main.c create mode 100644 UART/timer.c create mode 100644 UART/timer.h create mode 100644 UART/uart.c create mode 100644 UART/uart.h delete mode 100644 main.c delete mode 100644 uart_module.c delete mode 100644 uart_module.h diff --git a/UART/circular_buf.c b/UART/circular_buf.c new file mode 100644 index 0000000..e1b91c7 --- /dev/null +++ b/UART/circular_buf.c @@ -0,0 +1,36 @@ +#include +#include +#include "circular_buf.h" + + +void initialize_buffer(struct circular_buffer* cb) { + cb->buf_head = 0; + cb->buf_tail = 0; +} +// Проверка, пустой ли буфер +int buffer_empty(const struct circular_buffer* cb) { + return cb->buf_head == cb->buf_tail; +} +// Проверка, заполнен ли буфер +int buffer_full(const struct circular_buffer* cb) { + return (cb->buf_tail + 1) % BUFFER_SIZE == cb->buf_head; //проверяем следующее число, если оно будет совпадать с индексом головы то будет false, при совпадении вывод true +} +// Запись в буфер +void write_buffer(struct circular_buffer* cb, int value) { + if (buffer_full(cb)) { // проверяем, заполнен ли буфер + return; + } + cb->buffer[cb->buf_tail] = value;// записываем значение в элемент массива в хвост + cb->buf_tail = (cb->buf_tail + 1) % BUFFER_SIZE;// присваивается cb->buf_tail, обновляется его значение на следующий индекс в буфере +} +// Чтение элемента +int read_buffer(struct circular_buffer* cb) { + if (buffer_empty(cb)) { // проверка на пустоту + return -1;// -1 как индикатор в случае ошибки + } + int value = cb->buffer[cb->buf_head]; // чтение по индексу головы + cb->buf_head = (cb->buf_head + 1) % BUFFER_SIZE; // увеличиваем индекс на 1 + return value; +} + + diff --git a/UART/circular_buf.h b/UART/circular_buf.h new file mode 100644 index 0000000..22dc139 --- /dev/null +++ b/UART/circular_buf.h @@ -0,0 +1,18 @@ +#ifndef CIRCULAR_BUFFER_H +#define CIRCULAR_BUFFER_H + +#define BUFFER_SIZE 32 + +struct circular_buffer{ + unsigned char buffer[BUFFER_SIZE]; + unsigned char buf_head; + unsigned char buf_tail; +}; + +void initialize_buffer(struct circular_buffer* cb); +int buffer_empty(const struct circular_buffer* cb); +int buffer_full(const struct circular_buffer* cb); +void write_buffer(struct circular_buffer* cb, int value); +int read_buffer(struct circular_buffer* cb); + +#endif /* CIRCULAR_BUFFER_H */ diff --git a/UART/main.c b/UART/main.c new file mode 100644 index 0000000..70784a5 --- /dev/null +++ b/UART/main.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include "timer.h" +#include "circular_buf.h" + +#define F_CPU 16000000 + +struct circular_buffer usartTxBuffer; +struct circular_buffer usartRxBuffer; + +void UART_init(void) { + UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // прерывание по приему и опустошению буфера передачи + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 103; +} + +void UART_send(uint8_t* data, size_t length) { + for (size_t i = 0; i < length; i++) { + if (!buffer_full(&usartTxBuffer)) { + write_buffer(&usartTxBuffer, data[i]); + } else { + break; // если буфер передачи заполнен, то отправка прерывается + } + } + UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера +} + +void USART_put_char(unsigned char sym) { + if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) { + UDR0 = sym; + } else { + if (!buffer_full(&usartTxBuffer)) { + write_buffer(&usartTxBuffer, sym); + } else { + // Буфер передачи полон, обработка ошибки или другая логика + } + } +} + +int get_char(unsigned char* sym) { + if (!buffer_empty(&usartTxBuffer)) { + *sym = read_buffer(&usartTxBuffer); + return 1; // Символ успешно прочитан + } else { + return 0; // Буфер пуст, ошибка чтения + } +} + +void USART_send_str(const unsigned char* data) { + while (*data) { + USART_put_char(*data++); + } +} + +uint32_t receivedByteCount = 0; +// Получение данных из буфера +int UART_receive(uint8_t* data, size_t length) { + char overflow=0; + uint32_t byteCount=0; + uint32_t timeout_ms_mb = 100; + uint32_t timeout_ms = 4; + uint32_t start_time = millis(); + while (buffer_empty(&usartRxBuffer)) { + if ((millis() - start_time) > timeout_ms_mb) { + // Обработка ошибки или таймаута + return -1; + } + } + while(1) + { + + while (!buffer_empty(&usartRxBuffer)) { + int reader = read_buffer(&usartRxBuffer);//прием и запись символа в переменную + if(byteCount<=length){ + data[byteCount] = reader; // запись в массив с индексом byteCount + } + else{ + overflow=1; + } + byteCount++; + + start_time = millis(); + } + if ((millis() - start_time) > timeout_ms) { // если превышение времени в 4 ms + break; + } + + } + return overflow?-1:byteCount; +} + + + +int main(void) { + sei(); + UART_init(); + timerInit(); + DDRD = 0xFF; + uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09}; + //UART_send(buff, sizeof(buff)); + // + //uint8_t receivedData[BUFFER_SIZE]; + //UART_receive(receivedData,sizeof(receivedData)); + //UART_send(receivedData, sizeof(receivedData)); + + while (1) { + //unsigned long currentTime = millis(); + + } + return 0; +} +// прерывание по завершению приема +ISR(USART_RX_vect) { + uint8_t data = UDR0; // читаем из регистра UDR0 + if (!buffer_full(&usartRxBuffer)) { + write_buffer(&usartRxBuffer, data);// записываем символ в буфер приема + } + +} +//перезаписать чтоб освободитть байт, из udr0 diff --git a/UART/timer.c b/UART/timer.c new file mode 100644 index 0000000..a886d1f --- /dev/null +++ b/UART/timer.c @@ -0,0 +1,23 @@ +#include +#include + +static volatile unsigned long timerMillis = 0; + +void timerInit() { + TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); + OCR1A = 249; + TIMSK1 |= (1 << OCIE1A); + sei(); +} + +unsigned long millis() { + unsigned long ms; + cli(); + ms = timerMillis; + sei(); + return ms; +} + +ISR(TIMER1_COMPA_vect) { + timerMillis++; +} \ No newline at end of file diff --git a/UART/timer.h b/UART/timer.h new file mode 100644 index 0000000..f5b07fe --- /dev/null +++ b/UART/timer.h @@ -0,0 +1,7 @@ +#ifndef TIMER_H +#define TIMER_H + +void timerInit(); +unsigned long millis(); + +#endif // TIMER_H \ No newline at end of file diff --git a/UART/uart.c b/UART/uart.c new file mode 100644 index 0000000..d2eaa22 --- /dev/null +++ b/UART/uart.c @@ -0,0 +1,119 @@ +#include +#include +#include + +#define F_CPU 16000000 +#define SIZE_BUF 8 + +// кольцевой буфер +volatile unsigned char usartTxBuf[SIZE_BUF]; +unsigned char txBufTail = 0; // указатель хвоста буфера +unsigned char txBufHead = 0; // указатель головы буфера +volatile unsigned char txCount = 0; // счетчик символов + +uint8_t receive = 0; +uint8_t rx_data = 0; +volatile uint8_t rx_flag = 0; + +void UARTInit(void) { + UCSR1B=0; UCSR1C=0; // Обнулим регистры статуса и контроля + UBRR0H = 0; // Старшие биты регистра скорости + UBRR0L = 103; // Скорость передачи данных 9600 + UCSR0B = (1< 0){ // если буфер не пустой + sym = cycleBuf[head]; // считываем символ из буфера + count--; // уменьшаем счетчик символов + head++; // увеличиваем индекс головы + if (head == SIZE_BUF) head = 0; + } + return sym; +} + +// загрузка строк +void USART_SendStr(unsigned char * data) +{ + unsigned char sym; + while(*data){ // пока не считан символ конца строки + sym = *data++; + USART_PutChar(sym); + } +} +// unsigned char UARTGet() { +// while(!rx_flag); //пока значение флага не станет равно "1" +// rx_flag = 0; +// return rx_data; //возвращет состояние переменной rx_data +// } + +int main(void) { + sei(); + UARTInit(); + DDRL = 0b11111111; // Определим порт "L" на выход + while(1) { + receive = UARTGet(); + receive++; + UARTSend(receive); + } +} + +// обработчик прерывания по завершению передачи +ISR(USART_TXC_vect) { + if (txCount > 0){ // если буфер не пустой + UDR0 = usartTxBuf[txBufHead]; // записываем в UDR символ из буфера + txCount--; // уменьшаем счетчик символов + txBufHead++; // увеличиваем индекс головы буфера + if (txBufHead == SIZE_BUF) + txBufHead = 0; + } + else { + UCSR0B &= ~(0< -#include "config.h" -#include -#include -#include -#include "uart_hal.h" - - -int main(void) -{ - //example - uint8_t data = 'A'; - - uart_init(9600,0); - uart_send_byte(data); - sei(); - while (1) - { - if(uart_read_count() > 0){ - data = uart_read(); - uart_send_byte(data); - } - - } -} \ No newline at end of file diff --git a/uart_module.c b/uart_module.c deleted file mode 100644 index c4cbc2a..0000000 --- a/uart_module.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "uart_hal.h" - -volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0}; -volatile static uint16_t rx_count = 0; -volatile static uint8_t uart_tx_busy = 1; -// кольцевой буффер -ISR(USART_RX_vect){ - - volatile static uint16_t rx_write_pos = 0; - - rx_buffer[rx_write_pos] = UDR0; - rx_count++; - rx_write_pos++; - if(rx_write_pos >= RX_BUFFER_SIZE){ - rx_write_pos = 0; - } - -} - - -ISR(USART_TX_vect){ - uart_tx_busy = 1; -} - - -void uart_init(uint32_t baud,uint8_t high_speed){ - - uint8_t speed = 16; - - if(high_speed != 0){ - speed = 8; - UCSR0A |= 1 << U2X0; - } - - baud = (F_CPU/(speed*baud)) - 1; - - UBRR0H = (baud & 0x0F00) >> 8; - UBRR0L = (baud & 0x00FF); - - UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << TXCIE0) | (1 << RXCIE0); - -} - - -void uart_send_byte(uint8_t c){ - while(uart_tx_busy == 0); - uart_tx_busy = 0; - UDR0 = c; -} - -void uart_send_array(uint8_t *c,uint16_t len){ - for(uint16_t i = 0; i < len;i++){ - uart_send_byte(c[i]); - } -} - -void uart_send_string(uint8_t *c){ - uint16_t i = 0; - do{ - uart_send_byte(c[i]); - i++; - - }while(c[i] != '\0'); - uart_send_byte(c[i]); -} - -uint16_t uart_read_count(void){ - return rx_count; -} - -uint8_t uart_read(void){ - static uint16_t rx_read_pos = 0; - uint8_t data = 0; - - data = rx_buffer[rx_read_pos]; - rx_read_pos++; - rx_count--; - if(rx_read_pos >= RX_BUFFER_SIZE){ - rx_read_pos = 0; - } - return data; -} \ No newline at end of file diff --git a/uart_module.h b/uart_module.h deleted file mode 100644 index 284a941..0000000 --- a/uart_module.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef UART_HAL_H_ -#define UART_HAL_H_ - - -#include -#include "config.h" -#include -#include -#include - -#define RX_BUFFER_SIZE 128 - -void uart_init(uint32_t baud,uint8_t high_speed); -void uart_send_byte(uint8_t c); -void uart_send_array(uint8_t *c,uint16_t len); -void uart_send_string(uint8_t *c); -uint16_t uart_read_count(void); -uint8_t uart_read(void); - -#endif /* UART_HAL_H_ */ \ No newline at end of file From e6a1ad36c216a074f5b5ca87c20692255a0ef8f8 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Tue, 7 Nov 2023 18:02:54 +0300 Subject: [PATCH 6/8] unused files deleted --- UART/uart.c | 119 ---------------------------------------------------- UART/uart.h | 11 ----- 2 files changed, 130 deletions(-) delete mode 100644 UART/uart.c delete mode 100644 UART/uart.h diff --git a/UART/uart.c b/UART/uart.c deleted file mode 100644 index d2eaa22..0000000 --- a/UART/uart.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include - -#define F_CPU 16000000 -#define SIZE_BUF 8 - -// кольцевой буфер -volatile unsigned char usartTxBuf[SIZE_BUF]; -unsigned char txBufTail = 0; // указатель хвоста буфера -unsigned char txBufHead = 0; // указатель головы буфера -volatile unsigned char txCount = 0; // счетчик символов - -uint8_t receive = 0; -uint8_t rx_data = 0; -volatile uint8_t rx_flag = 0; - -void UARTInit(void) { - UCSR1B=0; UCSR1C=0; // Обнулим регистры статуса и контроля - UBRR0H = 0; // Старшие биты регистра скорости - UBRR0L = 103; // Скорость передачи данных 9600 - UCSR0B = (1< 0){ // если буфер не пустой - sym = cycleBuf[head]; // считываем символ из буфера - count--; // уменьшаем счетчик символов - head++; // увеличиваем индекс головы - if (head == SIZE_BUF) head = 0; - } - return sym; -} - -// загрузка строк -void USART_SendStr(unsigned char * data) -{ - unsigned char sym; - while(*data){ // пока не считан символ конца строки - sym = *data++; - USART_PutChar(sym); - } -} -// unsigned char UARTGet() { -// while(!rx_flag); //пока значение флага не станет равно "1" -// rx_flag = 0; -// return rx_data; //возвращет состояние переменной rx_data -// } - -int main(void) { - sei(); - UARTInit(); - DDRL = 0b11111111; // Определим порт "L" на выход - while(1) { - receive = UARTGet(); - receive++; - UARTSend(receive); - } -} - -// обработчик прерывания по завершению передачи -ISR(USART_TXC_vect) { - if (txCount > 0){ // если буфер не пустой - UDR0 = usartTxBuf[txBufHead]; // записываем в UDR символ из буфера - txCount--; // уменьшаем счетчик символов - txBufHead++; // увеличиваем индекс головы буфера - if (txBufHead == SIZE_BUF) - txBufHead = 0; - } - else { - UCSR0B &= ~(0< Date: Wed, 17 Jan 2024 16:11:54 +0300 Subject: [PATCH 7/8] UART modified and added header file --- UART/{main.c => uart.c} | 32 +++++++++++++++++--------------- UART/uart.h | 12 ++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) rename UART/{main.c => uart.c} (66%) create mode 100644 UART/uart.h diff --git a/UART/main.c b/UART/uart.c similarity index 66% rename from UART/main.c rename to UART/uart.c index 70784a5..a0ba34e 100644 --- a/UART/main.c +++ b/UART/uart.c @@ -28,7 +28,7 @@ void UART_send(uint8_t* data, size_t length) { UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера } -void USART_put_char(unsigned char sym) { +void UART_put_char(unsigned char sym) { if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) { UDR0 = sym; } else { @@ -40,38 +40,42 @@ void USART_put_char(unsigned char sym) { } } -int get_char(unsigned char* sym) { - if (!buffer_empty(&usartTxBuffer)) { - *sym = read_buffer(&usartTxBuffer); +int UART_get_char(unsigned char* sym) { + if (!buffer_empty(&usartRxBuffer)) { + *sym = read_buffer(&usartRxBuffer); return 1; // Символ успешно прочитан } else { return 0; // Буфер пуст, ошибка чтения } } -void USART_send_str(const unsigned char* data) { +void UART_send_str(const unsigned char* data) { while (*data) { USART_put_char(*data++); } } -uint32_t receivedByteCount = 0; +//uint32_t receivedByteCount = 0; + // Получение данных из буфера int UART_receive(uint8_t* data, size_t length) { - char overflow=0; - uint32_t byteCount=0; - uint32_t timeout_ms_mb = 100; - uint32_t timeout_ms = 4; + char overflow=0; // Флаг переполнения, который устанавливается, если превышен размер массива + uint32_t byteCount=0; // Счетчик байтов, принятых из буфера приема + uint32_t timeout_ms_mb = 100; // Таймаут в миллисекундах для ожидания первого байта в буфере приема + uint32_t timeout_ms = 4; // Таймаут в миллисекундах для общего времени приема данных uint32_t start_time = millis(); + // Цикл ожидания первого байта в буфере приема с учетом таймаута while (buffer_empty(&usartRxBuffer)) { if ((millis() - start_time) > timeout_ms_mb) { - // Обработка ошибки или таймаута + // Обработка таймаута return -1; } } + //Цикл приема данных с таймаутом while(1) { - + // Пока буфер приема не пуст и не истек таймаут общего времени, + // функция продолжает читать байты из буфера и сохранять их в массив data. while (!buffer_empty(&usartRxBuffer)) { int reader = read_buffer(&usartRxBuffer);//прием и запись символа в переменную if(byteCount<=length){ @@ -89,7 +93,7 @@ int UART_receive(uint8_t* data, size_t length) { } } - return overflow?-1:byteCount; + return overflow?-1:byteCount; // возвращает количество успешно принятых байт или -1 } @@ -108,7 +112,6 @@ int main(void) { while (1) { //unsigned long currentTime = millis(); - } return 0; } @@ -120,4 +123,3 @@ ISR(USART_RX_vect) { } } -//перезаписать чтоб освободитть байт, из udr0 diff --git a/UART/uart.h b/UART/uart.h new file mode 100644 index 0000000..c92e55b --- /dev/null +++ b/UART/uart.h @@ -0,0 +1,12 @@ +#ifndef UART_H +#define UART_H + +void UART_init(void); +void UART_send(uint8_t* data, size_t length); +void UART_put_char(unsigned char sym); +int UART_get_char(unsigned char* sym); +void UART_send_str(const unsigned char* data); +int UART_receive(uint8_t* data, size_t length); + + +#endif /* UART_H */ \ No newline at end of file From 1f38dff368fc41eebc3881d315ffce87e353b16b Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Mon, 29 Jan 2024 19:53:00 +0300 Subject: [PATCH 8/8] uart.c updated and some code refactoring --- UART/timer.c | 4 +--- UART/uart.c | 63 +--------------------------------------------------- UART/uart.h | 12 +++++++--- 3 files changed, 11 insertions(+), 68 deletions(-) diff --git a/UART/timer.c b/UART/timer.c index a886d1f..ca35795 100644 --- a/UART/timer.c +++ b/UART/timer.c @@ -5,16 +5,14 @@ static volatile unsigned long timerMillis = 0; void timerInit() { TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); - OCR1A = 249; + OCR1A = 250; TIMSK1 |= (1 << OCIE1A); sei(); } unsigned long millis() { unsigned long ms; - cli(); ms = timerMillis; - sei(); return ms; } diff --git a/UART/uart.c b/UART/uart.c index a0ba34e..355d7ee 100644 --- a/UART/uart.c +++ b/UART/uart.c @@ -4,11 +4,7 @@ #include #include "timer.h" #include "circular_buf.h" - -#define F_CPU 16000000 - -struct circular_buffer usartTxBuffer; -struct circular_buffer usartRxBuffer; +#include "uart.h" void UART_init(void) { UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // прерывание по приему и опустошению буфера передачи @@ -28,49 +24,12 @@ void UART_send(uint8_t* data, size_t length) { UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера } -void UART_put_char(unsigned char sym) { - if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) { - UDR0 = sym; - } else { - if (!buffer_full(&usartTxBuffer)) { - write_buffer(&usartTxBuffer, sym); - } else { - // Буфер передачи полон, обработка ошибки или другая логика - } - } -} - -int UART_get_char(unsigned char* sym) { - if (!buffer_empty(&usartRxBuffer)) { - *sym = read_buffer(&usartRxBuffer); - return 1; // Символ успешно прочитан - } else { - return 0; // Буфер пуст, ошибка чтения - } -} - -void UART_send_str(const unsigned char* data) { - while (*data) { - USART_put_char(*data++); - } -} - -//uint32_t receivedByteCount = 0; - // Получение данных из буфера int UART_receive(uint8_t* data, size_t length) { char overflow=0; // Флаг переполнения, который устанавливается, если превышен размер массива uint32_t byteCount=0; // Счетчик байтов, принятых из буфера приема - uint32_t timeout_ms_mb = 100; // Таймаут в миллисекундах для ожидания первого байта в буфере приема uint32_t timeout_ms = 4; // Таймаут в миллисекундах для общего времени приема данных uint32_t start_time = millis(); - // Цикл ожидания первого байта в буфере приема с учетом таймаута - while (buffer_empty(&usartRxBuffer)) { - if ((millis() - start_time) > timeout_ms_mb) { - // Обработка таймаута - return -1; - } - } //Цикл приема данных с таймаутом while(1) { @@ -96,30 +55,10 @@ int UART_receive(uint8_t* data, size_t length) { return overflow?-1:byteCount; // возвращает количество успешно принятых байт или -1 } - - -int main(void) { - sei(); - UART_init(); - timerInit(); - DDRD = 0xFF; - uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09}; - //UART_send(buff, sizeof(buff)); - // - //uint8_t receivedData[BUFFER_SIZE]; - //UART_receive(receivedData,sizeof(receivedData)); - //UART_send(receivedData, sizeof(receivedData)); - - while (1) { - //unsigned long currentTime = millis(); - } - return 0; -} // прерывание по завершению приема ISR(USART_RX_vect) { uint8_t data = UDR0; // читаем из регистра UDR0 if (!buffer_full(&usartRxBuffer)) { write_buffer(&usartRxBuffer, data);// записываем символ в буфер приема } - } diff --git a/UART/uart.h b/UART/uart.h index c92e55b..e9fa4eb 100644 --- a/UART/uart.h +++ b/UART/uart.h @@ -1,11 +1,17 @@ #ifndef UART_H #define UART_H +#include +#include +#include "timer.h" +#include "circular_buf.h" + +#define F_CPU 16000000 + +struct circular_buffer usartRxBuffer; +struct circular_buffer usartTxBuffer; void UART_init(void); void UART_send(uint8_t* data, size_t length); -void UART_put_char(unsigned char sym); -int UART_get_char(unsigned char* sym); -void UART_send_str(const unsigned char* data); int UART_receive(uint8_t* data, size_t length);