Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
7 / 7 / 0
Регистрация: 26.11.2018
Сообщений: 262

GPIO без HAL

07.06.2021, 23:04. Показов 2555. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу помигать светодиодом без библиотеки HAL, но не получается. Что я не так делаю?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GPIOC->MODER |= GPIO_MODER_MODER0_0;            // Output mode GPIOC0
GPIOC->OTYPER &= ~GPIO_OTYPER_OT_0;             // Push-pull mode
GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0_0;     // Speed
GPIOC->ODR |= 0x01;
GPIOC->BSRR = 0x01;
 
int i = 0;
while(i < 300)
{
    HAL_Delay(20);
    GPIOC->ODR &= ~0x01;
    GPIOC->BSRR = (1U << 15);
    HAL_Delay(20);
    i++;
}
Тактирования порта включен кубом. Сигнал на выходе GPOIC_0 всегда 1
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.06.2021, 23:04
Ответы с готовыми решениями:

Stm32 без HAL
Всех приветствую! Всех с Новым Годом! Решил поиграться с stm32. Имеется Board Nucleo-64 с ST-Link. Хотел попробовать создать проекты...

STM32F429+CooCox без HAL
Начал ковырять STM32F429. В кокосе 1.7.8 этот чип есть, но почему-то в репозитории для него есть только HAL, SPL штатно прицепить нельзя....

Задержка на STM32F429I discovery без HAL
Добрый вечер. Есть МК STM32F429I discovery. На экране нужно реализовать определенную анимацию, что успешно сделано, но проблема в том, что...

33
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
15.06.2021, 15:37
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Любая периферия нуждается в адресации. Если разбивать взаимодействие с ней на большое количество отдельных областей памяти, это сильно усложнит схему. А учитывая, что никаких реальных преимуществ это не дает, никто так и не делает.
ну это да, просто то что вы сейчас сказали, относится к схематике, но никак не относится к
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
проблемы с топологией кристалла
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
и пользоваться GPIO[1].io.ODR = 1;
Другое дело что хранить в одной переменной и номер порта, и номер бита, почти всегда хуже, чем переложить это на макрос
Ну, не совсем. Вы можете использовать "осмысленный" доступ к этим данным для удобства, через макрос, типа:
C
1
#define set_led_state(v) do { GPIO[1].io.ODR = (v != 0) } while (0);
Это в принципе хорошо и удобно. Но подменять количество, клеить имена имен аргументов - это плохо. Например:
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
#define AM2302 C,0
Вот это мне бы очень не понравилось.
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
15.06.2021, 15:56
Цитата Сообщение от Voland_ Посмотреть сообщение
ну это да, просто то что вы сейчас сказали, относится к схематике, но никак не относится к
В данном случае разница невелика. Усложняются схемы сравнения адреса, увеличивается количество дорожек, которые к ним ведут. Наверное, даже линии тактирования пришлось бы по-другому вести.
Цитата Сообщение от Voland_ Посмотреть сообщение
Ну, не совсем. Вы можете использовать "осмысленный" доступ к этим данным для удобства, через макрос, типа:
Именно в таком виде можно вообще обойтись без унифицированного представления ножек:
C
1
2
#define led_on() GPIOA->BSRR = (1<<5)
#define led_off() GPIOA->BSRR = (0x0100<<5)
Но задача-то стоит чтобы к любой ножке можно было обращаться единообразным способом, не придумывая каждый раз новые макросы.
В варианте с массивом можно сделать так:
C
1
2
3
4
5
6
7
#define PORTA (0<<8)
#define PORTB (1<<8)
#define PORTC (2<<8)
 
#define GPO_ON(x) do{ GPIO[(x)>>8].io.BSRR |= (1<<((x)&0xFF)); }while(0)
 
#define LED ( PORTB | 5 ) //0-й байт: номер вывода, 1-й байт: номер порта. Остальное (если есть): настройки и прочая служебная информация.
Хм... а выглядит не так уж плохо. Жаль, только полагается на то, что порты всегда идет последовательно с равными интервалами. Впрочем, если найдется камень, где это неприменимо, там можно оставить старый способ.
Надо будет помедитировать над этим.
Цитата Сообщение от Voland_ Посмотреть сообщение
Но подменять количество, клеить имена имен аргументов - это плохо.
Плохо. Но варианта лучше вы так и не назвали.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
15.06.2021, 16:23
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
вы так и не назвали.
я ж писал - я за inline-функции ). Ну, или избыточное тестирование static-проверками, что заметно отнимает время. Потому что если проблема детектится в момент компиляции - ее быстрее можно исправить, чем тестить все всякими проверками.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В варианте с массивом можно сделать так:
ну... можно-то можно. Просто если вы запишете в ODR значение 100500, возможно, порт отреагирует и нормально, без ошибки, но работать будет неправильно. В случае же inline функции и/или структуры, у вас есть все возможности ограничить юзера (функции), не использовать значения больше положенных (допустим, 0 или 1), и не пихать в них 100500 - ибо компилятор ругнется о "впихивании невпихуемого". Ну, и т.д. - это не единственный случай.
В отношении же get()/set() я говорил, потому что сплошь и рядом в регистрах есть флаги, и есть сдвоенные регистры на чтение и запись. Скажем, выражение для, например 16ти битного SPI:
C
1
SPI->DR <<= 16;
ДОПУСТИМО на большинстве популярных архитектур, но в корне не верно, естественно. В случае же inline-оберток вы получаете относительно безопасный код и в этом случае уже на этапе компиляции компилятор "даст по голове" за такое
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
15.06.2021, 18:42
Цитата Сообщение от Voland_ Посмотреть сообщение
я ж писал - я за inline-функции
Простейший вариант inline функций слишком сильно уступает макросам, а сложный... приведите пример как это могло бы выглядеть.
Цитата Сообщение от Voland_ Посмотреть сообщение
Просто если вы запишете в ODR значение 100500
Когда-то я решал задачу работы AVR с дисплеем HD44780, причем выводы RS, E и DATA должны быть на разных портах. Через макросы это решилось просто
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define LCD_DATA    D,4
#define LCD_RS  B,0
#define LCD_E       D,3
...
void lcd_send(unsigned char data){
  _delay_ms(1);
 LCD_E_1;
 _delay_us(100);        
 PORTx(LCD_DATA) = (PORTx(LCD_DATA) & ~(0x0F<<num(LCD_DATA)))|((data>>4)<<num(LCD_DATA));//high half of byte
 LCD_E_0;
 _delay_us(100);
 LCD_E_1;
 _delay_us(100);
 PORTx(LCD_DATA) = (PORTx(LCD_DATA) & ~(0x0F<<num(LCD_DATA)))|((data & 0x0F)<<num(LCD_DATA));//low half of byte
 LCD_E_0;
 _delay_us(100);
}
Делал я это давно, поэтому стиль слегка отличается от теперяшнего.
Не хотелось бы, чтобы мне "давали по голове" за подобное.
Цитата Сообщение от Voland_ Посмотреть сообщение
В отношении же get()/set()
Что толку спорить о более безопасном решении, если окажется, что оно вовсе не решение?
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
15.06.2021, 21:10
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
приведите пример как это могло бы выглядеть.
к примеру:

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
#define GPO_ON(x) do{ GPIO[(x)>>8].io.BSRR |= (1<<((x)&0xFF)); }while(0)
могло бы быть:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct {
  uint8_t port : 2; /* 4 ports available */
  uint8_t pin : 3; /* 8 pins available per port */
} gpio_t;
 
static inline void GPO_ON(const gpio_t port) {
    GPIO(port.port).io.BSRR |= (uint8_t)1u << port.pin;
}
 
const gpio_t RED_LED = {.port = 1, .pin = 3};
 
void foo(void) {
    GPO_ON(RED_LED);
}
преимущества видите? или перечислить?
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
15.06.2021, 22:29
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
GPIO[6];
Цитата Сообщение от Voland_ Посмотреть сообщение
uint8_t port : 2; /* 4 ports available */
Только я вижу противоречие?
Цитата Сообщение от Voland_ Посмотреть сообщение
преимущества видите? или перечислить?
Недостатки вижу. Существенных преимуществ не вижу. Перечислите. Разумеется, мифическая "проверка времени компиляции" не интересует. С некоторыми костылями она реализуется и на макросах, просто чтение затрудняет. Не менее очевидно, что ваша конструкция должна разворачиваться в минимум ассемблерных инструкций независимо от прихотей компилятора.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
16.06.2021, 08:26
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Только я вижу противоречие?
нашли к чему придраться ). Ну это ж пример. Растяните поле порта на один бит еще, и получите 8 возможных вариантов.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Разумеется, мифическая "проверка времени компиляции" не интересует.
ну, если это не интересует, то их и нет особо. Но этого достаточно.

PS: я ощущаю Ваш воинственный "дух" отстоять использование макросов, и не использовать inline-функции вместо ). У меня нет цели Вас переубедить ). Почитайте рекомендации C-guidelines от Google, MIT, MISRA и др. - это понятно, что верить "какому-то там" явно не очевидно ).
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Не менее очевидно, что ваша конструкция должна разворачиваться в минимум ассемблерных инструкций
я так понимаю, это вы говорите о макросах, но не о "моих" конструкциях (в контексте inline-функций)? Скажу только, что на одну из платформ я написал вариант конвертера доступа к регистрам с макросов в inline-варианты. И косвенной целью как раз, на первом этапе, и являлась 100% идентичность кода на уровне ассемблера. В итоге при конвертации в нескольких проектах были выявлены места, где потенциально используются неправильные типы переменных (sign, width), что в очевидных случаях приводит в warning'ам компилятора. Эти ошибки были "не ошибки", в рабочих проектах, к счастью, но запросто могли бы быть и ошибками. И тут уж дело каждого - насколько серьезно к этому относиться )
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
16.06.2021, 09:57
Цитата Сообщение от Voland_ Посмотреть сообщение
нашли к чему придраться )
Да это не придраться, это так, мимо проходил.
Цитата Сообщение от Voland_ Посмотреть сообщение
ну, если это не интересует, то их и нет особо. Но этого достаточно.
Я ведь говорил, что ее и на макросах добавить можно:
C
1
2
3
4
5
char test(int x){}
#define func(x) do{\
  printf("%i\n", x); \
  if( 1 || test(x) ){} /*проверка аргументов макроса*/\
}while(0)
Здесь вызов функции с нужными аргументами компилятору виден, но в реальности не произойдет из-за вычисления условий слева направо.
Цитата Сообщение от Voland_ Посмотреть сообщение
PS: я ощущаю Ваш воинственный "дух" отстоять использование макросов
Вариант с оформлением существующих портов в массив предложил я, если помните. То есть другие варианты тоже рассматриваю, даже если не собираюсь применять прямо сейчас.
Что же до макросов, лично я уже в некоторой степени наловчился ими жонглировать и не ощущаю особых трудностей. Хотел было написать, что достаточно понять, что это всего лишь текстовая подстановка в исходный код - но нет, правила разворачивания аргументов не очевидны и мне.
Поэтому шаблоны мне не нравятся - я их не знаю. А inline функции действительно имеют ряд ограничений. Например, их не всегда можно определить в заголовочном файле, они могут конфликтовать сами с собой, они не могут разворачиваться в несколько выходных значений, для них нельзя гарантировать то, что они правда заинлайнятся.
Цитата Сообщение от Voland_ Посмотреть сообщение
я так понимаю, это вы говорите о макросах, но не о "моих" конструкциях
Я говорю о решении задачи, независимо какой подход использовался.
Скажем, ардуино-подход (включая ST-HAL, естественно) меня не устраивает именно потому что порт хранится в переменной, и у компилятора нет даже шанса его оптимизировать в 1-3 инструкции. Ну и провоцирует излишнюю универсальность вроде хранения номера SPI в переменной вместо макроса/константы. Но в реальности это нужно примерно никогда: плата как разведена, так разведена, в процессе работы микросхема не переползет на другой порт.
Цитата Сообщение от Voland_ Посмотреть сообщение
В итоге при конвертации в нескольких проектах были выявлены места, где потенциально используются неправильные типы переменных (sign, width)
У меня в аналогичной ситуации компилятор и на макросы ругался. Конечно, разобрать его ругань было сложнее, но сам факт, что он отследил.
Цитата Сообщение от Voland_ Посмотреть сообщение
Скажу только, что на одну из платформ я написал вариант конвертера доступа к регистрам с макросов в inline-варианты.
Не хотите помедитировать над чуть менее тривиальным случаем, чем порты?
Кликните здесь для просмотра всего текста
В stm32l1 для АЦП можно задать последовательность каналов. Контроллер читает регистры ADC_SQR5 - ADC_SQR1, группами по 5 битов (5-битный номер очередного канала). Вот чтобы самому не высчитывать к какому регистру нужный номер относится, я написал макрос ADC_SEQ_SET(номер_АЦП, номер_в_списке, номер_канала). Не без костылей, конечно, но вроде работает.
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
16.06.2021, 11:28
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
лично я уже в некоторой степени наловчился ими жонглировать и не ощущаю особых трудностей.
Вот именно - лично Вы ). Но когда дело касается open-source, библиотек, и вообще, командной разработки - появляется тут же куча ненужных вопросов и неудобств. Да, если работать годами в одном и том же фреймворке - через время все становится очевидным, но во многих, я бы даже сказал, большинстве случаев, это не так - вы обычно берете библиотеку и начинаете ее использовать.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
У меня в аналогичной ситуации компилятор и на макросы ругался. Конечно, разобрать его ругань было сложнее, но сам факт, что он отследил.
Давайте сойдемся на том, что макросы - это не Си. И компилятор о них, строго говоря, ничего не знает - макросами занимается прекомпилятор (в GCC по крайней мере).
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
чуть менее тривиальным случаем, чем порты?
я медитировал о всех случаях в отдельно взятой платформе, пару лет назад ). Поэтому, кое-что слышал об этом...
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Не без костылей, конечно, но вроде работает.
Верю. В определенных случаях так и надо. Но в данном примере, я бы попробовал начать с битовых структур, и inline-функции, ее использующей. Вообще, union+struct творят чудеса, вы это и сами продемонстрировали ).

и кстати сказать,
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
читает регистры ADC_SQR5 - ADC_SQR1, группами по 5 битов (5-битный номер очередного канала).
плохо корреспондируется с
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Усложняются схемы сравнения адреса, увеличивается количество дорожек, которые к ним ведут. Наверное, даже линии тактирования пришлось бы по-другому вести.
Я не к конкретно этой фразе, но к диалогу вцелом - цифровикам оказалось проще расписать настройки без выравнивания (даже) в 8 бит в данном конкретном случае
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
16.06.2021, 12:16
Цитата Сообщение от Voland_ Посмотреть сообщение
Вот именно - лично Вы ). Но когда дело касается open-source, библиотек, и вообще, командной разработки - появляется тут же куча ненужных вопросов и неудобств.
Где это возможно, я макросы не использую. Но бывают и ситуации, где без них выглядит еще хуже. А бывает как с портами: запись GPO_ON достаточно понятна для чтения, даже если вводит в заблуждение количеством аргументов.
Цитата Сообщение от Voland_ Посмотреть сообщение
Давайте сойдемся на том, что макросы - это не Си. И компилятор о них, строго говоря, ничего не знает - макросами занимается прекомпилятор (в GCC по крайней мере).
Но макросы и не выполняются потом на реальной железке. Значит, если где-то есть конфликт типов, компилятор на него наткнется в любом случае.
Цитата Сообщение от Voland_ Посмотреть сообщение
Верю. В определенных случаях так и надо. Но в данном примере, я бы попробовал начать с битовых структур, и inline-функции, ее использующей. Вообще, union+struct творят чудеса, вы это и сами продемонстрировали ).
Поскольку 32 не делится нацело на 5, в каждом регистре остается по 2 бита, которые не задействованы ни под что. А вот с такими "дырявыми" массивами даже struct+union мало что могут сделать.
Цитата Сообщение от Voland_ Посмотреть сообщение
читает регистры ADC_SQR5 - ADC_SQR1, группами по 5 битов (5-битный номер очередного канала).
плохо корреспондируется с
Усложняются схемы сравнения адреса
Тут деление скорее большого 140-битного числа на отдельные регистры. Но число обрабатывается железом то ли как одно целое, то ли группами по 5 битов. Это не независимые порты.
Цитата Сообщение от Voland_ Посмотреть сообщение
Я не к конкретно этой фразе, но к диалогу вцелом - цифровикам оказалось проще расписать настройки без выравнивания (даже) в 8 бит в данном конкретном случае
Да если бы! В том и беда, что с выравниванием и лишними битами в середине. И понятно зачем это сделано - чтобы для изменения одного элемента менять только один регистр, а не два смежных. Как по мне, лучше бы вот тут выделили по 8 бит на каждый номер, из которых старшие 3 незначащие и вообще не разведены на кристалле. Ну заняло бы это не 20 адресов, а 28 - адресное пространство там немеряное.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
16.06.2021, 12:28
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
вот с такими "дырявыми" массивами даже struct+union мало что могут сделать.
могут-могут. https://icarus.cs.weber.edu/~d... nions.html для пропусков вы можете написать "uint8_t :3;", чтобы просто отступить 3 бита в структуре.
PS: относится и к последущим комментам. Можно использовать неименованые битовые поля (unnamed bit fields)
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
16.06.2021, 13:11
Как это поможет оформить пятерки битов в единый массив?
Потому что вариант с "заразервированными" полями ничем не лучше прямой работы с регистрами: все тот же ручной выбор регистра, все тот же ручной выбор позиции в регистре.
0
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
16.06.2021, 13:20
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
ничем не лучше
он лучше уже тем, что это чистый Си, а не нагромождение прекомпилированного кода
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,055
16.06.2021, 13:26
Неважно насколько он лучше или хуже выглядит. Если он не решает проблему, он бесполезен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.06.2021, 13:26

Подключение LCD 1602 через I2C к STM32F4 без библиотеки Hal
Здравствуйте! Пытаюсь запустить дисплей LCD 1602(по I2C) при помощи STM32F411VET6U. На форуме целое множество примеров по поводу запуска...

FreeRTOS и HAL без кодгенератора
Привет, коллеги! Как поменять источник timebase для HAL без использования кодгенератора??

Qt + gpio
Всем привет, я на Raspberry Pi подключил к gpio кнопки, с них я обрабатываю сигнал, всё хорошо, у меня написано приложение на qt,змейка,...

ADC and GPIO
привет форум... нужна помощь знающих людей. вот если я настраиваю PA0 для работы с ADC и настраиваю его как аналоговый мод, и вот ADC...

GPIO и LPC11xx
Добрый вечер! Как то открыл я даташит по LPC1114 контроллеру, и прочитал вот такую фразу: Pull-up level If the pull-up resistor is...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы Кратко. . .
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем **Полевые заметки о двухнедельной совместной работе**. . .
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru