summaryrefslogtreecommitdiff
path: root/_PROGRAMs
diff options
context:
space:
mode:
authorvlapa <vlapa@ya.ru>2026-06-13 20:33:26 +0300
committervlapa <vlapa@ya.ru>2026-06-13 20:33:26 +0300
commite5abc1fe99340b979b18864d978179f71fe8f5c5 (patch)
tree98fd0ad7c6d0744894d6e74e446daacd9e6dd1b5 /_PROGRAMs
First
Diffstat (limited to '_PROGRAMs')
-rw-r--r--_PROGRAMs/C++/C UART.md165
-rw-r--r--_PROGRAMs/C++/MQTT.md29
-rw-r--r--_PROGRAMs/C++/TIME.md26
-rw-r--r--_PROGRAMs/C++/WiFi.md40
-rw-r--r--_PROGRAMs/C++/snprintf.md48
-rw-r--r--_PROGRAMs/C++/УСРЕДНЕНИЕ.md67
-rw-r--r--_PROGRAMs/ESP8266-ESP32/EEPROM.md33
-rw-r--r--_PROGRAMs/ESP8266-ESP32/RTC память.md15
8 files changed, 423 insertions, 0 deletions
diff --git a/_PROGRAMs/C++/C UART.md b/_PROGRAMs/C++/C UART.md
new file mode 100644
index 0000000..f58dd7c
--- /dev/null
+++ b/_PROGRAMs/C++/C UART.md
@@ -0,0 +1,165 @@
+# Работа с UART (Си)
+
+Рассмотрим передачу и приём сообщения по UART подробнее (на Си).
+
+Сконфигурировать UART на передачу и приём сообщения на Си также просто как и на ассемблере мультиклеточного процессора.
+Кроме того на Си для работы с UART доступны полезные функции и макросы, такие как вывод значения типа int, вывод строки,
+вывод заданного массива памяти данных.
+
+В приведённых ниже примерах кода используется библиотека для работы с UART, которую необходимо подключить:
+
+#include <uart.h>
+
+## а) Передача по UART
+
+### 1. Настраиваем UART на передачу
+
+Первым шагом задаём структуру (все элементы структуры можно посмотреть в файле uart.h).
+
+UART_InitTypeDef UART_InitStructure;
+
+Затем инициализируем нужные параметры (незаданные параметры по умолчанию инициализируются нулём).
+
+ UART_InitStructure.BaudRate = 38400; //скорость обмена данными
+ UART_InitStructure.TypeParity = 0x00000000; //тип контроля четности
+ UART_InitStructure.Parity = 0x00000000; //разрешение контроля четности
+ UART_InitStructure.FlowControl = 0x00000000; //разрешение аппаратного контроля
+ UART_InitStructure.Mode = 0x00000002; //разрешение передачи
+
+
+Инициализация для UART0:
+
+uart_init(UART0, &UART_InitStructure);
+
+
+Для UART3:
+
+uart_init(UART3, &UART_InitStructure);
+
+### 2. Разрешаем альтернативные функции порта
+
+Для UART0:
+
+GPIOB->BPS = 0x00000F00;
+
+Для UART3:
+
+GPIOD->BPS = 0x00000F00;
+
+### 3. Проверка буфера передатчика на полноту
+
+Для UART0:
+
+while(UART_FIFO_TX_FULL(UART0) == 1);
+
+Для UART3:
+
+while(UART_FIFO_TX_FULL(UART3) == 1);
+
+### 4.Передача байта по UART
+
+Для UART0:
+
+UART_SEND_BYTE(0xAB, UART0);
+
+Для UART3:
+
+UART_SEND_BYTE(0xAB, UART3);
+
+В результате можно получить простой пример по отправке байта по UART со скоростью 38400 Кбит/с:
+
+Для UART0:
+
+#include <HDL51001_ccf.h>
+#include <uart.h>
+
+void main()
+{
+ UART_InitTypeDef UART_InitStructure;
+
+ UART_InitStructure.BaudRate = 38400; //скорость обмена данными
+ UART_InitStructure.TypeParity = 0x00000000; //тип контроля четности
+ UART_InitStructure.Parity = 0x00000000; //разрешение контроля четности
+ UART_InitStructure.FlowControl = 0x00000000; //разрешение аппаратного контроля
+ UART_InitStructure.Mode = 0x00000002; //разрешение передачи
+
+ uart_init(UART0, &UART_InitStructure);
+
+ GPIOB->BPS = 0x00000F00;
+
+ while(UART_FIFO_TX_FULL(UART0) == 1);
+ UART_SEND_BYTE(0xAB, UART0);
+}
+
+Для UART3 пример можно составить аналогично, только лишь заменив порт B на D и UART0 на UART3.
+
+Переданный байт данных можно получить с помощью программы - монитора COM-порта настроенного на данные с 1 стоп-битом,
+скоростью передачи 38400 кбит/с, размером данных - 8 бит и отключённым контролем чётности.
+
+## б) Приём по UART
+
+Для приёма по UART необходимо:
+
+### 1. Выполнить пункты 1,2 под а)
+
+### 2. Проверить буфер приемника на наличие новых данных
+
+Для UART0:
+
+while(UART_NEW_DATA(UART0) == 0);
+
+Для UART3:
+
+while(UART_NEW_DATA(UART3) == 0);
+
+### 3. Прочитать данные
+
+Для UART0:
+
+rbyte = UART_GET_BYTE(UART0);
+
+Для UART3:
+
+rbyte = UART_GET_BYTE(UART3);
+
+Пример приёма байта данных составить довольно просто по аналогии с передачей байта. Следует заметить, что помимо анализа буфера приемника на
+наличие новых данных, необходимо проверять буфер приёма на полноту.
+
+## API функции UART:
+
+Кроме полезных макросов имеются функции для вывода данных по UART.
+Разберём подробнее каждую функцию, которая объявлена в uart.h
+
+`void uart_init(UART_TypeDef *UART, UART_InitTypeDef* UART_InitStruct)
+
+Функция _uart_init()_ выполняет инициализацию заданного номера UART.
+UART - может принимать значения: UART0, UART1, UART2, UART3
+UART_InitStruct - структура, содержащая элементы конфигурации UART
+
+`void DM2UART(UART_TypeDef *UART, int start_address, int size_block)
+
+Функция _DM2UART ()_ выводит область памяти данных по UART младшим байтом вперёд.
+UART - может принимать значения: UART0, UART1, UART2, UART3
+start_address - начальный адрес памяти данных
+size_block - размер области данных
+
+`void uart_send_str(char *str, UART_TypeDef *UART)
+
+Функция _uart_send_str()_ выводит строку по UART.
+UART - может принимать значения: UART0, UART1, UART2, UART3
+str - строка символов
+
+`void uart_send_int(int str, UART_TypeDef *UART)
+
+Функция _uart_send_int()_ выводит переменную типа int по UART.
+UART - может принимать значения: UART0, UART1, UART2, UART3
+str - переменная типа int
+
+### Замечание:
+
+В версиях библиотеки до 01.04.13 необходимо перед вызовом функций DM2UART (), uart_send_int()
+применять конструкцию:
+
+`while(UART_FIFO_TX_EMPTY(UART0) == 0);
+
+В версиях библиотеки после 01.04.13 функции могут использоваться самостоятельно. \ No newline at end of file
diff --git a/_PROGRAMs/C++/MQTT.md b/_PROGRAMs/C++/MQTT.md
new file mode 100644
index 0000000..c24332e
--- /dev/null
+++ b/_PROGRAMs/C++/MQTT.md
@@ -0,0 +1,29 @@
+
+```C++
+bool reconnect() {
+ Serial.print("MQTT connect : ");
+ Serial.println(mqtt_server);
+ uint8_t countMQTT = 20; // кол-во попыток соединения
+ uint16_t countPause = 500; // пауза между попытками
+ while (!(client.connect(mqtt_client, mqtt_user, mqtt_pass)) && countMQTT--) {
+ Serial.print(countMQTT);
+ Serial.print('>');
+ delay(countPause);
+ }
+ if (client.connected()) {
+ Serial.println("MQTT connected - OK !");
+ String topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempRoom;
+ mqtt_subscribe(client, topic);
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicReboot;
+ mqtt_subscribe(client, topic);
+ return true;
+ } else {
+ return false;
+ }
+}
+```
+
diff --git a/_PROGRAMs/C++/TIME.md b/_PROGRAMs/C++/TIME.md
new file mode 100644
index 0000000..9643b06
--- /dev/null
+++ b/_PROGRAMs/C++/TIME.md
@@ -0,0 +1,26 @@
+
+```C++
+String timeCalc(uint32_t t) {
+ uint32_t timer = t / 1000;
+ uint32_t timeSec = (timer % 3600) % 60;
+ uint32_t timeMin = (timer % 3600) / 60;
+ uint32_t timeHour = timer / 3600 % 24;
+ uint32_t timeDay = timer / 60 / 60 / 24;
+ String s = "";
+ s += timeDay;
+ s += ":";
+ if (timeHour < 10)
+ s += "0";
+ s += timeHour;
+ s += ":";
+ if (timeMin < 10)
+ s += "0";
+ s += timeMin;
+ s += ":";
+ if (timeSec < 10)
+ s += "0";
+ s += timeSec;
+ return s;
+}
+```
+
diff --git a/_PROGRAMs/C++/WiFi.md b/_PROGRAMs/C++/WiFi.md
new file mode 100644
index 0000000..fc47f88
--- /dev/null
+++ b/_PROGRAMs/C++/WiFi.md
@@ -0,0 +1,40 @@
+
+```C++
+const char *ssid = "ssid";
+const char *pass = "passwd";
+
+bool setupWiFi(const char *wifi_ssid, const char *wifi_pass) {
+ digitalWrite(LED_BUILTIN, LOW); // включаем светодиод
+ Serial.print("\n\nSetup WiFi: ");
+ Serial.println(ssid);
+ WiFi.mode(WIFI_STA);
+ uint8_t countWiFi = 20; // кол-во попыток соединения
+ uint16_t countPause = 500; // пауза между попытками
+ WiFi.begin(wifi_ssid, wifi_pass);
+ while ((WiFi.status() != WL_CONNECTED) && countWiFi--) {
+ Serial.print(countWiFi);
+ Serial.print('>');
+ delay(countPause);
+ }
+ digitalWrite(LED_BUILTIN, HIGH); // выключаем светодиод
+ if (WiFi.status() == WL_CONNECTED) {
+ // индикация IP
+ Serial.print("\nWiFi connected - OK !\n");
+ Serial.println(WiFi.localIP());
+ // индикация силы сигнала
+ int16_t dBm = WiFi.RSSI();
+ Serial.print("RSSI dBm = ");
+ Serial.println(dBm);
+ quality_RSSI = 2 * (dBm + 100);
+ if (quality_RSSI >= 100)
+ quality_RSSI = 100;
+ Serial.print("RSSI % = ");
+ Serial.println(quality_RSSI);
+ Serial.println();
+ return true;
+ } else {
+ return false;
+ }
+}
+```
+
diff --git a/_PROGRAMs/C++/snprintf.md b/_PROGRAMs/C++/snprintf.md
new file mode 100644
index 0000000..376e26b
--- /dev/null
+++ b/_PROGRAMs/C++/snprintf.md
@@ -0,0 +1,48 @@
+# snprintf в C/C++: разбираемся с примерами
+
+👋 Привет! В этой статье мы поговорим о функции `snprintf`. В отличие от функции [`sprintf`](https://codelessons.dev/ru/sprintf-in-c-cplusplus/), она принимает дополнительный аргумент: максимальная длинна C-строки, которая будет записана по адресу. Сначала мы посмотрим на сигнатуру этой функции, а потом напишем простую программу, чтобы продемонстрировать работу этой функции. В [конце статьи](https://codelessons.dev/ru/snprintf-in-c-cplusplus/#%D1%83%D0%BF%D1%80%D0%B0%D0%B6%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F) вы найдете упражнения для закрепления материала.
+
+![Иллюстрация snprintf](https://codelessons.dev/static/e86a1cafb44e5cd0493300384183ff37/5a190/snprintf-illustration.png)
+
+## Как отформатировать строку используя snprintf
+
+Функция `snprintf` объявлена в заголовочном файле `<stdio.h>`. В C++ вы также можете использовать `<cstdio>`.
+
+`snprintf` форматирует строку как [`printf`](https://codelessons.dev/ru/printf-in-c-cplusplus/), но записывает результат работы по адресу, вместо того, чтобы вывести строку в стандартный вывод. Также эта функция принимает максимальное количество байтов, которые нужно записать по адресу. Это делает ее более безопасной альтернативой функции `sprintf`.
+
+Прототип этой функции выглядит следующим образом:
+
+```cpp
+int snprintf(char* s, size_t n, const char* format, ...);
+```
+
+- Первым аргументом функция принимает ссылку на начало строки, куда будет записан результат ее работы. В конец строки будет обязательно записан символ ее окончания - `\0`.
+- Вторым аргументом мы передаем максимальное количество байтов, которые будут записаны по адресу (первый аргумент). В максимальное количество байтов включается `\0`.
+- Третьим аргументом передается строка форматирования.
+- Далее передаются дополнительные аргументы. Их количество зависит от используемых [спецификаторов формата](https://codelessons.dev/ru/printf-in-c-cplusplus/#%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D1%8B-%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B0) в строке форматирования (третий аргумент).
+- Возвращает функция длину отформатированной строки (как и `printf`). На это число не влияет максимальное число записанных байтов `n` (второй аргумент).
+
+Теперь давайте посмотрим на простой пример использования этой функции:
+
+```c
+#include <stdio.h>
+
+int main() {
+ int a = 1, b = 2;
+ char s[6];
+
+ int n = snprintf(s, 6, "%d + %d = %d", a, b, a + b);
+
+ printf("s = %s, n = %d", s, n);
+
+ return 0;
+}
+```
+
+Вывод программы:
+
+```console
+s = 1 + 2, n = 9
+```
+
+Как вы можете видеть, функция обрезала строку. Только первые пять символов попали в `s` (только пять, потому что последний символ занимает `\0`). \ No newline at end of file
diff --git a/_PROGRAMs/C++/УСРЕДНЕНИЕ.md b/_PROGRAMs/C++/УСРЕДНЕНИЕ.md
new file mode 100644
index 0000000..3204281
--- /dev/null
+++ b/_PROGRAMs/C++/УСРЕДНЕНИЕ.md
@@ -0,0 +1,67 @@
+
+```C++
+################################################
+// бегущее среднее
+float k = 0.1; // коэффициент фильтрации, 0.0-1.0
+float expRunningAverage(float newVal) {
+ static float filVal = 0;
+ filVal += (newVal - filVal) * k;
+ return filVal;
+}
+
+################################################
+// медиана на 3 значения со своим буфером
+float medianRoom(float newValRoom) {
+ static float bufRoom[3] = {0, 0, 0};
+ if (!(bufRoom[0] + bufRoom[1] + bufRoom[2]))
+ bufRoom[0] = bufRoom[1] = bufRoom[2] = newValRoom;
+ static byte countRoom = 0;
+ bufRoom[countRoom] = newValRoom;
+ if (++countRoom >= 3)
+ countRoom = 0;
+ float dataRoom = (max(bufRoom[0], bufRoom[1]) == max(bufRoom[1], bufRoom[2]))
+ ? max(bufRoom[0], bufRoom[2])
+ : max(bufRoom[1], min(bufRoom[0], bufRoom[2]));
+ // return expRunningAverage(data);
+ return dataRoom;
+}
+
+################################################
+
+# это не совсем средние это апериодичное звено или простейший фильтр НЧ , и он имеет зону не чувствительности, скользящие средние делается через массив, код для ПЫКов , ну думаю разберетесь.
+
+unsigned int ReadADC_AN0(void)
+{ static unsigned char s_ucCount;
+  static unsigned int  m_TempResalt[32];
+  static unsigned int  s_uiSymm;
+  s_ucCount++;
+  s_ucCount&=0b00011111;
+  s_uiSymm -= m_TempResalt[s_ucCount];
+  __delay_us(20); 
+  ADCON0bits.GO_DONE=1;
+  while(ADCON0bits.GO_DONE) continue;
+  __delay_us(5);
+  m_TempResalt[s_ucCount] = ADRESH;
+  m_TempResalt[s_ucCount]<<=8;
+  m_TempResalt[s_ucCount]+= ADRESL;
+  s_uiSymm += m_TempResalt[s_ucCount];
+  return s_uiSymm/32;   
+}
+
+################################################
+// AVR: Усредняем показания:
+// revOld = старое значение
+uint16_t filtr(uint16_t rev)
+{
+ static uint8_t a = pow(2, KOEFF) - 1;
+ (revOld > rev / KOEFF) ? revOld = (a * revOld + rev) >> KOEFF : revOld = rev;
+ return revOld;
+}
+
+################################################
+
+
+################################################
+```
+
diff --git a/_PROGRAMs/ESP8266-ESP32/EEPROM.md b/_PROGRAMs/ESP8266-ESP32/EEPROM.md
new file mode 100644
index 0000000..a32093c
--- /dev/null
+++ b/_PROGRAMs/ESP8266-ESP32/EEPROM.md
@@ -0,0 +1,33 @@
+## Список всех функций библиотеки EEPROM для ESP32, ESP8266 с подробными описаниями:
+
+**1. EEPROM.begin(size):**
+
+Инициализирует эмулированную EEPROM с указанным размером `size` (в байтах). Обычно вызывается в функции `setup()`.
+
+**2. EEPROM.end():**
+
+Завершает работу с эмулированной EEPROM и освобождает зарезервированные ресурсы. Необходимо вызывать, когда вы закончили работу с EEPROM.
+
+**3. EEPROM.write(address, value):**
+
+Записывает значение `value` (байт) в указанный адрес `address` в эмулированной EEPROM.
+
+**4. EEPROM.read(address):**
+
+Считывает байт данных из указанного адреса `address` в эмулированной EEPROM и возвращает это значение.
+
+**5. EEPROM.update(address, value):**
+
+Обновляет значение в указанном адресе `address` в эмулированной EEPROM. Если новое значение отличается от текущего, то происходит запись нового значения.
+
+**6. EEPROM.get(address, data):**
+
+Считывает данные из указанного адреса `address` в эмулированной EEPROM и сохраняет их в переменную `data`. Может использоваться для считывания структур или пользовательских типов данных.
+
+**7. EEPROM.put(address, data):**
+
+Записывает данные из переменной `data` в указанный адрес `address` в эмулированной EEPROM. Может использоваться для записи структур или пользовательских типов данных.
+
+**8. EEPROM.commit():**
+
+Сохраняет все изменения, внесенные в эмулированную EEPROM, во флэш-памяти. Это необходимо вызвать после операций записи, чтобы изменения вступили в силу. \ No newline at end of file
diff --git a/_PROGRAMs/ESP8266-ESP32/RTC память.md b/_PROGRAMs/ESP8266-ESP32/RTC память.md
new file mode 100644
index 0000000..1ea035e
--- /dev/null
+++ b/_PROGRAMs/ESP8266-ESP32/RTC память.md
@@ -0,0 +1,15 @@
+### Сохраняем данные в RTC-память
+
+При работе с платой ESP32 данные можно сохранять в RTC память (точнее, в ее RTC-модуль), она оснащена 8 Кб памяти SRAM, которую называют **«быстрой RTC-памятью»**.
+Хранящиеся в ней данные не стираются во время глубокого сна, но стираются при нажатии на кнопку сброса под названием **«EN»**.
+
+Чтобы сохранить данные в RTC-память, перед объявлением переменной нужно добавить конструкцию:
+```C++
+RTC_DATA_ATTR
+
+# В результате код сохранит переменную **«bootCount»** в RTC-память:
+
+RTC_DATA_ATTR int bootCount = 0;
+```
+
+