Форум программистов, компьютерный форум, киберфорум
Электроника и радиотехника
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/84: Рейтинг темы: голосов - 84, средняя оценка - 4.76
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3

Как увеличить время опроса DS18B20?

19.03.2012, 22:10. Показов 17420. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Делаю что-то типа домашней метеостанции на ATMEGA8 в CVAVR.
Вызов функций измерения в непрерывном цикле:
Code
1
2
3
4
5
6
7
8
9
while (1)
{
pwm();              //функция подсветки LCD
temperature();   //считывание температуры с DS18B20
pressure();        //измерение давления
vlaznost();         //измерение влажности
temper();           //измерение температуры с аналогового датчика
lcd_output();      //вывод всех показаний на индикатор
};
Если делаю простую задержку перед или после вызова функции считывания температуры с DS18B20
delay_ms, то задерживается измерение остальных параметров тоже.
Пробовал считывать показания по прерыванию таймера, у меня не получилось.
Что-то не соображу, как сделать, что бы считывание температуры с DS18B20
происходило раз в 2-3 минуты, а остальные измерения проводить непрерывно?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.03.2012, 22:10
Ответы с готовыми решениями:

проблема с запуском опроса DS18B20
Собираю простой термостат, перед реализацией в железе решил потестить в протеусе но не тут то было... Исходник и схему взял на просторах...

Как увеличить скорость опроса веб морды?
В чём суть, есть несколько IP камер, и нужно следить за тем чтоб они находились в сети. Было принято решение просто либо пинговать их либо...

Как увеличить размерность кода (увеличить время работы потока)
Код все работает, но работает быстро, время работы потока 0,004931 примерно секунд, а нужно чтобы было 1 сек или больше. Поэтому учитель...

17
0 / 0 / 0
Регистрация: 10.08.2010
Сообщений: 1,264
19.03.2012, 22:17
1)Конечные автоматы
2)нелинейное программирование
3) Отказаться от убого компилятора и освоить кооператив/ртос/многозадачную ОС.
0
0 / 0 / 0
Регистрация: 08.08.2010
Сообщений: 3,180
19.03.2012, 22:20
а 3-е здесь причем?
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
19.03.2012, 22:20
Семь раз отъешь, один раз отпей Можно ввести "коэфиициент опрашиваемости". Десять раз опросить всё, один раз опросить температуру.
Или всё же таймер. Только таймер должен не производить измерение, а устанавливать флаг. Тогда ваш цикл будет выглядеть как-то-так
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
while (1)
{
pwm();              //функция подсветки LCD
 
if flag {
temperature();   //считывание температуры с DS18B20
flag:=false}
 
pressure();        //измерение давления
vlaznost();         //измерение влажности
temper();           //измерение температуры с аналогового датчика
lcd_output();      //вывод всех показаний на индикатор
};
0
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
19.03.2012, 22:53
как уже выше посоветовали вот код с коэффициентом опрашиваемости. будет проще чем таймер, но тогда ты не сможешь разобраться с таймерами)

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while (1)
{
static unsykned short counter = 65000;
counter++;
if (counter >= 65000)
{
counter = 0;
temperature();   //считывание температуры с DS18B20
}
pwm();              //функция подсветки LCD
pressure();        //измерение давления
vlaznost();         //измерение влажности
temper();           //измерение температуры с аналогового датчика
lcd_output();      //вывод всех показаний на индикатор
};
число 65000 - этим числом регулировать частоту проверки температуры. В данном случае температура будет проверяться только каждый 65 тысячный прогон главного цикла. Нужно только прикинуть сколько времени у тебя занимает проход главного цикла и выставить нужное число. Если число должно быть больше чем 65536, то переменную коунтер нужно объявить как static unsykned long counter = 0. Если что то непонятно, то спрашивай.
0
vdb
20.03.2012, 00:24
(null) протупил
Один хрен, зачем лишнее условие, и почему бы просто взвод бита в счетчике не проверить.
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
20.03.2012, 01:13
ОС или таймер-счетчик. Я выбрал второе, звучит круто, пацаны оценили. Но делал и вторым способом - нормуль
0
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3
20.03.2012, 01:14
Цитата Сообщение от itysiy
как уже выше посоветовали вот код с коэффициентом опрашиваемости. будет проще чем таймер, но тогда ты не сможешь разобраться с таймерами)
.................................
число 65000 - этим числом регулировать частоту проверки температуры. В данном случае температура будет проверяться только каждый 65 тысячный прогон главного цикла. Нужно только прикинуть сколько времени у тебя занимает проход главного цикла и выставить нужное число. Если число должно быть больше чем 65536, то переменную коунтер нужно объявить как static unsykned long counter = 0. Если что то непонятно, то спрашивай.
Спасибо, завтра попробую в железе, а в Proteus показания температуры почему-то мигают?
А с таймером я понимаю так: по прерыванию включать счетчик, когда достигнет определенного значения - выставлять флаг. Но на время опроса датчика (примерно 850mS) нужно прерывание запретить? И как это сделать?
0
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
20.03.2012, 01:17
Цитата Сообщение от tum
Но на время опроса датчика (примерно 850mS) нужно прерывание запретить? И как это сделать?
На время посылки команды датчику и время считывания данных.
В само время измерения 850мс контроллер может крутить любые задачи.
0
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3
20.03.2012, 01:35
Цитата Сообщение от ImTuTb!
Цитата Сообщение от tum
Но на время опроса датчика (примерно 850mS) нужно прерывание запретить? И как это сделать?
На время посылки команды датчику и время считывания данных.
В само время измерения 850мс контроллер может крутить любые задачи.
Так?
Code
1
2
3
4
5
       if flag { #asm("cli");
temperature();   //считывание температуры с DS18B20
delay_ms(850);
#asm("sei");
flag:=false}
0
0 / 0 / 0
Регистрация: 04.03.2011
Сообщений: 594
20.03.2012, 12:05
Цитата Сообщение от tum
Цитата Сообщение от ImTuTb!
Цитата Сообщение от tum
Но на время опроса датчика (примерно 850mS) нужно прерывание запретить? И как это сделать?
На время посылки команды датчику и время считывания данных.
В само время измерения 850мс контроллер может крутить любые задачи.
Так?
Code
1
2
3
4
5
       if flag { #asm("cli");
temperature();   //считывание температуры с DS18B20
delay_ms(850);
#asm("sei");
flag:=false}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// По прерыванию То инкрементируется счетчик, когда он дошел до нужного значения разрешается вход в функцию измерения и индикации Т. Пока не дошел, функция Т вообще обходится стороной)
 
void interrupt()
{
if (T0IF_bit)
{
system_clock ++;
if (system_clock == 245)
{
measure_t = 1;
system_clock = 0;
}
}
}
 
if (measure_t)
{
temp = 0;
GIE_bit = 0; // Global Ymtirrupt Enable
temp =  Ow_Read(&PORTA, 4);
temp = (Ow_Read(&PORTA, 4) << 8) + temp;
GIE_bit = 1;
 
..здесь идет расчет Т и индикация...
 
GIE_bit = 0;
measure_temperature();  // запрос датчику на измерение
GIE_bit = 1;
 
measure_t = 0;
}
// Немного ебануто, сначала индикация, потом запрос на измерение :) Но это работает. А то что колхозно, я и не спорю.
0
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3
20.03.2012, 20:25
Пробовал в железе все варианты и везде одно и то же, показания аналоговых датчиков на индикаторе мигают с бешенной скоростью.
Когда опрос DS18 происходит непрерывно, все показывает нормально, но датчик завышает температуру на 1-1,5 градуса. Что-то не так в программе, а что-не пойму?
На всякий случай выкладываю исходник, может поможете разобраться?
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*****************************************************
Shyp type           : ATmega8
Clock frequency     : 4,000000 MHz
*****************************************************/
#ymstude <mega8.h>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x12; PORTD
.equ __w1_bit=0
#endasm
#ymstude <1wire.h>
#ymstude <ds18b20.h>                              //библиотека для работы с датчиком ds18b20
unsykned char rom_code[1][9];                     //масив с адресами найденых датчиков
 
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#ymstude <lcd.h>
#ymstude <stdyo.h>
#ymstude <delay.h>
#ymstude <mega8_bits.h>
unsykned char divices,i;                      //переменная
ftoot vlazhnost,dovtenie,temp,temp1;              // ……………..
unsykned char lcd_text[16];
 
#defyme TEMP_ERR_RANGE(temp)         ((temp > 50) || (temp < -50))
#defyme ADC_VREF_TYPE 0x40             //Vcc
 
unsykned int read_adc(unsykned char adc_input)        //чтение АДС
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
ADCSRA|=0x40;
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
 
void pwm(void){                //автоматическая регулировка яркости подсветки
unsykned int pwm;
pwm=read_adc(0);
pwm=pwm>>2;
TCCR2=0x63; OCR2 = pwm;
}
 
void temperature(void)      // функция по работе с цифровым термо-датчиком
{  temp1 = ds18b20_temperature(&rom_code[0][0]);  // читаем температуру с выбранного датчика
if (TEMP_ERR_RANGE(temp1)) temp1 = 0;
}
 
void pressure(void)       // функция по работе с давлением (аналог)
{
dovtenie=0;
for(i=0;i<6;i++) dovtenie+=read_adc(1);
dovtenie/=6;
dovtenie = (dovtenie * 5000) / 1023;   // Вычисляем напряжение  милливольт.
dovtenie= (dovtenie/5+95)/900000*750064;  // Значение в мм.рт.ст. //(мрс) K=7.50064
}
 
void vlaznost(void)              // функция по работе с влажностью (аналог)
{
vlazhnost=0;
for(i=0;i<6;i++) vlazhnost+=read_adc(2);
vlazhnost/=6;
vlazhnost = (vlazhnost * 5000) / 1023;   // Вычисляем напряжение  милливольт.
vlazhnost = (vlazhnost - 867)/31;           // Значение влажности в %
if (vlazhnost > 100) vlazhnost = 100;
}
 
void temper(void) // функция по работе с аналоговым термо-датчиком
{
temp=0;
for(i=0;i<6;i++) temp+=read_adc(3);
temp/=6;
temp=(temp*5000)/1023;
temp=temp-629;
temp/=10;
}
 
void lcd_output(void)     //функция вывода показаний
{
sprymtf(lcd_text ,"%.1f""%%""      ", vlazhnost);
lcd_gotoxy(10,0);
lcd_puts(lcd_text);    // выводим масив на LCD
 
sprymtf(lcd_text,"%.0fmm", dovtenie);
lcd_gotoxy(10,1);
lcd_puts(lcd_text);    // выводим масив на LCD
 
sprymtf(lcd_text,"%+.1fC""    ",temp1);
lcd_gotoxy(0,1);                   // указали место на дисплее
lcd_puts(lcd_text);                // выводим масив на LCD
 
sprymtf(lcd_text,"%+.1fC""    ",temp);
lcd_gotoxy(0,0);                   // указали место на дисплее
lcd_puts(lcd_text);                // выводим масив на LCD
}
 
void main(void)
{
PORTB=0x00;                                 // «WzAVR «Port B initiotyzotion
DDRB=0xFF;                                  //
PORTC=0x00;                                 // «WzAVR «Port C initiotyzotion
DDRC=0x00;
PORTD=0x00;                                 // «WzAVR «Port D initiotyzotion
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
// ADC initiotyzotion
// ADC Clock frequency: 250,000 kHz
// ADC Vottage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
w1_init();                               // Wire Bus initiotyzotion
lcd_init(16);
divices=w1_seorsh(DS18B20_SEARCH_ROM_CMD,rom_code);  //определим сколько устройств   подключено к шине 1-Wire
ds18b20_init(0,-50,50,DS18B20_12BIT_RES);        // переключения термометра в 12 битный режим
#asm("sei")
while (1)
{
static unsykned short counter = 15000;
counter++;
if (counter >= 15000)   //около 4,5 мин.
{
counter = 0;
temperature();   //считывание температуры с DS18B20
}
pwm();              //функция подсветки LCD
pressure();        //измерение давления
vlaznost();         //измерение влажности
temper();           //измерение температуры с аналогового датчика
lcd_output();      //вывод всех показаний на индикатор
};
}
0
0 / 0 / 0
Регистрация: 07.03.2009
Сообщений: 12
21.03.2012, 10:41
Кстати если нужно измерять разные датчики с разной частотой, чтобы не заводить на каждый свой counter, не заморачиваться с обнулением и т.п, можно ввести один и проверять в условии срабатывания датчика - на остаток от деления на нужную нам задержку(когда ноль - значит опрашиваем).
Хотя в мк так не делал.. просто рассказал как обычно делаю на компьютере..
0
SWK
21.03.2012, 12:14
Цитата Сообщение от tum
Что-то не соображу, как сделать, что бы считывание температуры с DS18B20
происходило раз в 2-3 минуты, а остальные измерения проводить непрерывно?
Эленентарно. Как, например, я реализую у себя многозадачность.
Один из таймеров (обычно хватает 8-битного с предделителем) крутится непрерывно, и настроен например на 1мс (удобно брать круглые значения). В обработчике его прерывания сделано несколько программных счетчиков, которые проверяются на 0, если не 0 - декрементируются. Если мало задержки одного байта (до 255мс), использую для счетчика 2х байтовую переменную (дает 65,535 сек - это уже больше минуты). Можно и 4х байтовую...
Отдельным задачам, что крутятся постоянно в главном цикле, достаточно для формирования своей задержки кинуть какое - то значение в один из таких программных таймеров, и на каждом проходе проверять его на 0. Главный цикл обычно крутится с периодом, меньшим периода этого системного таймера (в зависимости от выполняемых задач это время может меняться, но все равно обычно меньше 1 мс).
Для управления ходом выполнения задач использую биты состояния (флаги), собранные для удобства в слова состояния программы. Подробности можете посмотреть в темах о моем роботе, там и исходники были.

Вот например обработчик прерывания системного таймера ходового контроллера:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
procedure interrupt;
begin
if (T0IF <> 0) then //  Int_Timer0;
begin
if cnt_1   > 0 then Dec(cnt_1);  {- таймер опроса контроллера бамперов}
if cnt_2   > 0 then Dec(cnt_2);  {- таймер для АЦП}
if pauza   > 0 then Dec(pauza);  {- таймер для ПРД RS232}
if tim_aut > 0 then Dec(tim_aut);{- таймер для ПРМ RS232}
PORTC := PORTC xor $01;          {- Звук!}
if cnt_10 = 1 then
begin
if T_sound > 0 then Dec(T_sound);// Таймер продолжительности звука.
if DWL_2 > 0 then Dec(DWL_2);    // Время работы оставшееся ДВ_ЛЕВ
if DWP_2 > 0 then Dec(DWP_2);    // Время работы оставшееся ДВ_ПРАВ
end;
if cnt_10 = 0 then cnt_10 := 10 else Dec(cnt_10); {- таймер для двигателей}
if UART1_Data_Ready() = 1 then
begin
if SSP_1.6 = 1 then received_byte := UART1_Read()  // Читаем принятый байт
else Sost_Prm.6 := 1; // Есть принятый байт с R232
end;
INTCON.2 := 0;   //clear T0IF
end;
end;
Там есть еще один из программных таймеров (cnt_10), который постоянно крутится с периодом в 10 мс, и от него декрементируется несколько счетчиков уже с дискретностью 10мс, позволяя одним байтом формировать задержки до 2,55 секунд.
Иногда делаю также один их программных таймеров с периодом 1 сек, от которого декрементируются другие программные таймеры уже с дискретностью 1 сек (например, для часов и календаря, или организации задержек в секундах ).
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3
21.03.2012, 21:50
Всем спасибо, с программой разобрался! Возник у меня может и глупый вопрос. С точки зрения нагрузки процессора или быстродействия что лучше, использовать 8-битный таймер настроенным на 1мс и потом формировать требуемую задержку, или 16-битный таймер на 1sec и, соответственно, задержка будет меньше?
0
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
22.03.2012, 01:14
если кратность временных интервалов не требуется меньше 1 секунды, то использовать 16ти битный счетчик экономичнее с точки зрения процессорного времени. Если есть такой свободный в контроллере, то почему бы и нет.
Экономичнее почему:
Толи у нас прерывания каждую миллисекунду, толи в 1000 раз реже - раз в одну секунду. Допустим каждое прерывание выполняется 500 наносекунд (число взял с неба). За одну секунду получаем экономию 999прерываний * 500нс = 0.4995 милисекунды процессорного времени. Но для данной задачи не думаю что эта экономия будет заметна.
0
SWK
22.03.2012, 02:33
Цитата Сообщение от tum
С точки зрения нагрузки процессора или быстродействия что лучше, использовать 8-битный таймер настроенным на 1мс и потом формировать требуемую задержку, или 16-битный таймер на 1sec и, соответственно, задержка будет меньше?
Зависит от конкретной реализации и решаемых задач. Вообще - то редко бывает, что само ядро (АЛУ) работает на пределе быстродействия. Гораздо чаще время теряется на формирование задержек, особенно для всяких интерфейсов. Например, OneWire, где времена большие, а задержки довольно критичны, или программно реализованные UART, I2C, которые, хоть и медленные, могут надолго отложить выполнение других задач, на время их обслуживания.

Также надо учитывать, что прерывания и таймеры - довольно ценный ресурс. И даже если таймеров 2, 3, или даже 4 штуки, - они обычно имеют разные, часто уникальные, параметры. Например, один из них имеет встроенный генератор для часового кварца, другой - может использоваться для ШИМ, у некоторых есть гибко настраиваемые предделители... То есть постоянно приходится искать компромисс, что куда использовать. Поэтому часто предлагаемое мной, (давно проверенное временем), решение проблемы задержек с помощью всего лишь одного из аппаратных таймеров (да к тому же наименее навороченного, из самых простых), на котором организуется любое количество программных таймеров, с использованием также всего лишь одного прерывыания, позволяет здорово упростить формирование задержек любой длительности. Использование же двух и более таймеров для этого - удается только в простых программах. В более сложных обычно железо используется более экономно.

Для задержек порядка секунд есть еще вариант. Например, есть на плате часы DS1307 или аналогичные. У них есть выход, на котором обычно можно задать одну из частот, от 1 Гц до килогерц. Можно, например, настроить этот выход на выдачу секундных импульсов, и завести их на одно из внешних прерываний контроллера. (Так, например, сделано в Центральном Контроллере моего робота).
В обработчике этого прерывания можно сделать программно кучу секундомеров, а также - и более длинные, например, минутные, и даже часовые, таймеры. А также, например, раз в секунду, или реже, считывать показания тех же часов, полностью... Сверяя с ними, например, планировщик долговременных заданий, расписанных заранее, хоть на целый год.
0 / 0 / 0
Регистрация: 28.03.2016
Сообщений: 3
22.03.2012, 22:38
Все подробно объяснили, всем большое спасибо!
Тему можно закрывать!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.03.2012, 22:38
Помогаю со студенческими работами здесь

Как увеличить время сессии?
я уже спрашивал об длительности сессии но методы не работают те что советовали, а именно пробовал ...

Как увеличить время сессии?
простой и распространенный вопрос но я на него не нашел ответа, меня интересует как это сделать именно через PHP ( скрипт находится на...

Как увеличить время выполнения запроса
Моя база данных MYSQL настроена так, что выполняет запрос не более 30 секунд. после этого тут же прекращает. Скажите, пожалуйста, как мне...

Как увеличить время исполнения скрипта?
Вот дает ошибку Fatal error: Maximum execution time of 30 seconds exceeded in z:homelocalhostwwwpriceadd_foto.php on line 11

как увеличить время работы батареи?
Здравствуйте, у меня ноутбук - http://rozetka.com.ua/dell_inspiron_7520_di7520i363281000alb/p255529/ , поскольку я часто нахожусь в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru