Ср май 18, 2022 18:35:57
Ср май 18, 2022 18:37:23
То есть подобная библиотека сама пишется в самом начале освоения. Жаль только, я не видел удачного интерфейса, под который можно было бы подгонять свою.
Ср май 18, 2022 18:54:52
Ср май 18, 2022 19:02:15
Ср май 18, 2022 19:07:59
Ср май 18, 2022 19:21:47
COKPOWEHEU писал(а):Немалым, но не возьмусь сказать, что он обязательно будет больше и сложнее, чем на Си
COKPOWEHEU писал(а):Все-таки отсутствие мощного препроцессора вынуждает либо выдумывать хитрые извращения, либо плевать на эффективность и делать все в рантайме
VladislavS писал(а):Вы не представляете какой кайф при программировании ничего не знать о внутреннем устройство GPIO-порта, а просто оперировать стандартными методами и режимами. Особенно, когда в работе их целый зоопарк
НовыйДень писал(а):не были выключены триггеры шмитта в режиме цифрового входа, и для их отключения нужен режим аналогового входа
Ср май 18, 2022 19:32:34
Надо будет проверить. Хотя у меня сейчас только L151 под рукой. Но это же "младшее семейство"?Теперь накладываем на это дело разные компиляторы (GCC, IAR, ARMClang) и у каждого куча уровней оптимизации.
Как раз в моем случае С++ нет вообще.И как раз в вашем случае из C++ взята
А в L1 деление не "вдоль", а "поперек", вместо разбиения по 8 ног на регистр делят на "режим" и "скорость", MODER и OSPEEDR. И лично я не помню какой режим за что отвечает. Лучше уж писать так, чтобы из текста было понятно, чего ты хочешь добиться, а не какие биты выставить.То есть, вот я например на память не помню, как в F1 идут биты в CRL(H) регистре - сначала MODE, потом CNF или наоборот, хэзэ. Но зато я помню, что сброс обеих CNF и установка обеих MODE - это пин на выход в ПП-режиме.
А на стадии освоения вообще нужно избегать писать какие-либо долгосрочные библиотеки. По мере наработки опыта изменится взгляд на уже написанное. И вот такие "улучшения" будут просто слишком тяжеловесными. По мере освоения программист упрощает все эти тонны портянок и в конечном счете приходит к самой короткой записи, то есть к тому, что уже было предложено в сопроводительных документах. Там же люди тоже не дураки сидят, и если они разработали микроконтроллер, то именно они лучше всего и знают его работу.
Вероятнее всего, имелось в виду "не держать в голове подробностей". Знать-то, понятное дело, надо. Но если я хочу нарисовать на дисплее линию, я предпочту оперировать функциями рисования точек или областей, но не командами конкретного дисплея, регистрами SPI или поворотом плоскости поляризации жидкими кристаллами.Кайф "ничего не знать"?
Не могу ни подтвердить, ни опровергнуть. Я под контроллеры на С++ не писал.Меньше, в разы. Проверено на практике. Не забывай про наследование, которое уменьшает дублирование кода.
Еще раз: в Си нет достаточно удобного препроцессора чтобы реализовывать компил-тайм алгоритмы по-человечески, поэтому приходится извращаться. В С++ такого тоже нет, зато есть constexpr'ы, которые решают ту же задачу, но другим способом. Насколько я понимаю, это позволяет на С++ при должном умении (которого у меня нет) писать более читаемый код, чем на Си. Быстродействия-то там примерно одинакового можно достичь.Во-первых, препроцессор никуда в С++ не делся. А, во-вторых, он там и не нужен особо.
Ср май 18, 2022 19:49:52
Чт май 19, 2022 05:56:14
Чт май 19, 2022 07:37:23
Чт май 19, 2022 08:33:17
Если пытаться адаптировать плюсовый код под Си - да. Но такой задачи ведь не стоит. Я не мыслю в терминах С++, соответственно и костылить тамошний подход нужды нет. А на Си подход другой, и описанных вами проблем не возникает.На каком-то небольшом участке кода да. Но в реальном проекте соревноваться с шаблонами и constexpr умумукаешься.
Давай установим, к примеру, на каком-нибудь PA13 режим Analog для любого контроллера (за исключением F1 серии, там GPIO другой).
1. На православном С. (попросим форумчан поучаствовать в этом процессе).
2. Твоим макросом.
3. На С++. Тут я могу показать листинг от PA13<PinMode::Analog>::mode();
#define ADC_IN A,13,8,GPIO_ADC
GPIO_config( ADC_IN );
#define GPIO_ADC 0b0000
#define mode GPIO_ADC
do{
uint32_t temp = GPIO ## A -> CR ## H; //для тех, кто не знаком с препроцессором, ## это объединение строк, то есть GPIO ## A превращается в GPIOA
temp &=~(0b1111<<(((13-8)&0x07)*4));
temp |= ( mode <<(((13-8)&0x07)*4));
GPIO ## A -> CR ## H = temp;
}while(0);
Именно с этим никто не спорит, хотя бы потому, что на С++ почти всегда можно компилировать напрямую Си-шный код. То есть на С++ достичь ровной той же производительности, что на Си можно просто по определению.И вывод дядьки сделали такой, что нет объективных причин отказываться от использования С++ на МК с его ограниченными ресурсами.
Чт май 19, 2022 09:25:52
Чт май 19, 2022 09:42:03
COKPOWEHEU писал(а):Туда напихали слишком много и бессистемно
Чт май 19, 2022 10:49:04
// clear MODER: ~GPIO_MODER_MODERXX_Msk, you should AND these
#define MODER_CLR(n) (~(3<<(n*2)))
// _AI - analog inpt, _O - general output, _AF - alternate function
// these should be OR'ed
#define MODER_I(n) (0)
#define MODER_O(n) (1<<(n*2))
#define MODER_AF(n) (2<<(n*2))
#define MODER_AI(n) (3<<(n*2))
// AFR field: afr - AFR number, pin - pin (0..15)
TRUE_INLINE uint32_t AFRf(uint8_t afr, uint8_t pin){
if(pin > 7) pin -= 8;
return (afr << (pin * 4));
}
GPIOA->MODER = (GPIOA->MODER & (MODER_CLR(11) & MODER_CLR(12) & MODER_CLR(15))) |
(MODER_AF(11) | MODER_AF(12) | MODER_O(15));
// USB - alternate function 14 @ pins PA11/PA12
GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH3_Msk | GPIO_AFRH_AFRH4_Msk)) |
AFRf(14, 11) | AFRf(14, 12);
// MODE:
#define MODE_INPUT 0
#define MODE_NORMAL 1 // 10MHz
#define MODE_SLOW 2 // 2MHz
#define MODE_FAST 3 // 50MHz
// CNF:
#define CNF_ANALOG (0 << 2)
#define CNF_PPOUTPUT (0 << 2)
#define CNF_FLINPUT (1 << 2)
#define CNF_ODOUTPUT (1 << 2)
#define CNF_PUDINPUT (2 << 2)
#define CNF_AFPP (2 << 2)
#define CNF_AFOD (3 << 2)
#define CRL(pin, cnfmode) ((cnfmode) << (pin*4))
#define CRH(pin, cnfmode) ((cnfmode) << ((pin-8)*4))
// Set led as opendrain output
GPIOC->CRH |= CRH(13, CNF_ODOUTPUT | MODE_SLOW);
// USB pullup (PA15) - pushpull output
GPIOA->CRH = CRH(15, CNF_PPOUTPUT | MODE_SLOW);
Чт май 19, 2022 13:44:15
Ну я же просил не F1. Какой интерес с его одним регистром?
Как минимум чтобы читать чужой код.А зачем этим всем многим пользоваться?
Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.А я для удобства работы с GPIO простые макросы накатал. Скажем, для F303:
Чт май 19, 2022 13:59:31
Чт май 19, 2022 14:05:53
COKPOWEHEU писал(а):Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.
Чт май 19, 2022 14:28:58
// clear MODER: ~GPIO_MODER_MODERXX_Msk, you should AND these
#define MODER_CLR(n) (~(3<<(n*2)))
// _AI - analog inpt, _O - general output, _AF - alternate function
// these should be OR'ed
#define MODER_I(n) (0)
#define MODER_O(n) (1<<(n*2))
#define MODER_AF(n) (2<<(n*2))
#define MODER_AI(n) (3<<(n*2))
Чт май 19, 2022 15:13:12
*((volatile uint8_t *)&GPIOA->MODER+3) |= 3<<2;
LDR.N R0,??DataTable1_1
LDRB R1,[R0, #+0]
ORR R1,R1,#0xC
STRB R1,[R0, #+0]
??DataTable1_1:
DC32 0x48000003
Чт май 19, 2022 15:18:24
Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.
Подумайте что будет с вашими макросами когда например: MODER_O(1 + 2) ?